Преглед изворни кода

LibWeb: Speed up gradient painting quite a lot

Previously gradient painting was dominated by the clipping checks in
Painter::set_pixel(). This commit changes gradient painting to use the
new Painter::fill_pixels() function (which does all these checks outside
the hot loop).

With this change gradient painting drops from 96% of the profile to 51%
when scrolling around on gradients.html. A nice 45% reduction :^)
MacDue пре 2 година
родитељ
комит
f2fe3245cf
1 измењених фајлова са 9 додато и 6 уклоњено
  1. 9 6
      Userland/Libraries/LibWeb/Painting/GradientPainting.cpp

+ 9 - 6
Userland/Libraries/LibWeb/Painting/GradientPainting.cpp

@@ -219,6 +219,8 @@ public:
                     color_stop_step(stop_list[i], stop_list[i + 1], relative_loc));
             }
             m_gradient_line_colors[loc] = gradient_color;
+            if (gradient_color.alpha() < 255)
+                m_requires_blending = true;
         }
     }
 
@@ -245,18 +247,19 @@ public:
 
     void paint_into_rect(Gfx::Painter& painter, DevicePixelRect rect, auto location_transform)
     {
-        for (DevicePixels y = 0; y < rect.height(); y++) {
-            for (DevicePixels x = 0; x < rect.width(); x++) {
-                auto gradient_color = sample_color(location_transform(x, y));
-                painter.set_pixel((rect.x() + x).value(), (rect.y() + y).value(), gradient_color, gradient_color.alpha() < 255);
-            }
-        }
+        painter.fill_pixels(
+            rect.to_type<int>(), [&](auto point) {
+                return sample_color(location_transform(point.x(), point.y()));
+            },
+            m_requires_blending);
     }
 
 private:
     bool m_repeating;
     int m_start_offset;
     Vector<Gfx::Color, 1024> m_gradient_line_colors;
+
+    bool m_requires_blending = false;
 };
 
 void paint_linear_gradient(PaintContext& context, DevicePixelRect const& gradient_rect, LinearGradientData const& data)