Procházet zdrojové kódy

LibWeb: Cache combined CSS transform on pre-paint phase

Makes 5% of `compute_combined_css_transform()` in Discord profiles gone.
Aliaksandr Kalenik před 1 rokem
rodič
revize
776951b7ff

+ 1 - 2
Userland/Libraries/LibWeb/Painting/ClippableAndScrollable.cpp

@@ -31,8 +31,7 @@ Optional<CSSPixelRect> ClippableAndScrollable::clip_rect() const
         //       Otherwise, the transform will be applied twice to the clip rect.
         //       Similarly, for hit-testing, the transform must be removed from the clip rectangle since the position
         //       includes the transform.
-        auto combined_transform = compute_combined_css_transform_for_clippable_and_scrollable();
-        rect.translate_by(-combined_transform.translation().to_type<CSSPixels>());
+        rect.translate_by(-m_combined_css_transform.translation().to_type<CSSPixels>());
         return rect;
     }
     return {};

+ 4 - 1
Userland/Libraries/LibWeb/Painting/ClippableAndScrollable.h

@@ -27,11 +27,14 @@ public:
     [[nodiscard]] Optional<CSSPixelRect> clip_rect() const;
     [[nodiscard]] Span<BorderRadiiClip const> border_radii_clips() const;
 
-    virtual Gfx::AffineTransform compute_combined_css_transform_for_clippable_and_scrollable() const = 0;
+    Gfx::AffineTransform const& combined_css_transform() const { return m_combined_css_transform; }
+    void set_combined_css_transform(Gfx::AffineTransform const& transform) { m_combined_css_transform = transform; }
 
 private:
     RefPtr<ScrollFrame const> m_enclosing_scroll_frame;
     RefPtr<ClipFrame const> m_enclosing_clip_frame;
+
+    Gfx::AffineTransform m_combined_css_transform;
 };
 
 }

+ 0 - 5
Userland/Libraries/LibWeb/Painting/InlinePaintable.h

@@ -46,11 +46,6 @@ public:
     void set_outline_offset(CSSPixels outline_offset) { m_outline_offset = outline_offset; }
     CSSPixels outline_offset() const { return m_outline_offset; }
 
-    virtual Gfx::AffineTransform compute_combined_css_transform_for_clippable_and_scrollable() const override
-    {
-        return compute_combined_css_transform();
-    }
-
 private:
     InlinePaintable(Layout::InlineNode const&);
 

+ 2 - 2
Userland/Libraries/LibWeb/Painting/PaintableBox.cpp

@@ -483,7 +483,7 @@ void PaintableBox::apply_clip_overflow_rect(PaintContext& context, PaintPhase ph
         context.recording_painter().add_clip_rect(context.enclosing_device_rect(overflow_clip_rect).to_type<int>());
         auto const& border_radii_clips = this->border_radii_clips();
         m_corner_clipper_ids.resize(border_radii_clips.size());
-        auto combined_transform = compute_combined_css_transform();
+        auto const& combined_transform = combined_css_transform();
         for (size_t corner_clip_index = 0; corner_clip_index < border_radii_clips.size(); ++corner_clip_index) {
             auto const& corner_clip = border_radii_clips[corner_clip_index];
             auto corners = corner_clip.radii.as_corners(context);
@@ -504,7 +504,7 @@ void PaintableBox::clear_clip_overflow_rect(PaintContext& context, PaintPhase ph
 
     if (m_clipping_overflow) {
         m_clipping_overflow = false;
-        auto combined_transform = compute_combined_css_transform();
+        auto const& combined_transform = combined_css_transform();
         auto const& border_radii_clips = this->border_radii_clips();
         for (size_t corner_clip_index = 0; corner_clip_index < border_radii_clips.size(); ++corner_clip_index) {
             auto const& corner_clip = border_radii_clips[corner_clip_index];

+ 0 - 5
Userland/Libraries/LibWeb/Painting/PaintableBox.h

@@ -203,11 +203,6 @@ public:
 
     Optional<CSSPixelRect> get_clip_rect() const;
 
-    virtual Gfx::AffineTransform compute_combined_css_transform_for_clippable_and_scrollable() const override
-    {
-        return compute_combined_css_transform();
-    }
-
 protected:
     explicit PaintableBox(Layout::Box const&);
 

+ 10 - 0
Userland/Libraries/LibWeb/Painting/ViewportPaintable.cpp

@@ -440,6 +440,16 @@ void ViewportPaintable::resolve_paint_only_properties()
             inline_paintable.set_outline_offset(outline_offset);
         }
 
+        if (is_paintable_box) {
+            auto& paintable_box = static_cast<Painting::PaintableBox&>(paintable);
+            auto combined_transform = paintable.compute_combined_css_transform();
+            paintable_box.set_combined_css_transform(combined_transform);
+        } else if (is_inline_paintable) {
+            auto& inline_paintable = static_cast<Painting::InlinePaintable&>(paintable);
+            auto combined_transform = paintable.compute_combined_css_transform();
+            inline_paintable.set_combined_css_transform(combined_transform);
+        }
+
         return TraversalDecision::Continue;
     });
 }