Forráskód Böngészése

LibAccelGfx+LibWeb: Store state of all stacking contexts in GPU painter

This change ensures that the GPU painting executor follows the pattern
of the CPU executor, where the state is stored for each stacking
context, but a painter is created only for those with opacity.

Fixes crashing on apple.com because now save() and restore() are called
on correct painters.
Aliaksandr Kalenik 1 éve
szülő
commit
24da32c884

+ 1 - 1
Userland/Libraries/LibAccelGfx/Painter.cpp

@@ -137,7 +137,7 @@ void main() {
 
 
 HashMap<u32, GL::Texture> s_immutable_bitmap_texture_cache;
 HashMap<u32, GL::Texture> s_immutable_bitmap_texture_cache;
 
 
-OwnPtr<Painter> Painter::create()
+NonnullOwnPtr<Painter> Painter::create()
 {
 {
     auto& context = Context::the();
     auto& context = Context::the();
     return make<Painter>(context);
     return make<Painter>(context);

+ 1 - 1
Userland/Libraries/LibAccelGfx/Painter.h

@@ -29,7 +29,7 @@ class Painter {
     AK_MAKE_NONMOVABLE(Painter);
     AK_MAKE_NONMOVABLE(Painter);
 
 
 public:
 public:
-    static OwnPtr<Painter> create();
+    static NonnullOwnPtr<Painter> create();
 
 
     Painter(Context&);
     Painter(Context&);
     ~Painter();
     ~Painter();

+ 12 - 5
Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorGPU.cpp

@@ -15,7 +15,7 @@ PaintingCommandExecutorGPU::PaintingCommandExecutorGPU(Gfx::Bitmap& bitmap)
     auto painter = AccelGfx::Painter::create();
     auto painter = AccelGfx::Painter::create();
     auto canvas = AccelGfx::Canvas::create(bitmap.size());
     auto canvas = AccelGfx::Canvas::create(bitmap.size());
     painter->set_target_canvas(canvas);
     painter->set_target_canvas(canvas);
-    stacking_contexts.append({ .canvas = canvas,
+    m_stacking_contexts.append({ .canvas = canvas,
         .painter = move(painter),
         .painter = move(painter),
         .opacity = 1.0f,
         .opacity = 1.0f,
         .destination = {} });
         .destination = {} });
@@ -23,7 +23,7 @@ PaintingCommandExecutorGPU::PaintingCommandExecutorGPU(Gfx::Bitmap& bitmap)
 
 
 PaintingCommandExecutorGPU::~PaintingCommandExecutorGPU()
 PaintingCommandExecutorGPU::~PaintingCommandExecutorGPU()
 {
 {
-    VERIFY(stacking_contexts.size() == 1);
+    VERIFY(m_stacking_contexts.size() == 1);
     painter().flush(m_target_bitmap);
     painter().flush(m_target_bitmap);
 }
 }
 
 
@@ -92,6 +92,7 @@ CommandResult PaintingCommandExecutorGPU::set_font(Gfx::Font const&)
 
 
 CommandResult PaintingCommandExecutorGPU::push_stacking_context(float opacity, bool is_fixed_position, Gfx::IntRect const& source_paintable_rect, Gfx::IntPoint post_transform_translation, CSS::ImageRendering, StackingContextTransform transform, Optional<StackingContextMask>)
 CommandResult PaintingCommandExecutorGPU::push_stacking_context(float opacity, bool is_fixed_position, Gfx::IntRect const& source_paintable_rect, Gfx::IntPoint post_transform_translation, CSS::ImageRendering, StackingContextTransform transform, Optional<StackingContextMask>)
 {
 {
+    m_stacking_contexts.last().stacking_context_depth++;
     painter().save();
     painter().save();
     if (is_fixed_position) {
     if (is_fixed_position) {
         auto const& translation = painter().transform().translation();
         auto const& translation = painter().transform().translation();
@@ -110,23 +111,29 @@ CommandResult PaintingCommandExecutorGPU::push_stacking_context(float opacity, b
         auto transformed_destination_rect = affine_transform.map(source_rect).translated(transform.origin);
         auto transformed_destination_rect = affine_transform.map(source_rect).translated(transform.origin);
         auto destination_rect = transformed_destination_rect.to_rounded<int>();
         auto destination_rect = transformed_destination_rect.to_rounded<int>();
 
 
-        stacking_contexts.append({ .canvas = canvas,
+        m_stacking_contexts.append({ .canvas = canvas,
             .painter = move(painter),
             .painter = move(painter),
             .opacity = opacity,
             .opacity = opacity,
             .destination = destination_rect });
             .destination = destination_rect });
     } else {
     } else {
         painter().translate(affine_transform.translation() + post_transform_translation.to_type<float>());
         painter().translate(affine_transform.translation() + post_transform_translation.to_type<float>());
+        m_stacking_contexts.append({ .canvas = {},
+            .painter = MaybeOwned(painter()),
+            .opacity = opacity,
+            .destination = {} });
     }
     }
     return CommandResult::Continue;
     return CommandResult::Continue;
 }
 }
 
 
 CommandResult PaintingCommandExecutorGPU::pop_stacking_context()
 CommandResult PaintingCommandExecutorGPU::pop_stacking_context()
 {
 {
-    if (stacking_contexts.last().opacity < 1) {
-        auto stacking_context = stacking_contexts.take_last();
+    auto stacking_context = m_stacking_contexts.take_last();
+    VERIFY(stacking_context.stacking_context_depth == 0);
+    if (stacking_context.painter.is_owned()) {
         painter().blit_canvas(stacking_context.destination, *stacking_context.canvas, stacking_context.opacity);
         painter().blit_canvas(stacking_context.destination, *stacking_context.canvas, stacking_context.opacity);
     }
     }
     painter().restore();
     painter().restore();
+    m_stacking_contexts.last().stacking_context_depth--;
     return CommandResult::Continue;
     return CommandResult::Continue;
 }
 }
 
 

+ 6 - 4
Userland/Libraries/LibWeb/Painting/PaintingCommandExecutorGPU.h

@@ -6,6 +6,7 @@
 
 
 #pragma once
 #pragma once
 
 
+#include <AK/MaybeOwned.h>
 #include <LibAccelGfx/Painter.h>
 #include <LibAccelGfx/Painter.h>
 #include <LibWeb/Painting/RecordingPainter.h>
 #include <LibWeb/Painting/RecordingPainter.h>
 
 
@@ -63,15 +64,16 @@ private:
 
 
     struct StackingContext {
     struct StackingContext {
         RefPtr<AccelGfx::Canvas> canvas;
         RefPtr<AccelGfx::Canvas> canvas;
-        OwnPtr<AccelGfx::Painter> painter;
+        MaybeOwned<AccelGfx::Painter> painter;
         float opacity;
         float opacity;
         Gfx::IntRect destination;
         Gfx::IntRect destination;
+        int stacking_context_depth { 0 };
     };
     };
 
 
-    [[nodiscard]] AccelGfx::Painter const& painter() const { return *stacking_contexts.last().painter; }
-    [[nodiscard]] AccelGfx::Painter& painter() { return *stacking_contexts.last().painter; }
+    [[nodiscard]] AccelGfx::Painter const& painter() const { return *m_stacking_contexts.last().painter; }
+    [[nodiscard]] AccelGfx::Painter& painter() { return *m_stacking_contexts.last().painter; }
 
 
-    Vector<StackingContext> stacking_contexts;
+    Vector<StackingContext> m_stacking_contexts;
 };
 };
 
 
 }
 }