Modified: trunk/Source/WebCore/ChangeLog (281487 => 281488)
--- trunk/Source/WebCore/ChangeLog 2021-08-24 05:07:32 UTC (rev 281487)
+++ trunk/Source/WebCore/ChangeLog 2021-08-24 05:37:49 UTC (rev 281488)
@@ -1,3 +1,16 @@
+2021-08-23 Cameron McCormack <hey...@apple.com>
+
+ Avoid unnecessary CGColor creation in Gradient::createCGGradient for common sRGB-only cases
+ https://bugs.webkit.org/show_bug.cgi?id=229422
+ <rdar://problem/82261384>
+
+ Reviewed by Sam Weinig.
+
+ * platform/graphics/Gradient.h:
+ * platform/graphics/cg/GradientCG.cpp:
+ (WebCore::Gradient::hasOnlyBoundedSRGBColorStops const):
+ (WebCore::Gradient::createCGGradient):
+
2021-08-23 Rob Buis <rb...@igalia.com>
Null check scriptExecutionContext
Modified: trunk/Source/WebCore/platform/graphics/Gradient.h (281487 => 281488)
--- trunk/Source/WebCore/platform/graphics/Gradient.h 2021-08-24 05:07:32 UTC (rev 281487)
+++ trunk/Source/WebCore/platform/graphics/Gradient.h 2021-08-24 05:37:49 UTC (rev 281488)
@@ -145,6 +145,7 @@
#if USE(CG)
void createCGGradient();
+ bool hasOnlyBoundedSRGBColorStops() const;
#endif
Data m_data;
Modified: trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp (281487 => 281488)
--- trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp 2021-08-24 05:07:32 UTC (rev 281487)
+++ trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp 2021-08-24 05:37:49 UTC (rev 281488)
@@ -40,11 +40,19 @@
m_gradient = nullptr;
}
+bool Gradient::hasOnlyBoundedSRGBColorStops() const
+{
+ for (const auto& stop : m_stops) {
+ if (stop.color.colorSpace() != ColorSpace::SRGB)
+ return false;
+ }
+ return true;
+}
+
void Gradient::createCGGradient()
{
sortStops();
- auto colorsArray = adoptCF(CFArrayCreateMutable(0, m_stops.size(), &kCFTypeArrayCallBacks));
unsigned numStops = m_stops.size();
const int reservedStops = 3;
@@ -51,26 +59,29 @@
Vector<CGFloat, reservedStops> locations;
locations.reserveInitialCapacity(numStops);
- Vector<CGFloat, 4 * reservedStops> colorComponents;
- colorComponents.reserveInitialCapacity(numStops * 4);
+ // If all the stops are bounded sRGB (as represented by the color having the color space
+ // ColorSpace::SRGB), it is faster to create a gradient using components than CGColors.
+ if (hasOnlyBoundedSRGBColorStops()) {
+ Vector<CGFloat, 4 * reservedStops> colorComponents;
+ colorComponents.reserveInitialCapacity(numStops * 4);
- // FIXME: Consider making this into two loops to avoid unnecessary allocation of the
- // CGColorRefs in the common case of all ColorSpace::SRGB.
+ for (const auto& stop : m_stops) {
+ auto [colorSpace, components] = stop.color.colorSpaceAndComponents();
+ auto [r, g, b, a] = components;
+ colorComponents.uncheckedAppend(r);
+ colorComponents.uncheckedAppend(g);
+ colorComponents.uncheckedAppend(b);
+ colorComponents.uncheckedAppend(a);
- bool hasOnlyBoundedSRGBColorStops = true;
- for (const auto& stop : m_stops) {
- // If all the stops are bounded sRGB (as represented by the color having the color space
- // ColorSpace::SRGB, it is faster to create a gradient using components than CGColors.
- if (stop.color.colorSpace() != ColorSpace::SRGB)
- hasOnlyBoundedSRGBColorStops = false;
+ locations.uncheckedAppend(stop.offset);
+ }
- auto [colorSpace, components] = stop.color.colorSpaceAndComponents();
- auto [r, g, b, a] = components;
- colorComponents.uncheckedAppend(r);
- colorComponents.uncheckedAppend(g);
- colorComponents.uncheckedAppend(b);
- colorComponents.uncheckedAppend(a);
+ m_gradient = adoptCF(CGGradientCreateWithColorComponents(sRGBColorSpaceRef(), colorComponents.data(), locations.data(), numStops));
+ return;
+ }
+ auto colorsArray = adoptCF(CFArrayCreateMutable(0, m_stops.size(), &kCFTypeArrayCallBacks));
+ for (const auto& stop : m_stops) {
CFArrayAppendValue(colorsArray.get(), cachedCGColor(stop.color));
locations.uncheckedAppend(stop.offset);
}
@@ -81,10 +92,7 @@
auto extendedColorsGradientColorSpace = sRGBColorSpaceRef();
#endif
- if (hasOnlyBoundedSRGBColorStops)
- m_gradient = adoptCF(CGGradientCreateWithColorComponents(sRGBColorSpaceRef(), colorComponents.data(), locations.data(), numStops));
- else
- m_gradient = adoptCF(CGGradientCreateWithColors(extendedColorsGradientColorSpace, colorsArray.get(), locations.data()));
+ m_gradient = adoptCF(CGGradientCreateWithColors(extendedColorsGradientColorSpace, colorsArray.get(), locations.data()));
}
void Gradient::fill(GraphicsContext& context, const FloatRect& rect)