Title: [264280] trunk/Source/WebCore
Revision
264280
Author
da...@apple.com
Date
2020-07-12 10:28:02 -0700 (Sun, 12 Jul 2020)

Log Message

Simplify and improve Gradient, some other small color-related removals
https://bugs.webkit.org/show_bug.cgi?id=214221

Reviewed by Sam Weinig.

* css/CSSGradientValue.cpp: Removed some unneeded includes.

* html/ColorInputType.cpp:
(WebCore::ColorInputType::currentColor): Deleted.
(WebCore::ColorInputType::shouldShowSuggestions const): Deleted.
* html/ColorInputType.h: Updated for the above.

* html/HTMLDocument.cpp: Removed unneeded include of HashTools.h.

* html/canvas/CanvasGradient.cpp:
(WebCore::CanvasGradient::create): Moved these functions out of the
header since inlining should be the same or better with them here.
(WebCore::CanvasGradient::~CanvasGradient): Moved this out of the
header so we don't need to include Gradient.h in the header.
(WebCore::CanvasGradient::addColorStop): Updated for change to
Gradient::addColorStop and move Color rather than copying it.

* html/canvas/CanvasGradient.h: Removed include of Gradient.h.
Moved things out of the header to make that work.

* inspector/InspectorCanvas.cpp:
(WebCore::InspectorCanvas::buildArrayForCanvasGradient): Removed
use of Gradient::type and instead unify the type string code with
the code that interprets the data for the different types.

* page/FrameView.cpp:
(WebCore::FrameView::recalculateScrollbarOverlayStyle): Refactored
to eliminate the multiple redundant code paths, otherwising leaving
the logic unchanged.

* platform/ColorChooserClient.h: Remove unneeded includes and unused
currentColor and shouldShowSuggestions functions.

* platform/graphics/Gradient.cpp:
(WebCore::Gradient::create): Replaced create functions that take
type-specific data structure with one that takes the variant Data.
(WebCore::Gradient::Gradient): Ditto. Also removed platformInit.
(WebCore::Gradient::~Gradient): Removed platformDestroy.
(WebCore::Gradient::type const): Deleted.
(WebCore::Gradient::addColorStop): Take an rvalue reference to cut down
a little bit on reference count churn. Replaced the platformDestroy
function with a new stopsChanged function. Removed an unneeded overload
that takes the two parts of a ColorStop separately.
(WebCore::Gradient::setSortedColorStops): Use stopsChanged.
(WebCore::Gradient::sortStops const): Simplify a bit, using a lambda.
Also gave this a shorter name; it still optimizes by not sorting if
the vector is already sorted.
(WebCore::Gradient::hasAlpha const): Deleted.
(WebCore::Gradient::setSpreadMethod): Removed some slightly overzealous
code checking this isn't used after creating the platform-specific gradient.
Decided not to bother with this for now.
(WebCore::Gradient::setGradientSpaceTransform): Tweaked formatting.
(WebCore::add): Added overloads to add(Hasher&) so we can use computeHash.
(WebCore::Gradient::hash const): Use computeHash instead of hashMemory.

* platform/graphics/Gradient.h: Use RetainPtr, COMPtr, and RefPtr instead
of manually managing the lifetimes of the platform-specific underlying
gradient objects. Also removed the unhelpful PlatformGradient type. This
pattern, all too common in our platform library, provides no useful
abstraction here. Removed unneeded constructors from ColorStop.
Updated for changes above. Added platform-specific functions createBrush,
createPattern, and createCGGradient. Simplify encoding and decoding by
taking advantage of the support for encoding/decoding variants.
Remove the enum Gradient::Type entirely. Removed the invalidateHash
function because it's only used in a few setters and setting the hash
to 0 is a fine way to write it there.

* platform/graphics/GraphicsContext.cpp:
(WebCore::GraphicsContextState::GraphicsContextState): Moved here from
the header so we don't need to include Gradient.h in the header.
(WebCore::GraphicsContextState::~GraphicsContextState): Ditto.
(WebCore::GraphicsContextState::operator=): Ditto.

* platform/graphics/GraphicsContext.h: Removed include of Gradient.h.
Moved things out of the header to make that work.

* platform/graphics/cairo/CairoOperations.cpp:
(WebCore::Cairo::FillSource::FillSource): Use createPattern instead of
createPlatformGradient.
(WebCore::Cairo::StrokeSource::StrokeSource): Ditto.

* platform/graphics/cairo/GradientCairo.cpp:
(WebCore::Gradient::stopsChanged): Renamed from platformDestroy.
(WebCore::interpolateColorStop): Rewrote to use existing blend functions.
(WebCore::createConic): Changed return type to RefPtr. Tweaked to match
WebKit coding style a bit better, use auto, use Vector::first/last, and
updated for removal of the Gradient::ColorStop constructor.
(WebCore::Gradient::createPattern): Renamed from createPlatformGradient.
Changed to return a RefPtr instead of a raw pointer the caller needs to
adopt at each call site. Refactored so it no longer uses Gradient::type.
(WebCore::Gradient::fill): Use createPattern.
* platform/graphics/cairo/GraphicsContextImplCairo.cpp:
(WebCore::GraphicsContextImplCairo::fillRect): Ditto.

* platform/graphics/cg/GradientCG.cpp:
(WebCore::Gradient::stopsChanged): Renamed from platformDestroy, and
simplified implementation now that we use RetainPtr.
(WebCore::Gradient::createCGGradient): Renamed from platformGradient,
got rid of the return value, and made it caller responsibility to only
call this when a gradeitn needs to be allocated.
(WebCore::Gradient::paint): Updated to use the above.

* platform/graphics/cg/GraphicsContextCG.cpp: Add include of Gradient.h.

* platform/graphics/displaylists/DisplayListItems.h:
Added include of Gradient.h since the function templates in this file
encode and decode gradients.

* platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp:
(Nicosia::CairoOperationRecorder::fillRect): Use createPattern.

* platform/graphics/win/Direct2DOperations.cpp:
(WebCore::Direct2D::FillSource::FillSource): Use createBrush
(WebCore::Direct2D::StrokeSource::StrokeSource): Ditto.

* platform/graphics/win/GradientDirect2D.cpp:
(WebCore::Gradient::stopsChanged): Renamed from platformDestroy and
simplified implementation now that we use COMPtr.
(WebCore::Gradient::platformGradient): Deleted.
(WebCore::Gradient::createPlatformGradientIfNecessary): Deleted.
(WebCore::Gradient::createBrush): Renamed from generateGradient and
added a return value. Simplified now that we use COMPtr, optimized
the code a bit, and added some FIXME about mistakes I noticed.
(WebCore::Gradient::fill): Use createBrush and m_brush.
* platform/graphics/win/GraphicsContextImplDirect2D.cpp:
(WebCore::GraphicsContextImplDirect2D::fillRect): Use createBrush.

* platform/mac/ScrollAnimatorMac.mm: Added include of Gradient.h.

* rendering/RenderThemeIOS.mm:
(WebCore::RenderThemeIOS::paintProgressBar): Updated for changes to
addColorStop. Also remove a lot of unnecessary conversion from float
to double and back to float.

* rendering/svg/RenderSVGResourceGradient.cpp:
(WebCore::RenderSVGResourceGradient::addStops): Update to make
and move a new color stop instead of copying it, modifying it in
place, and then copying it again.
* rendering/svg/RenderSVGResourceGradient.cpp: Removed include of
Gradient.h.

* svg/SVGGradientElement.cpp:
(WebCore::SVGGradientElement::buildStops): Use std::clamp to convert
the offsets into monotonically increasing ones in a more direct way,
using variable names instead of comments to clarify what we are doing.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (264279 => 264280)


--- trunk/Source/WebCore/ChangeLog	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/ChangeLog	2020-07-12 17:28:02 UTC (rev 264280)
@@ -1,3 +1,156 @@
+2020-07-12  Darin Adler  <da...@apple.com>
+
+        Simplify and improve Gradient, some other small color-related removals
+        https://bugs.webkit.org/show_bug.cgi?id=214221
+
+        Reviewed by Sam Weinig.
+
+        * css/CSSGradientValue.cpp: Removed some unneeded includes.
+
+        * html/ColorInputType.cpp:
+        (WebCore::ColorInputType::currentColor): Deleted.
+        (WebCore::ColorInputType::shouldShowSuggestions const): Deleted.
+        * html/ColorInputType.h: Updated for the above.
+
+        * html/HTMLDocument.cpp: Removed unneeded include of HashTools.h.
+
+        * html/canvas/CanvasGradient.cpp:
+        (WebCore::CanvasGradient::create): Moved these functions out of the
+        header since inlining should be the same or better with them here.
+        (WebCore::CanvasGradient::~CanvasGradient): Moved this out of the
+        header so we don't need to include Gradient.h in the header.
+        (WebCore::CanvasGradient::addColorStop): Updated for change to
+        Gradient::addColorStop and move Color rather than copying it.
+
+        * html/canvas/CanvasGradient.h: Removed include of Gradient.h.
+        Moved things out of the header to make that work.
+
+        * inspector/InspectorCanvas.cpp:
+        (WebCore::InspectorCanvas::buildArrayForCanvasGradient): Removed
+        use of Gradient::type and instead unify the type string code with
+        the code that interprets the data for the different types.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::recalculateScrollbarOverlayStyle): Refactored
+        to eliminate the multiple redundant code paths, otherwising leaving
+        the logic unchanged.
+
+        * platform/ColorChooserClient.h: Remove unneeded includes and unused
+        currentColor and shouldShowSuggestions functions.
+
+        * platform/graphics/Gradient.cpp:
+        (WebCore::Gradient::create): Replaced create functions that take
+        type-specific data structure with one that takes the variant Data.
+        (WebCore::Gradient::Gradient): Ditto. Also removed platformInit.
+        (WebCore::Gradient::~Gradient): Removed platformDestroy.
+        (WebCore::Gradient::type const): Deleted.
+        (WebCore::Gradient::addColorStop): Take an rvalue reference to cut down
+        a little bit on reference count churn. Replaced the platformDestroy
+        function with a new stopsChanged function. Removed an unneeded overload
+        that takes the two parts of a ColorStop separately.
+        (WebCore::Gradient::setSortedColorStops): Use stopsChanged.
+        (WebCore::Gradient::sortStops const): Simplify a bit, using a lambda.
+        Also gave this a shorter name; it still optimizes by not sorting if
+        the vector is already sorted.
+        (WebCore::Gradient::hasAlpha const): Deleted.
+        (WebCore::Gradient::setSpreadMethod): Removed some slightly overzealous
+        code checking this isn't used after creating the platform-specific gradient.
+        Decided not to bother with this for now.
+        (WebCore::Gradient::setGradientSpaceTransform): Tweaked formatting.
+        (WebCore::add): Added overloads to add(Hasher&) so we can use computeHash.
+        (WebCore::Gradient::hash const): Use computeHash instead of hashMemory.
+
+        * platform/graphics/Gradient.h: Use RetainPtr, COMPtr, and RefPtr instead
+        of manually managing the lifetimes of the platform-specific underlying
+        gradient objects. Also removed the unhelpful PlatformGradient type. This
+        pattern, all too common in our platform library, provides no useful
+        abstraction here. Removed unneeded constructors from ColorStop.
+        Updated for changes above. Added platform-specific functions createBrush,
+        createPattern, and createCGGradient. Simplify encoding and decoding by
+        taking advantage of the support for encoding/decoding variants.
+        Remove the enum Gradient::Type entirely. Removed the invalidateHash
+        function because it's only used in a few setters and setting the hash
+        to 0 is a fine way to write it there.
+
+        * platform/graphics/GraphicsContext.cpp:
+        (WebCore::GraphicsContextState::GraphicsContextState): Moved here from
+        the header so we don't need to include Gradient.h in the header.
+        (WebCore::GraphicsContextState::~GraphicsContextState): Ditto.
+        (WebCore::GraphicsContextState::operator=): Ditto.
+
+        * platform/graphics/GraphicsContext.h: Removed include of Gradient.h.
+        Moved things out of the header to make that work.
+
+        * platform/graphics/cairo/CairoOperations.cpp:
+        (WebCore::Cairo::FillSource::FillSource): Use createPattern instead of
+        createPlatformGradient.
+        (WebCore::Cairo::StrokeSource::StrokeSource): Ditto.
+
+        * platform/graphics/cairo/GradientCairo.cpp:
+        (WebCore::Gradient::stopsChanged): Renamed from platformDestroy.
+        (WebCore::interpolateColorStop): Rewrote to use existing blend functions.
+        (WebCore::createConic): Changed return type to RefPtr. Tweaked to match
+        WebKit coding style a bit better, use auto, use Vector::first/last, and
+        updated for removal of the Gradient::ColorStop constructor.
+        (WebCore::Gradient::createPattern): Renamed from createPlatformGradient.
+        Changed to return a RefPtr instead of a raw pointer the caller needs to
+        adopt at each call site. Refactored so it no longer uses Gradient::type.
+        (WebCore::Gradient::fill): Use createPattern.
+        * platform/graphics/cairo/GraphicsContextImplCairo.cpp:
+        (WebCore::GraphicsContextImplCairo::fillRect): Ditto.
+
+        * platform/graphics/cg/GradientCG.cpp:
+        (WebCore::Gradient::stopsChanged): Renamed from platformDestroy, and
+        simplified implementation now that we use RetainPtr.
+        (WebCore::Gradient::createCGGradient): Renamed from platformGradient,
+        got rid of the return value, and made it caller responsibility to only
+        call this when a gradeitn needs to be allocated.
+        (WebCore::Gradient::paint): Updated to use the above.
+
+        * platform/graphics/cg/GraphicsContextCG.cpp: Add include of Gradient.h.
+
+        * platform/graphics/displaylists/DisplayListItems.h:
+        Added include of Gradient.h since the function templates in this file
+        encode and decode gradients.
+
+        * platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp:
+        (Nicosia::CairoOperationRecorder::fillRect): Use createPattern.
+
+        * platform/graphics/win/Direct2DOperations.cpp:
+        (WebCore::Direct2D::FillSource::FillSource): Use createBrush
+        (WebCore::Direct2D::StrokeSource::StrokeSource): Ditto.
+
+        * platform/graphics/win/GradientDirect2D.cpp:
+        (WebCore::Gradient::stopsChanged): Renamed from platformDestroy and
+        simplified implementation now that we use COMPtr.
+        (WebCore::Gradient::platformGradient): Deleted.
+        (WebCore::Gradient::createPlatformGradientIfNecessary): Deleted.
+        (WebCore::Gradient::createBrush): Renamed from generateGradient and
+        added a return value. Simplified now that we use COMPtr, optimized
+        the code a bit, and added some FIXME about mistakes I noticed.
+        (WebCore::Gradient::fill): Use createBrush and m_brush.
+        * platform/graphics/win/GraphicsContextImplDirect2D.cpp:
+        (WebCore::GraphicsContextImplDirect2D::fillRect): Use createBrush.
+
+        * platform/mac/ScrollAnimatorMac.mm: Added include of Gradient.h.
+
+        * rendering/RenderThemeIOS.mm:
+        (WebCore::RenderThemeIOS::paintProgressBar): Updated for changes to
+        addColorStop. Also remove a lot of unnecessary conversion from float
+        to double and back to float.
+
+        * rendering/svg/RenderSVGResourceGradient.cpp:
+        (WebCore::RenderSVGResourceGradient::addStops): Update to make
+        and move a new color stop instead of copying it, modifying it in
+        place, and then copying it again.
+        * rendering/svg/RenderSVGResourceGradient.cpp: Removed include of
+        Gradient.h.
+
+        * svg/SVGGradientElement.cpp:
+        (WebCore::SVGGradientElement::buildStops): Use std::clamp to convert
+        the offsets into monotonically increasing ones in a more direct way,
+        using variable names instead of comments to clarify what we are doing.
+
 2020-07-12  Yusuke Suzuki  <ysuz...@apple.com>
 
         Unreviewed, fix GTK debian builds

Modified: trunk/Source/WebCore/css/CSSGradientValue.cpp (264279 => 264280)


--- trunk/Source/WebCore/css/CSSGradientValue.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/css/CSSGradientValue.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -30,8 +30,6 @@
 #include "CSSToLengthConversionData.h"
 #include "CSSValueKeywords.h"
 #include "ColorBlending.h"
-#include "FloatSize.h"
-#include "Gradient.h"
 #include "GradientImage.h"
 #include "NodeRenderStyle.h"
 #include "Pair.h"

Modified: trunk/Source/WebCore/html/ColorInputType.cpp (264279 => 264280)


--- trunk/Source/WebCore/html/ColorInputType.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/html/ColorInputType.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -270,21 +270,6 @@
     return element()->document().view()->contentsToRootView(element()->renderer()->absoluteBoundingBoxRect());
 }
 
-Color ColorInputType::currentColor()
-{
-    return valueAsColor();
-}
-
-bool ColorInputType::shouldShowSuggestions() const
-{
-#if ENABLE(DATALIST_ELEMENT)
-    ASSERT(element());
-    return element()->hasAttributeWithoutSynchronization(listAttr);
-#else
-    return false;
-#endif
-}
-
 Vector<Color> ColorInputType::suggestedColors() const
 {
     Vector<Color> suggestions;

Modified: trunk/Source/WebCore/html/ColorInputType.h (264279 => 264280)


--- trunk/Source/WebCore/html/ColorInputType.h	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/html/ColorInputType.h	2020-07-12 17:28:02 UTC (rev 264280)
@@ -48,8 +48,6 @@
     void didChooseColor(const Color&) final;
     void didEndChooser() final;
     IntRect elementRectRelativeToRootView() const final;
-    Color currentColor() final;
-    bool shouldShowSuggestions() const final;
     Vector<Color> suggestedColors() const final;
     bool isMouseFocusable() const final;
     bool isKeyboardFocusable(KeyboardEvent*) const final;

Modified: trunk/Source/WebCore/html/HTMLDocument.cpp (264279 => 264280)


--- trunk/Source/WebCore/html/HTMLDocument.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/html/HTMLDocument.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -74,7 +74,6 @@
 #include "HTMLHtmlElement.h"
 #include "HTMLIFrameElement.h"
 #include "HTMLNames.h"
-#include "HashTools.h"
 #include "ScriptController.h"
 #include "StyleResolver.h"
 #include <wtf/IsoMallocInlines.h>

Modified: trunk/Source/WebCore/html/canvas/CanvasGradient.cpp (264279 => 264280)


--- trunk/Source/WebCore/html/canvas/CanvasGradient.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/html/canvas/CanvasGradient.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -29,6 +29,7 @@
 
 #include "CanvasBase.h"
 #include "CanvasStyle.h"
+#include "Gradient.h"
 
 namespace WebCore {
 
@@ -44,6 +45,18 @@
 {
 }
 
+Ref<CanvasGradient> CanvasGradient::create(const FloatPoint& p0, const FloatPoint& p1, CanvasBase& canvasBase)
+{
+    return adoptRef(*new CanvasGradient(p0, p1, canvasBase));
+}
+
+Ref<CanvasGradient> CanvasGradient::create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, CanvasBase& canvasBase)
+{
+    return adoptRef(*new CanvasGradient(p0, r0, p1, r1, canvasBase));
+}
+
+CanvasGradient::~CanvasGradient() = default;
+
 ExceptionOr<void> CanvasGradient::addColorStop(float value, const String& colorString)
 {
     if (!(value >= 0 && value <= 1))
@@ -54,7 +67,7 @@
     if (!color.isValid())
         return Exception { SyntaxError };
 
-    m_gradient->addColorStop(value, color);
+    m_gradient->addColorStop({ value, WTFMove(color) });
     return { };
 }
 

Modified: trunk/Source/WebCore/html/canvas/CanvasGradient.h (264279 => 264280)


--- trunk/Source/WebCore/html/canvas/CanvasGradient.h	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/html/canvas/CanvasGradient.h	2020-07-12 17:28:02 UTC (rev 264280)
@@ -27,22 +27,18 @@
 #pragma once
 
 #include "ExceptionOr.h"
-#include "Gradient.h"
+#include "FloatPoint.h"
 
 namespace WebCore {
 
 class CanvasBase;
+class Gradient;
 
 class CanvasGradient : public RefCounted<CanvasGradient> {
 public:
-    static Ref<CanvasGradient> create(const FloatPoint& p0, const FloatPoint& p1, CanvasBase& canvasBase)
-    {
-        return adoptRef(*new CanvasGradient(p0, p1, canvasBase));
-    }
-    static Ref<CanvasGradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, CanvasBase& canvasBase)
-    {
-        return adoptRef(*new CanvasGradient(p0, r0, p1, r1, canvasBase));
-    }
+    static Ref<CanvasGradient> create(const FloatPoint& p0, const FloatPoint& p1, CanvasBase&);
+    static Ref<CanvasGradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, CanvasBase&);
+    ~CanvasGradient();
 
     Gradient& gradient() { return m_gradient; }
     const Gradient& gradient() const { return m_gradient; }
@@ -55,7 +51,6 @@
 
     Ref<Gradient> m_gradient;
     CanvasBase& m_canvas;
-
 };
 
 }

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (264279 => 264280)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -36,6 +36,7 @@
 #include "CSSFontSelector.h"
 #include "CSSParser.h"
 #include "CSSPropertyNames.h"
+#include "Gradient.h"
 #include "ImageBuffer.h"
 #include "ImageData.h"
 #include "InspectorInstrumentation.h"

Modified: trunk/Source/WebCore/inspector/InspectorCanvas.cpp (264279 => 264280)


--- trunk/Source/WebCore/inspector/InspectorCanvas.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/inspector/InspectorCanvas.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -1158,19 +1158,17 @@
 
 Ref<JSON::ArrayOf<JSON::Value>> InspectorCanvas::buildArrayForCanvasGradient(const CanvasGradient& canvasGradient)
 {
-    const auto& gradient = canvasGradient.gradient();
-    
-    String type = gradient.type() == Gradient::Type::Radial ? "radial-gradient"_s : gradient.type() == Gradient::Type::Linear ? "linear-gradient"_s : "conic-gradient"_s;
-
+    ASCIILiteral type = "linear-gradient"_s;
     auto parameters = JSON::ArrayOf<float>::create();
-    WTF::switchOn(gradient.data(),
-        [&parameters] (const Gradient::LinearData& data) {
+    WTF::switchOn(canvasGradient.gradient().data(),
+        [&] (const Gradient::LinearData& data) {
             parameters->addItem(data.point0.x());
             parameters->addItem(data.point0.y());
             parameters->addItem(data.point1.x());
             parameters->addItem(data.point1.y());
         },
-        [&parameters] (const Gradient::RadialData& data) {
+        [&] (const Gradient::RadialData& data) {
+            type = "radial-gradient"_s;
             parameters->addItem(data.point0.x());
             parameters->addItem(data.point0.y());
             parameters->addItem(data.startRadius);
@@ -1178,7 +1176,8 @@
             parameters->addItem(data.point1.y());
             parameters->addItem(data.endRadius);
         },
-        [&parameters] (const Gradient::ConicData& data) {
+        [&] (const Gradient::ConicData& data) {
+            type = "conic-gradient"_s;
             parameters->addItem(data.point0.x());
             parameters->addItem(data.point0.y());
             parameters->addItem(data.angleRadians);
@@ -1186,7 +1185,7 @@
     );
 
     auto stops = JSON::ArrayOf<JSON::Value>::create();
-    for (auto& colorStop : gradient.stops()) {
+    for (auto& colorStop : canvasGradient.gradient().stops()) {
         auto stop = JSON::ArrayOf<JSON::Value>::create();
         stop->addItem(colorStop.offset);
         stop->addItem(indexForData(serializationForCSS(colorStop.color)));

Modified: trunk/Source/WebCore/page/FrameView.cpp (264279 => 264280)


--- trunk/Source/WebCore/page/FrameView.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/page/FrameView.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -350,32 +350,27 @@
 
 void FrameView::recalculateScrollbarOverlayStyle()
 {
-    ScrollbarOverlayStyle oldOverlayStyle = scrollbarOverlayStyle();
-    Optional<ScrollbarOverlayStyle> clientOverlayStyle = frame().page() ? frame().page()->chrome().client().preferredScrollbarOverlayStyle() : WTF::nullopt;
-    if (clientOverlayStyle) {
-        if (clientOverlayStyle.value() != oldOverlayStyle)
-            setScrollbarOverlayStyle(clientOverlayStyle.value());
-        return;
-    }
-
-    ScrollbarOverlayStyle computedOverlayStyle = ScrollbarOverlayStyleDefault;
-
-    Color backgroundColor = documentBackgroundColor();
-    if (backgroundColor.isValid()) {
-        // Reduce the background color from RGB to a lightness value
-        // and determine which scrollbar style to use based on a lightness
-        // heuristic.
-        if (backgroundColor.lightness() <= .5f && backgroundColor.isVisible())
-            computedOverlayStyle = ScrollbarOverlayStyleLight;
-        else if (!backgroundColor.isVisible() && useDarkAppearance())
-            computedOverlayStyle = ScrollbarOverlayStyleLight;
-    }
-
-    if (oldOverlayStyle != computedOverlayStyle)
-        setScrollbarOverlayStyle(computedOverlayStyle);
+    auto style = [this] {
+        if (auto page = frame().page()) {
+            if (auto clientStyle = page->chrome().client().preferredScrollbarOverlayStyle())
+                return *clientStyle;
+        }
+        auto background = ""
+        if (background.isVisible()) {
+            if (background.lightness() <= .5f)
+                return ScrollbarOverlayStyleLight;
+        } else {
+            if (useDarkAppearance())
+                return ScrollbarOverlayStyleLight;
+        }
+        return ScrollbarOverlayStyleDefault;
+    }();
+    if (scrollbarOverlayStyle() != style)
+        setScrollbarOverlayStyle(style);
 }
 
 #if ENABLE(DARK_MODE_CSS)
+
 void FrameView::recalculateBaseBackgroundColor()
 {
     bool usingDarkAppearance = useDarkAppearance();
@@ -388,6 +383,7 @@
         backgroundColor = Color(Color::transparent);
     updateBackgroundRecursively(backgroundColor);
 }
+
 #endif
 
 void FrameView::clear()

Modified: trunk/Source/WebCore/platform/ColorChooserClient.h (264279 => 264280)


--- trunk/Source/WebCore/platform/ColorChooserClient.h	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/ColorChooserClient.h	2020-07-12 17:28:02 UTC (rev 264280)
@@ -27,17 +27,16 @@
  *
  */
 
-#ifndef ColorChooserClient_h
-#define ColorChooserClient_h
+#pragma once
 
 #if ENABLE(INPUT_TYPE_COLOR)
 
-#include "IntRect.h"
-#include <wtf/Vector.h>
+#include <wtf/Forward.h>
 
 namespace WebCore {
 
 class Color;
+class IntRect;
 
 class ColorChooserClient {
 public:
@@ -46,8 +45,6 @@
     virtual void didChooseColor(const Color&) = 0;
     virtual void didEndChooser() = 0;
     virtual IntRect elementRectRelativeToRootView() const = 0;
-    virtual Color currentColor() = 0;
-    virtual bool shouldShowSuggestions() const = 0;
     virtual Vector<Color> suggestedColors() const = 0;
 };
 
@@ -54,5 +51,3 @@
 } // namespace WebCore
 
 #endif // ENABLE(INPUT_TYPE_COLOR)
-
-#endif // ColorChooserClient_h

Modified: trunk/Source/WebCore/platform/graphics/Gradient.cpp (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/Gradient.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/Gradient.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -36,59 +36,18 @@
 
 namespace WebCore {
 
-Ref<Gradient> Gradient::create(LinearData&& data)
+Ref<Gradient> Gradient::create(Data&& data)
 {
     return adoptRef(*new Gradient(WTFMove(data)));
 }
 
-Ref<Gradient> Gradient::create(RadialData&& data)
-{
-    return adoptRef(*new Gradient(WTFMove(data)));
-}
-
-Ref<Gradient> Gradient::create(ConicData&& data)
-{
-    return adoptRef(*new Gradient(WTFMove(data)));
-}
-
-Gradient::Gradient(LinearData&& data)
+Gradient::Gradient(Data&& data)
     : m_data(WTFMove(data))
 {
-    platformInit();
 }
 
-Gradient::Gradient(RadialData&& data)
-    : m_data(WTFMove(data))
-{
-    platformInit();
-}
-    
-Gradient::Gradient(ConicData&& data)
-    : m_data(WTFMove(data))
-{
-    platformInit();
-}
+Gradient::~Gradient() = default;
 
-Gradient::~Gradient()
-{
-    platformDestroy();
-}
-
-auto Gradient::type() const -> Type
-{
-    return WTF::switchOn(m_data,
-        [] (const LinearData&) {
-            return Type::Linear;
-        },
-        [] (const RadialData&) {
-            return Type::Radial;
-        },
-        [] (const ConicData&) {
-            return Type::Conic;
-        }
-    );
-}
-
 void Gradient::adjustParametersForTiledDrawing(FloatSize& size, FloatRect& srcRect, const FloatSize& spacing)
 {
     if (srcRect.isEmpty())
@@ -134,71 +93,38 @@
     );
 }
 
-void Gradient::addColorStop(float offset, const Color& color)
+void Gradient::addColorStop(Gradient::ColorStop&& stop)
 {
-    addColorStop({ offset, color });
-}
-
-void Gradient::addColorStop(const Gradient::ColorStop& stop)
-{
-    m_stops.append(stop);
-
+    m_stops.append(WTFMove(stop));
     m_stopsSorted = false;
-
-    platformDestroy();
-    invalidateHash();
+    m_cachedHash = 0;
+    stopsChanged();
 }
 
 void Gradient::setSortedColorStops(ColorStopVector&& stops)
 {
     m_stops = WTFMove(stops);
-
     m_stopsSorted = true;
-
-    platformDestroy();
-    invalidateHash();
+    m_cachedHash = 0;
+    stopsChanged();
 }
 
-static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b)
+void Gradient::sortStops() const
 {
-    return a.offset < b.offset;
-}
-
-void Gradient::sortStopsIfNecessary()
-{
     if (m_stopsSorted)
         return;
-
     m_stopsSorted = true;
-
-    if (!m_stops.size())
-        return;
-
-    std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
-    invalidateHash();
+    std::stable_sort(m_stops.begin(), m_stops.end(), [] (auto& a, auto& b) {
+        return a.offset < b.offset;
+    });
 }
 
-bool Gradient::hasAlpha() const
-{
-    for (const auto& stop : m_stops) {
-        if (!stop.color.isOpaque())
-            return true;
-    }
-
-    return false;
-}
-
 void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod)
 {
-    // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set.
-    ASSERT(m_gradient == 0);
-
     if (m_spreadMethod == spreadMethod)
         return;
-
     m_spreadMethod = spreadMethod;
-
-    invalidateHash();
+    m_cachedHash = 0;
 }
 
 void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation)
@@ -205,75 +131,54 @@
 {
     if (m_gradientSpaceTransformation == gradientSpaceTransformation)
         return;
-
     m_gradientSpaceTransformation = gradientSpaceTransformation;
+    m_cachedHash = 0;
+}
 
-    invalidateHash();
+// FIXME: Instead of these add(Hasher) functions, consider using encode functions to compute the hash.
+
+static void add(Hasher& hasher, const Color& color)
+{
+    // FIXME: We don't want to hash a hash; do better.
+    add(hasher, color.hash());
 }
 
-unsigned Gradient::hash() const
+static void add(Hasher& hasher, const FloatPoint& point)
 {
-    if (m_cachedHash)
-        return m_cachedHash;
+    add(hasher, point.x(), point.y());
+}
 
-    struct {
-        Type type;
-        FloatPoint point0;
-        FloatPoint point1;
-        float startRadius;
-        float endRadius;
-        float aspectRatio;
-        float angleRadians;
-        GradientSpreadMethod spreadMethod;
-        AffineTransform gradientSpaceTransformation;
-    } parameters;
+static void add(Hasher& hasher, const AffineTransform& transform)
+{
+    add(hasher, transform.a(), transform.b(), transform.c(), transform.d(), transform.e(), transform.f());
+}
 
-    // StringHasher requires that the memory it hashes be a multiple of two in size.
-    COMPILE_ASSERT(!(sizeof(parameters) % 2), Gradient_parameters_size_should_be_multiple_of_two);
-    COMPILE_ASSERT(!(sizeof(ColorStop) % 2), Color_stop_size_should_be_multiple_of_two);
-    
-    // Ensure that any padding in the struct is zero-filled, so it will not affect the hash value.
-    // FIXME: This is asking for trouble, because it is a nontrivial type.
-    memset(static_cast<void*>(&parameters), 0, sizeof(parameters));
-    
-    WTF::switchOn(m_data,
-        [&parameters] (const LinearData& data) {
-            parameters.point0 = data.point0;
-            parameters.point1 = data.point1;
-            parameters.startRadius = 0;
-            parameters.endRadius = 0;
-            parameters.aspectRatio = 0;
-            parameters.angleRadians = 0;
-            parameters.type = Type::Linear;
-        },
-        [&parameters] (const RadialData& data) {
-            parameters.point0 = data.point0;
-            parameters.point1 = data.point1;
-            parameters.startRadius = data.startRadius;
-            parameters.endRadius = data.endRadius;
-            parameters.aspectRatio = data.aspectRatio;
-            parameters.angleRadians = 0;
-            parameters.type = Type::Radial;
-        },
-        [&parameters] (const ConicData& data) {
-            parameters.point0 = data.point0;
-            parameters.point1 = {0, 0};
-            parameters.startRadius = 0;
-            parameters.endRadius = 0;
-            parameters.aspectRatio = 0;
-            parameters.angleRadians = data.angleRadians;
-            parameters.type = Type::Conic;
-        }
-    );
+static void add(Hasher& hasher, const Gradient::ColorStop& stop)
+{
+    add(hasher, stop.offset, stop.color);
+}
 
-    parameters.spreadMethod = m_spreadMethod;
-    parameters.gradientSpaceTransformation = m_gradientSpaceTransformation;
+static void add(Hasher& hasher, const Gradient::LinearData& data)
+{
+    add(hasher, data.point0, data.point1);
+}
 
-    unsigned parametersHash = StringHasher::hashMemory(&parameters, sizeof(parameters));
-    unsigned stopHash = StringHasher::hashMemory(m_stops.data(), m_stops.size() * sizeof(ColorStop));
+static void add(Hasher& hasher, const Gradient::RadialData& data)
+{
+    add(hasher, data.point0, data.point1, data.startRadius, data.endRadius, data.aspectRatio);
+}
 
-    m_cachedHash = pairIntHash(parametersHash, stopHash);
+static void add(Hasher& hasher, const Gradient::ConicData& data)
+{
+    add(hasher, data.point0, data.angleRadians);
+}
 
+unsigned Gradient::hash() const
+{
+    if (!m_cachedHash) {
+        sortStops();
+        m_cachedHash = computeHash(m_data, m_spreadMethod, m_gradientSpaceTransformation, m_stops);
+    }
     return m_cachedHash;
 }
 

Modified: trunk/Source/WebCore/platform/graphics/Gradient.h (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/Gradient.h	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/Gradient.h	2020-07-12 17:28:02 UTC (rev 264280)
@@ -31,48 +31,44 @@
 #include "Color.h"
 #include "FloatPoint.h"
 #include "GraphicsTypes.h"
-#include <wtf/EnumTraits.h>
-#include <wtf/RefCounted.h>
 #include <wtf/Variant.h>
 #include <wtf/Vector.h>
 
 #if USE(CG)
+#include <wtf/RetainPtr.h>
+#endif
+
+#if USE(DIRECT2D)
+#include "COMPtr.h"
+#endif
+
+#if USE(CG)
 typedef struct CGContext* CGContextRef;
 typedef struct CGGradient* CGGradientRef;
-typedef CGGradientRef PlatformGradient;
-#elif USE(DIRECT2D)
+#endif
+
+#if USE(DIRECT2D)
 interface ID2D1Brush;
 interface ID2D1RenderTarget;
-typedef ID2D1Brush* PlatformGradient;
-#elif USE(CAIRO)
+#endif
+
+#if USE(CAIRO)
 typedef struct _cairo_pattern cairo_pattern_t;
-typedef cairo_pattern_t* PlatformGradient;
-#else
-typedef void* PlatformGradient;
 #endif
 
 namespace WebCore {
 
-class Color;
 class FloatRect;
 class GraphicsContext;
 
 class Gradient : public RefCounted<Gradient> {
 public:
-    // FIXME: ExtendedColor - A color stop needs a notion of color space.
     struct ColorStop {
         float offset { 0 };
         Color color;
 
-        ColorStop() = default;
-        ColorStop(float offset, const Color& color)
-            : offset(offset)
-            , color(color)
-        {
-        }
-
-        template<class Encoder> void encode(Encoder&) const;
-        template<class Decoder> static Optional<ColorStop> decode(Decoder&);
+        template<typename Encoder> void encode(Encoder&) const;
+        template<typename Decoder> static Optional<ColorStop> decode(Decoder&);
     };
 
     using ColorStopVector = Vector<ColorStop, 2>;
@@ -81,8 +77,8 @@
         FloatPoint point0;
         FloatPoint point1;
 
-        template<class Encoder> void encode(Encoder&) const;
-        template<class Decoder> static Optional<LinearData> decode(Decoder&);
+        template<typename Encoder> void encode(Encoder&) const;
+        template<typename Decoder> static Optional<LinearData> decode(Decoder&);
     };
 
     struct RadialData {
@@ -92,37 +88,29 @@
         float endRadius;
         float aspectRatio; // For elliptical gradient, width / height.
 
-        template<class Encoder> void encode(Encoder&) const;
-        template<class Decoder> static Optional<RadialData> decode(Decoder&);
+        template<typename Encoder> void encode(Encoder&) const;
+        template<typename Decoder> static Optional<RadialData> decode(Decoder&);
     };
-    
+
     struct ConicData {
         FloatPoint point0;
         float angleRadians;
 
-        template<class Encoder> void encode(Encoder&) const;
-        template<class Decoder> static Optional<ConicData> decode(Decoder&);
+        template<typename Encoder> void encode(Encoder&) const;
+        template<typename Decoder> static Optional<ConicData> decode(Decoder&);
     };
 
     using Data = "" RadialData, ConicData>;
 
-    enum class Type { Linear, Radial, Conic };
+    WEBCORE_EXPORT static Ref<Gradient> create(Data&&);
 
-    WEBCORE_EXPORT static Ref<Gradient> create(LinearData&&);
-    WEBCORE_EXPORT static Ref<Gradient> create(RadialData&&);
-    WEBCORE_EXPORT static Ref<Gradient> create(ConicData&&);
-
     WEBCORE_EXPORT ~Gradient();
 
-    WEBCORE_EXPORT Type type() const;
-
-    bool hasAlpha() const;
     bool isZeroSize() const;
 
     const Data& data() const { return m_data; }
 
-    WEBCORE_EXPORT void addColorStop(const ColorStop&);
-    WEBCORE_EXPORT void addColorStop(float, const Color&);
+    WEBCORE_EXPORT void addColorStop(ColorStop&&);
     WEBCORE_EXPORT void setSortedColorStops(ColorStopVector&&);
 
     const ColorStopVector& stops() const { return m_stops; }
@@ -130,7 +118,6 @@
     WEBCORE_EXPORT void setSpreadMethod(GradientSpreadMethod);
     GradientSpreadMethod spreadMethod() const { return m_spreadMethod; }
 
-    // CG needs to transform the gradient at draw time.
     WEBCORE_EXPORT void setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation);
     const AffineTransform& gradientSpaceTransform() const { return m_gradientSpaceTransformation; }
 
@@ -138,56 +125,56 @@
     void adjustParametersForTiledDrawing(FloatSize&, FloatRect&, const FloatSize& spacing);
 
     unsigned hash() const;
-    void invalidateHash() { m_cachedHash = 0; }
 
+#if USE(CAIRO)
+    RefPtr<cairo_pattern_t> createPattern(float globalAlpha);
+#endif
+
 #if USE(CG)
     void paint(GraphicsContext&);
     void paint(CGContextRef);
-#elif USE(DIRECT2D)
-    PlatformGradient createPlatformGradientIfNecessary(ID2D1RenderTarget*);
-#elif USE(CAIRO)
-    PlatformGradient createPlatformGradient(float globalAlpha);
 #endif
 
-    template<class Encoder> void encode(Encoder&) const;
-    template<class Decoder> static Optional<Ref<Gradient>> decode(Decoder&);
+#if USE(DIRECT2D)
+    ID2D1Brush* createBrush(ID2D1RenderTarget*);
+#endif
 
+    template<typename Encoder> void encode(Encoder&) const;
+    template<typename Decoder> static Optional<Ref<Gradient>> decode(Decoder&);
+
 private:
-    Gradient(LinearData&&);
-    Gradient(RadialData&&);
-    Gradient(ConicData&&);
+    explicit Gradient(Data&&);
 
-    PlatformGradient platformGradient();
-    void platformInit() { m_gradient = nullptr; }
-    void platformDestroy();
+    void sortStops() const;
+    void stopsChanged();
 
-    void sortStopsIfNecessary();
-
-#if USE(DIRECT2D)
-    void generateGradient(ID2D1RenderTarget*);
+#if USE(CG)
+    void createCGGradient();
 #endif
 
     Data m_data;
-
     mutable ColorStopVector m_stops;
     mutable bool m_stopsSorted { false };
     GradientSpreadMethod m_spreadMethod { GradientSpreadMethod::Pad };
+    mutable unsigned m_cachedHash { 0 };
     AffineTransform m_gradientSpaceTransformation;
 
-    mutable unsigned m_cachedHash { 0 };
+#if USE(CG)
+    RetainPtr<CGGradientRef> m_gradient;
+#endif
 
-    PlatformGradient m_gradient;
+#if USE(DIRECT2D)
+    COMPtr<ID2D1Brush> m_brush;
+#endif
 };
 
-template<class Encoder>
-void Gradient::ColorStop::encode(Encoder& encoder) const
+template<typename Encoder> void Gradient::ColorStop::encode(Encoder& encoder) const
 {
     encoder << offset;
     encoder << color;
 }
 
-template<class Decoder>
-Optional<Gradient::ColorStop> Gradient::ColorStop::decode(Decoder& decoder)
+template<typename Decoder> Optional<Gradient::ColorStop> Gradient::ColorStop::decode(Decoder& decoder)
 {
     Optional<float> offset;
     decoder >> offset;
@@ -202,15 +189,13 @@
     return {{ *offset, *color }};
 }
 
-template<class Encoder>
-void Gradient::LinearData::encode(Encoder& encoder) const
+template<typename Encoder> void Gradient::LinearData::encode(Encoder& encoder) const
 {
     encoder << point0;
     encoder << point1;
 }
 
-template<class Decoder>
-Optional<Gradient::LinearData> Gradient::LinearData::decode(Decoder& decoder)
+template<typename Decoder> Optional<Gradient::LinearData> Gradient::LinearData::decode(Decoder& decoder)
 {
     Optional<FloatPoint> point0;
     decoder >> point0;
@@ -225,8 +210,7 @@
     return {{ *point0, *point1 }};
 }
 
-template<class Encoder>
-void Gradient::RadialData::encode(Encoder& encoder) const
+template<typename Encoder> void Gradient::RadialData::encode(Encoder& encoder) const
 {
     encoder << point0;
     encoder << point1;
@@ -235,8 +219,7 @@
     encoder << aspectRatio;
 }
 
-template<class Decoder>
-Optional<Gradient::RadialData> Gradient::RadialData::decode(Decoder& decoder)
+template<typename Decoder> Optional<Gradient::RadialData> Gradient::RadialData::decode(Decoder& decoder)
 {
     Optional<FloatPoint> point0;
     decoder >> point0;
@@ -266,15 +249,13 @@
     return {{ *point0, *point1, *startRadius, *endRadius, *aspectRatio }};
 }
 
-template<class Encoder>
-void Gradient::ConicData::encode(Encoder& encoder) const
+template<typename Encoder> void Gradient::ConicData::encode(Encoder& encoder) const
 {
     encoder << point0;
     encoder << angleRadians;
 }
 
-template<class Decoder>
-Optional<Gradient::ConicData> Gradient::ConicData::decode(Decoder& decoder)
+template<typename Decoder> Optional<Gradient::ConicData> Gradient::ConicData::decode(Decoder& decoder)
 {
     Optional<FloatPoint> point0;
     decoder >> point0;
@@ -289,22 +270,9 @@
     return {{ *point0, *angleRadians }};
 }
 
-template<class Encoder>
-void Gradient::encode(Encoder& encoder) const
+template<typename Encoder> void Gradient::encode(Encoder& encoder) const
 {
-    auto type = this->type();
-    encoder << type;
-    switch (type) {
-    case Type::Linear:
-        encoder << WTF::get<Gradient::LinearData>(m_data);
-        break;
-    case Type::Radial:
-        encoder << WTF::get<Gradient::RadialData>(m_data);
-        break;
-    case Type::Conic:
-        encoder << WTF::get<Gradient::ConicData>(m_data);
-        break;
-    }
+    encoder << m_data;
     encoder << m_stops;
     encoder << m_stopsSorted;
     encoder << m_spreadMethod;
@@ -311,71 +279,32 @@
     encoder << m_gradientSpaceTransformation;
 }
 
-template<class Decoder>
-Optional<Ref<Gradient>> Gradient::decode(Decoder& decoder)
+template<typename Decoder> Optional<Ref<Gradient>> Gradient::decode(Decoder& decoder)
 {
-    Optional<Gradient::Type> type;
-    decoder >> type;
-    if (!type)
+    Optional<Data> data;
+    decoder >> data;
+    if (!data)
         return WTF::nullopt;
+    auto gradient = Gradient::create(WTFMove(*data));
 
-    RefPtr<Gradient> gradient;
-    switch (*type) {
-    case Type::Linear: {
-        Optional<LinearData> linearData;
-        decoder >> linearData;
-        if (!linearData)
-            return WTF::nullopt;
-
-        gradient = Gradient::create(WTFMove(*linearData));
-        break;
-    }
-    case Type::Radial: {
-        Optional<RadialData> radialData;
-        decoder >> radialData;
-        if (!radialData)
-            return WTF::nullopt;
-
-        gradient = Gradient::create(WTFMove(*radialData));
-        break;
-    }
-    case Type::Conic: {
-        Optional<ConicData> conicData;
-        decoder >> conicData;
-        if (!conicData)
-            return WTF::nullopt;
-
-        gradient = Gradient::create(WTFMove(*conicData));
-        break;
-    }
-    }
-
-    if (!gradient) {
-        ASSERT_NOT_REACHED();
-        return WTF::nullopt;
-    }
-
     Optional<ColorStopVector> stops;
     decoder >> stops;
     if (!stops)
         return WTF::nullopt;
-
     Optional<bool> stopsSorted;
     decoder >> stopsSorted;
     if (!stopsSorted.hasValue())
         return WTF::nullopt;
-
-    if (stopsSorted.value())
+    if (*stopsSorted)
         gradient->setSortedColorStops(WTFMove(*stops));
     else {
         for (auto& stop : *stops)
-            gradient->addColorStop(stop);
+            gradient->addColorStop(WTFMove(stop));
     }
 
     GradientSpreadMethod spreadMethod;
     if (!decoder.decode(spreadMethod))
         return WTF::nullopt;
-
     gradient->setSpreadMethod(spreadMethod);
 
     Optional<AffineTransform> gradientSpaceTransformation;
@@ -382,22 +311,9 @@
     decoder >> gradientSpaceTransformation;
     if (!gradientSpaceTransformation)
         return WTF::nullopt;
+    gradient->setGradientSpaceTransform(WTFMove(*gradientSpaceTransformation));
 
-    gradient->setGradientSpaceTransform(WTFMove(*gradientSpaceTransformation));
-    return gradient.releaseNonNull();
+    return WTFMove(gradient);
 }
 
 } // namespace WebCore
-
-namespace WTF {
-
-template<> struct EnumTraits<WebCore::Gradient::Type> {
-    using values = EnumValues<
-    WebCore::Gradient::Type,
-    WebCore::Gradient::Type::Linear,
-    WebCore::Gradient::Type::Radial,
-    WebCore::Gradient::Type::Conic
-    >;
-};
-
-} // namespace WTF

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -75,6 +75,26 @@
     if (m_changeFlags.contains(GraphicsContextState::flag) && (m_state.property != state.property)) \
         changeFlags.add(GraphicsContextState::flag);
 
+GraphicsContextState::GraphicsContextState()
+    : shouldAntialias(true)
+    , shouldSmoothFonts(true)
+    , shouldSubpixelQuantizeFonts(true)
+    , shadowsIgnoreTransforms(false)
+#if USE(CG)
+    // Core Graphics incorrectly renders shadows with radius > 8px (<rdar://problem/8103442>),
+    // but we need to preserve this buggy behavior for canvas and -webkit-box-shadow.
+    , shadowsUseLegacyRadius(false)
+#endif
+    , drawLuminanceMask(false)
+{
+}
+
+GraphicsContextState::~GraphicsContextState() = default;
+GraphicsContextState::GraphicsContextState(const GraphicsContextState&) = default;
+GraphicsContextState::GraphicsContextState(GraphicsContextState&&) = default;
+GraphicsContextState& GraphicsContextState::operator=(const GraphicsContextState&) = default;
+GraphicsContextState& GraphicsContextState::operator=(GraphicsContextState&&) = default;
+
 GraphicsContextState::StateChangeFlags GraphicsContextStateChange::changesFromState(const GraphicsContextState& state) const
 {
     GraphicsContextState::StateChangeFlags changeFlags;

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2020-07-12 17:28:02 UTC (rev 264280)
@@ -29,7 +29,6 @@
 #include "DashArray.h"
 #include "FloatRect.h"
 #include "FontCascade.h"
-#include "Gradient.h"
 #include "GraphicsTypes.h"
 #include "Image.h"
 #include "ImageOrientation.h"
@@ -98,6 +97,10 @@
 class TextRun;
 class TransformationMatrix;
 
+namespace DisplayList {
+class Recorder;
+}
+
 enum class TextDrawingMode : uint8_t {
     Fill = 1 << 0,
     Stroke = 1 << 1,
@@ -153,25 +156,16 @@
     return {{ *mode, *shouldUseDarkAppearance }};
 }
 
-namespace DisplayList {
-class Recorder;
-}
-
 struct GraphicsContextState {
-    GraphicsContextState()
-        : shouldAntialias(true)
-        , shouldSmoothFonts(true)
-        , shouldSubpixelQuantizeFonts(true)
-        , shadowsIgnoreTransforms(false)
-#if USE(CG)
-        // Core Graphics incorrectly renders shadows with radius > 8px (<rdar://problem/8103442>),
-        // but we need to preserve this buggy behavior for canvas and -webkit-box-shadow.
-        , shadowsUseLegacyRadius(false)
-#endif
-        , drawLuminanceMask(false)
-    {
-    }
+    WEBCORE_EXPORT GraphicsContextState();
+    WEBCORE_EXPORT ~GraphicsContextState();
 
+    GraphicsContextState(const GraphicsContextState&);
+    GraphicsContextState(GraphicsContextState&&);
+
+    GraphicsContextState& operator=(const GraphicsContextState&);
+    GraphicsContextState& operator=(GraphicsContextState&&);
+
     enum Change : uint32_t {
         StrokeGradientChange                    = 1 << 0,
         StrokePatternChange                     = 1 << 1,
@@ -197,7 +191,7 @@
         UseDarkAppearanceChange                 = 1 << 20,
 #endif
     };
-    typedef OptionSet<Change> StateChangeFlags;
+    using StateChangeFlags = OptionSet<Change>;
 
     RefPtr<Gradient> strokeGradient;
     RefPtr<Pattern> strokePattern;
@@ -308,7 +302,7 @@
     Pattern* strokePattern() const { return m_state.strokePattern.get(); }
 
     void setStrokeGradient(Ref<Gradient>&&);
-    RefPtr<Gradient> strokeGradient() const { return m_state.strokeGradient; }
+    Gradient* strokeGradient() const { return m_state.strokeGradient.get(); }
 
     void setFillRule(WindRule);
     WindRule fillRule() const { return m_state.fillRule; }
@@ -320,7 +314,7 @@
     Pattern* fillPattern() const { return m_state.fillPattern.get(); }
 
     WEBCORE_EXPORT void setFillGradient(Ref<Gradient>&&);
-    RefPtr<Gradient> fillGradient() const { return m_state.fillGradient; }
+    Gradient* fillGradient() const { return m_state.fillGradient.get(); }
 
     void setShadowsIgnoreTransforms(bool);
     bool shadowsIgnoreTransforms() const { return m_state.shadowsIgnoreTransforms; }

Modified: trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -40,6 +40,7 @@
 #include "DrawErrorUnderline.h"
 #include "FloatConversion.h"
 #include "FloatRect.h"
+#include "Gradient.h"
 #include "GraphicsContext.h"
 #include "GraphicsContextPlatformPrivateCairo.h"
 #include "Image.h"
@@ -568,9 +569,9 @@
         pattern.repeatX = state.fillPattern->repeatX();
         pattern.repeatY = state.fillPattern->repeatY();
     } else if (state.fillGradient) {
-        gradient.base = adoptRef(state.fillGradient->createPlatformGradient(1));
+        gradient.base = state.fillGradient->createPattern(1);
         if (state.alpha != 1)
-            gradient.alphaAdjusted = adoptRef(state.fillGradient->createPlatformGradient(state.alpha));
+            gradient.alphaAdjusted = state.fillGradient->createPattern(state.alpha);
     } else
         color = state.fillColor;
 }
@@ -581,9 +582,9 @@
     if (state.strokePattern)
         pattern = adoptRef(state.strokePattern->createPlatformPattern(AffineTransform()));
     else if (state.strokeGradient) {
-        gradient.base = adoptRef(state.strokeGradient->createPlatformGradient(1));
+        gradient.base = state.strokeGradient->createPattern(1);
         if (state.alpha != 1)
-            gradient.alphaAdjusted = adoptRef(state.strokeGradient->createPlatformGradient(state.alpha));
+            gradient.alphaAdjusted = state.strokeGradient->createPattern(state.alpha);
     } else
         color = state.strokeColor;
 }

Modified: trunk/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -30,8 +30,10 @@
 
 #if USE(CAIRO)
 
+#include "AnimationUtilities.h"
 #include "CairoOperations.h"
 #include "CairoUtilities.h"
+#include "ColorBlending.h"
 #include "GraphicsContext.h"
 #include "PlatformContextCairo.h"
 #include <wtf/MathExtras.h>
@@ -38,7 +40,7 @@
 
 namespace WebCore {
 
-void Gradient::platformDestroy()
+void Gradient::stopsChanged()
 {
 }
 
@@ -132,66 +134,54 @@
     cairo_mesh_pattern_end_patch(gradient);
 }
 
-static Gradient::ColorStop interpolateColorStop(Gradient::ColorStop from, Gradient::ColorStop to)
+static Gradient::ColorStop interpolateColorStop(const Gradient::ColorStop& from, const Gradient::ColorStop& to)
 {
-    auto [r1, g1, b1, a1] = from.color.toSRGBALossy<float>();
-    auto [r2, g2, b2, a2] = to.color.toSRGBALossy<float>();
-
-    float offset = from.offset + (to.offset - from.offset) * 0.5f;
-    float r = r1 + (r2 - r1) * 0.5f;
-    float g = g1 + (g2 - g1) * 0.5f;
-    float b = b1 + (b2 - b1) * 0.5f;
-    float a = a1 + (a2 - a1) * 0.5f;
-
-    return Gradient::ColorStop(offset, makeSimpleColor(SRGBA { r, g, b, a }));
+    return { blend(from.offset, to.offset, 0.5), blend(from.color, to.color, 0.5) };
 }
 
-static cairo_pattern_t* createConic(float xo, float yo, float r, float angleRadians,
+static RefPtr<cairo_pattern_t> createConic(float xo, float yo, float r, float angleRadians,
     Gradient::ColorStopVector stops, float globalAlpha)
 {
-    cairo_pattern_t* gradient = cairo_pattern_create_mesh();
-    Gradient::ColorStop from, to;
-
-    /* It's not possible to paint an entire circle with a single Bezier curve.
-     * To have a good approximation to a circle it's necessary to use at least
-     * four Bezier curves. So three additional stops with interpolated colors
-     * are added to force painting of four Bezier curves. */
+    // It's not possible to paint an entire circle with a single Bezier curve.
+    // To have a good approximation to a circle it's necessary to use at least
+    // four Bezier curves. So three additional stops with interpolated colors
+    // are added to force painting of four Bezier curves.
     if (stops.size() == 2) {
-        Gradient::ColorStop first = stops.at(0);
-        Gradient::ColorStop last = stops.at(1);
-        Gradient::ColorStop third = interpolateColorStop(first, last);
-        Gradient::ColorStop second = interpolateColorStop(first, third);
-        Gradient::ColorStop fourth = interpolateColorStop(third, last);
-        stops.insert(1, fourth);
-        stops.insert(1, third);
-        stops.insert(1, second);
+        auto third = interpolateColorStop(stops.first(), stops.last());
+        auto second = interpolateColorStop(stops.first(), third);
+        auto fourth = interpolateColorStop(third, stops.last());
+        stops.insert(1, WTFMove(fourth));
+        stops.insert(1, WTFMove(third));
+        stops.insert(1, WTFMove(second));
     }
 
-    // Add extra color stop at the beginning if first element offset is not zero.
-    if (stops.at(0).offset > 0)
-        stops.insert(0, Gradient::ColorStop(0, stops.at(0).color));
-    // Add extra color stop at the end if last element offset is not zero.
-    if (stops.at(stops.size() - 1).offset < 1)
-        stops.append(Gradient::ColorStop(1, stops.at(stops.size() - 1).color));
+    if (stops.first().offset > 0.0f)
+        stops.insert(0, Gradient::ColorStop { 0.0f, stops.first().color });
+    if (stops.last().offset < 1.0f)
+        stops.append({ 1.0f, stops.last().color });
 
-    for (size_t i = 0; i < stops.size() - 1; i++) {
-        from = stops.at(i), to = stops.at(i + 1);
-        addConicSector(gradient, xo, yo, r, angleRadians, from, to, globalAlpha);
-    }
-
+    auto gradient = adoptRef(cairo_pattern_create_mesh());
+    for (size_t i = 0; i < stops.size() - 1; i++)
+        addConicSector(gradient.get(), xo, yo, r, angleRadians, stops[i], stops[i + 1], globalAlpha);
     return gradient;
 }
 
-cairo_pattern_t* Gradient::createPlatformGradient(float globalAlpha)
+RefPtr<cairo_pattern_t> Gradient::createPattern(float globalAlpha)
 {
-    cairo_pattern_t* gradient = WTF::switchOn(m_data,
-        [&] (const LinearData& data) -> cairo_pattern_t* {
-            return cairo_pattern_create_linear(data.point0.x(), data.point0.y(), data.point1.x(), data.point1.y());
+    auto gradient = WTF::switchOn(m_data,
+        [&] (const LinearData& data) {
+            auto gradient = adoptRef(cairo_pattern_create_linear(data.point0.x(), data.point0.y(), data.point1.x(), data.point1.y()));
+            for (auto& stop : stops())
+                addColorStopRGBA(gradient.get(), stop, globalAlpha);
+            return gradient;
         },
-        [&] (const RadialData& data) -> cairo_pattern_t* {
-            return cairo_pattern_create_radial(data.point0.x(), data.point0.y(), data.startRadius, data.point1.x(), data.point1.y(), data.endRadius);
+        [&] (const RadialData& data) {
+            auto gradient = adoptRef(cairo_pattern_create_radial(data.point0.x(), data.point0.y(), data.startRadius, data.point1.x(), data.point1.y(), data.endRadius));
+            for (auto& stop : stops())
+                addColorStopRGBA(gradient.get(), stop, globalAlpha);
+            return gradient;
         },
-        [&] (const ConicData& data)  -> cairo_pattern_t* {
+        [&] (const ConicData& data) {
             // FIXME: data passed for a Conic gradient doesn't contain a radius. That's apparently correct because the W3C spec
             // (https://www.w3.org/TR/css-images-4/#conic-gradients) states a conic gradient is only defined by its position and angle.
             // Thus, here I give the radius an extremely large value. The resulting gradient will be later clipped by fillRect.
@@ -201,27 +191,21 @@
         }
     );
 
-    if (type() != Type::Conic) {
-        for (const auto& stop : stops()) {
-            addColorStopRGBA(gradient, stop, globalAlpha);
-        }
-    }
-
     switch (m_spreadMethod) {
     case GradientSpreadMethod::Pad:
-        cairo_pattern_set_extend(gradient, CAIRO_EXTEND_PAD);
+        cairo_pattern_set_extend(gradient.get(), CAIRO_EXTEND_PAD);
         break;
     case GradientSpreadMethod::Reflect:
-        cairo_pattern_set_extend(gradient, CAIRO_EXTEND_REFLECT);
+        cairo_pattern_set_extend(gradient.get(), CAIRO_EXTEND_REFLECT);
         break;
     case GradientSpreadMethod::Repeat:
-        cairo_pattern_set_extend(gradient, CAIRO_EXTEND_REPEAT);
+        cairo_pattern_set_extend(gradient.get(), CAIRO_EXTEND_REPEAT);
         break;
     }
 
     cairo_matrix_t matrix = toCairoMatrix(m_gradientSpaceTransformation);
     cairo_matrix_invert(&matrix);
-    cairo_pattern_set_matrix(gradient, &matrix);
+    cairo_pattern_set_matrix(gradient.get(), &matrix);
 
     return gradient;
 }
@@ -228,8 +212,8 @@
 
 void Gradient::fill(GraphicsContext& context, const FloatRect& rect)
 {
-    RefPtr<cairo_pattern_t> platformGradient = adoptRef(createPlatformGradient(1.0));
-    if (!platformGradient)
+    auto pattern = createPattern(1.0);
+    if (!pattern)
         return;
 
     ASSERT(context.hasPlatformContext());
@@ -236,7 +220,7 @@
     auto& platformContext = *context.platformContext();
 
     Cairo::save(platformContext);
-    Cairo::fillRect(platformContext, rect, platformGradient.get());
+    Cairo::fillRect(platformContext, rect, pattern.get());
     Cairo::restore(platformContext);
 }
 

Modified: trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -33,11 +33,11 @@
 #include "FloatRoundedRect.h"
 #include "Font.h"
 #include "GlyphBuffer.h"
+#include "Gradient.h"
 #include "GraphicsContextPlatformPrivateCairo.h"
 #include "ImageBuffer.h"
 #include "IntRect.h"
 
-
 namespace WebCore {
 
 GraphicsContext::GraphicsContextImplFactory GraphicsContextImplCairo::createFactory(PlatformContextCairo& platformContext)
@@ -154,12 +154,12 @@
 
 void GraphicsContextImplCairo::fillRect(const FloatRect& rect, Gradient& gradient)
 {
-    RefPtr<cairo_pattern_t> platformGradient = adoptRef(gradient.createPlatformGradient(1.0));
-    if (!platformGradient)
+    auto pattern = gradient.createPattern(1.0);
+    if (!pattern)
         return;
 
     Cairo::save(m_platformContext);
-    Cairo::fillRect(m_platformContext, rect, platformGradient.get());
+    Cairo::fillRect(m_platformContext, rect, pattern.get());
     Cairo::restore(m_platformContext);
 }
 

Modified: trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -35,19 +35,15 @@
 
 namespace WebCore {
 
-void Gradient::platformDestroy()
+void Gradient::stopsChanged()
 {
-    CGGradientRelease(m_gradient);
     m_gradient = nullptr;
 }
 
-CGGradientRef Gradient::platformGradient()
+void Gradient::createCGGradient()
 {
-    if (m_gradient)
-        return m_gradient;
+    sortStops();
 
-    sortStopsIfNecessary();
-
     auto colorsArray = adoptCF(CFArrayCreateMutable(0, m_stops.size(), &kCFTypeArrayCallBacks));
     unsigned numStops = m_stops.size();
 
@@ -82,11 +78,9 @@
     }
 
     if (hasExtendedColors)
-        m_gradient = CGGradientCreateWithColors(extendedSRGBColorSpaceRef(), colorsArray.get(), locations.data());
+        m_gradient = adoptCF(CGGradientCreateWithColors(extendedSRGBColorSpaceRef(), colorsArray.get(), locations.data()));
     else
-        m_gradient = CGGradientCreateWithColorComponents(sRGBColorSpaceRef(), colorComponents.data(), locations.data(), numStops);
-
-    return m_gradient;
+        m_gradient = adoptCF(CGGradientCreateWithColorComponents(sRGBColorSpaceRef(), colorComponents.data(), locations.data(), numStops));
 }
 
 void Gradient::fill(GraphicsContext& context, const FloatRect& rect)
@@ -103,8 +97,10 @@
 void Gradient::paint(CGContextRef platformContext)
 {
     CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
-    CGGradientRef gradient = platformGradient();
 
+    if (!m_gradient)
+        createCGGradient();
+
     WTF::switchOn(m_data,
         [&] (const LinearData& data) {
             switch (m_spreadMethod) {
@@ -146,7 +142,7 @@
                         CGPoint left = CGPointMake(flip ? start + width : start, boundingBox.origin.y);
                         CGPoint right = CGPointMake(flip ? start : start + width, boundingBox.origin.y);
 
-                        CGContextDrawLinearGradient(platformContext, gradient, left, right, extendOptions);
+                        CGContextDrawLinearGradient(platformContext, m_gradient.get(), left, right, extendOptions);
 
                         if (m_spreadMethod == GradientSpreadMethod::Reflect)
                             flip = !flip;
@@ -158,7 +154,7 @@
                 FALLTHROUGH;
             }
             case GradientSpreadMethod::Pad:
-                CGContextDrawLinearGradient(platformContext, gradient, data.point0, data.point1, extendOptions);
+                CGContextDrawLinearGradient(platformContext, m_gradient.get(), data.point0, data.point1, extendOptions);
             }
         },
         [&] (const RadialData& data) {
@@ -173,7 +169,7 @@
                 CGContextTranslateCTM(platformContext, -data.point0.x(), -data.point0.y());
             }
 
-            CGContextDrawRadialGradient(platformContext, gradient, data.point0, data.startRadius, data.point1, data.endRadius, extendOptions);
+            CGContextDrawRadialGradient(platformContext, m_gradient.get(), data.point0, data.startRadius, data.point1, data.endRadius, extendOptions);
 
             if (needScaling)
                 CGContextRestoreGState(platformContext);
@@ -186,7 +182,7 @@
             CGContextTranslateCTM(platformContext, data.point0.x(), data.point0.y());
             CGContextRotateCTM(platformContext, (CGFloat)-M_PI_2);
             CGContextTranslateCTM(platformContext, -data.point0.x(), -data.point0.y());
-            CGContextDrawConicGradient(platformContext, platformGradient(), data.point0, data.angleRadians);
+            CGContextDrawConicGradient(platformContext, m_gradient.get(), data.point0, data.angleRadians);
             CGContextRestoreGState(platformContext);
 #else
             UNUSED_PARAM(data);

Modified: trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -32,6 +32,7 @@
 #include "AffineTransform.h"
 #include "DisplayListRecorder.h"
 #include "FloatConversion.h"
+#include "Gradient.h"
 #include "GraphicsContextPlatformPrivateCG.h"
 #include "ImageBuffer.h"
 #include "ImageOrientation.h"

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h	2020-07-12 17:28:02 UTC (rev 264280)
@@ -27,15 +27,14 @@
 
 #include "AlphaPremultiplication.h"
 #include "DisplayList.h"
-#include "FloatPoint.h"
 #include "FloatRoundedRect.h"
 #include "Font.h"
 #include "GlyphBuffer.h"
+#include "Gradient.h"
 #include "Image.h"
 #include "ImageData.h"
 #include "Pattern.h"
 #include "SharedBuffer.h"
-#include <wtf/RefCounted.h>
 #include <wtf/TypeCasts.h>
 
 namespace WTF {

Modified: trunk/Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -31,6 +31,7 @@
 
 #include "CairoOperations.h"
 #include "FloatRoundedRect.h"
+#include "Gradient.h"
 #include "ImageBuffer.h"
 #include "NicosiaPaintingOperationReplayCairo.h"
 #include <type_traits>
@@ -291,7 +292,7 @@
         }
     };
 
-    append(createCommand<FillRect>(rect, adoptRef(gradient.createPlatformGradient(1.0))));
+    append(createCommand<FillRect>(rect, gradient.createPattern(1.0)));
 }
 
 void CairoOperationRecorder::fillRect(const FloatRect& rect, const Color& color, CompositeOperator compositeOperator, BlendMode blendMode)

Modified: trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.cpp (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -301,7 +301,7 @@
         AffineTransform userToBaseCTM; // FIXME: This isn't really needed on Windows
         brush = state.fillPattern->createPlatformPattern(context, state.alpha, userToBaseCTM);
     } else if (state.fillGradient && !state.fillGradient->stops().isEmpty())
-        brush = state.fillGradient->createPlatformGradientIfNecessary(platformContext.renderTarget());
+        brush = state.fillGradient->createBrush(platformContext.renderTarget());
     else
         brush = platformContext.brushWithColor(color);
 }
@@ -318,7 +318,7 @@
         AffineTransform userToBaseCTM; // FIXME: This isn't really needed on Windows
         brush = state.strokePattern->createPlatformPattern(context, state.alpha, userToBaseCTM);
     } else if (state.strokeGradient)
-        brush = state.strokeGradient->createPlatformGradientIfNecessary(platformContext.renderTarget());
+        brush = state.strokeGradient->createBrush(platformContext.renderTarget());
     else
         brush = platformContext.brushWithColor(color);
 }

Modified: trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -31,31 +31,16 @@
 #include "PlatformContextDirect2D.h"
 #include <d2d1.h>
 #include <wtf/MathExtras.h>
-#include <wtf/RetainPtr.h>
 
 #define GRADIENT_DRAWING 3
 
 namespace WebCore {
 
-void Gradient::platformDestroy()
+void Gradient::stopsChanged()
 {
-    if (m_gradient)
-        m_gradient->Release();
-    m_gradient = nullptr;
+    m_brush = nullptr;
 }
 
-ID2D1Brush* Gradient::platformGradient()
-{
-    ASSERT(m_gradient);
-    return m_gradient;
-}
-
-ID2D1Brush* Gradient::createPlatformGradientIfNecessary(ID2D1RenderTarget* context)
-{
-    generateGradient(context);
-    return m_gradient;
-}
-
 static bool circleIsEntirelyContained(const FloatPoint& centerA, float radiusA, const FloatPoint& centerB, float radiusB)
 {
     double deltaX = centerB.x() - centerA.x();
@@ -65,15 +50,16 @@
     return deltaX * deltaX + deltaY * deltaY < deltaRadius * deltaRadius && radiusA < radiusB;
 }
 
-void Gradient::generateGradient(ID2D1RenderTarget* renderTarget)
+ID2D1Brush* Gradient::createBrush(ID2D1RenderTarget* renderTarget)
 {
-    sortStopsIfNecessary();
+    sortStops();
 
     Vector<D2D1_GRADIENT_STOP> gradientStops;
-    // FIXME: Add support for ExtendedColor.
-    for (auto stop : m_stops) {
+    gradientStops.reserveInitialCapacity(m_stops.size());
+    for (auto& stop : m_stops) {
+        // FIXME: Add support for non-sRGBA color spaces.
         auto [r, g, b, a] stop.color.toSRGBALossy<float>();
-        gradientStops.append(D2D1::GradientStop(stop.offset, D2D1::ColorF(r, g, b, a)));
+        gradientStops.gradientStops.uncheckedAppend(D2D1::GradientStop(stop.offset, D2D1::ColorF(r, g, b, a)));
     }
 
     WTF::switchOn(m_data,
@@ -122,11 +108,6 @@
     HRESULT hr = renderTarget->CreateGradientStopCollection(gradientStops.data(), gradientStops.size(), &gradientStopCollection);
     RELEASE_ASSERT(SUCCEEDED(hr));
 
-    if (m_gradient) {
-        m_gradient->Release();
-        m_gradient = nullptr;
-    }
-
     WTF::switchOn(m_data,
         [&] (const LinearData& data) {
             ID2D1LinearGradientBrush* linearGradient = nullptr;
@@ -135,7 +116,7 @@
                 D2D1::BrushProperties(), gradientStopCollection.get(),
                 &linearGradient);
             RELEASE_ASSERT(SUCCEEDED(hr));
-            m_gradient = linearGradient;
+            m_brush = adoptCOM(linearGradient);
         },
         [&] (const RadialData& data) {
             FloatSize offset;
@@ -154,14 +135,15 @@
                 D2D1::BrushProperties(), gradientStopCollection.get(),
                 &radialGradient);
             RELEASE_ASSERT(SUCCEEDED(hr));
-            m_gradient = radialGradient;
+            m_brush = adoptCOM(radialGradient);
         },
         [&] (const ConicData&) {
             // FIXME: implement conic gradient rendering.
+            m_brush = nullptr;
         }
     );
 
-    hash();
+    return m_brush.get();
 }
 
 void Gradient::fill(GraphicsContext& context, const FloatRect& rect)
@@ -170,8 +152,9 @@
 
     WTF::switchOn(m_data,
         [&] (const LinearData& data) {
-            if (!m_cachedHash || !m_gradient)
-                generateGradient(d2dContext);
+            // FIXME: If we have a brush, why can we re-use it? What guarantees it's right for this context?
+            if (!m_brush)
+                createBrush(d2dContext);
 
 #if ASSERT_ENABLED
             d2dContext->SetTags(GRADIENT_DRAWING, __LINE__);
@@ -178,7 +161,7 @@
 #endif
 
             const D2D1_RECT_F d2dRect = rect;
-            d2dContext->FillRectangle(&d2dRect, m_gradient);
+            d2dContext->FillRectangle(&d2dRect, m_brush.get());
         },
         [&] (const RadialData& data) {
             bool needScaling = data.aspectRatio != 1;
@@ -199,8 +182,9 @@
                 d2dContext->SetTransform(ctm);
             }
 
-            if (!m_cachedHash || !m_gradient)
-                generateGradient(d2dContext);
+            // FIXME: If we have a brush, why can we re-use it? What guarantees it's right for this context?
+            if (!m_brush)
+                createBrush(d2dContext);
 
 #if ASSERT_ENABLED
             d2dContext->SetTags(GRADIENT_DRAWING, __LINE__);
@@ -207,7 +191,7 @@
 #endif
 
             const D2D1_RECT_F d2dRect = rect;
-            d2dContext->FillRectangle(&d2dRect, m_gradient);
+            d2dContext->FillRectangle(&d2dRect, m_brush.get());
 
             if (needScaling)
                 context.restore();

Modified: trunk/Source/WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp (264279 => 264280)


--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -155,11 +155,11 @@
 
 void GraphicsContextImplDirect2D::fillRect(const FloatRect& rect, Gradient& gradient)
 {
-    COMPtr<ID2D1Brush> platformGradient = gradient.createPlatformGradientIfNecessary(m_platformContext.renderTarget());
-    if (!platformGradient)
+    auto brush = gradient.createBrush(m_platformContext.renderTarget());
+    if (!brush)
         return;
 
-    Direct2D::fillRectWithGradient(m_platformContext, rect, platformGradient.get());
+    Direct2D::fillRectWithGradient(m_platformContext, rect, brush.get());
 }
 
 void GraphicsContextImplDirect2D::fillRect(const FloatRect& rect, const Color& color, CompositeOperator compositeOperator, BlendMode blendMode)

Modified: trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm (264279 => 264280)


--- trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm	2020-07-12 17:28:02 UTC (rev 264280)
@@ -28,7 +28,7 @@
 
 #if ENABLE(SMOOTH_SCROLLING)
 
-#import "FloatPoint.h"
+#import "Gradient.h"
 #import "GraphicsLayer.h"
 #import "Logging.h"
 #import "NSScrollerImpDetails.h"

Modified: trunk/Source/WebCore/rendering/RenderThemeIOS.mm (264279 => 264280)


--- trunk/Source/WebCore/rendering/RenderThemeIOS.mm	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/rendering/RenderThemeIOS.mm	2020-07-12 17:28:02 UTC (rev 264280)
@@ -900,7 +900,7 @@
         return true;
 
     const int progressBarHeight = 9;
-    const float verticalOffset = (rect.height() - progressBarHeight) / 2.0;
+    const float verticalOffset = (rect.height() - progressBarHeight) / 2.0f;
 
     GraphicsContextStateSaver stateSaver(paintInfo.context());
     if (rect.width() < 10 || rect.height() < 9) {
@@ -912,21 +912,21 @@
     // 1) Draw the progress bar track.
     // 1.1) Draw the white background with grey gradient border.
     GraphicsContext& context = paintInfo.context();
-    context.setStrokeThickness(0.68);
+    context.setStrokeThickness(0.68f);
     context.setStrokeStyle(SolidStroke);
 
     const float verticalRenderingPosition = rect.y() + verticalOffset;
     auto strokeGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) });
-    strokeGradient->addColorStop(0.0, makeSimpleColor(141, 141, 141));
-    strokeGradient->addColorStop(0.45, makeSimpleColor(238, 238, 238));
-    strokeGradient->addColorStop(0.55, makeSimpleColor(238, 238, 238));
-    strokeGradient->addColorStop(1.0, makeSimpleColor(141, 141, 141));
+    strokeGradient->addColorStop({ 0.0f, makeSimpleColor(141, 141, 141) });
+    strokeGradient->addColorStop({ 0.45f, makeSimpleColor(238, 238, 238) });
+    strokeGradient->addColorStop({ 0.55f, makeSimpleColor(238, 238, 238) });
+    strokeGradient->addColorStop({ 1.0f, makeSimpleColor(141, 141, 141) });
     context.setStrokeGradient(WTFMove(strokeGradient));
 
     context.setFillColor(Color::black);
 
     Path trackPath;
-    FloatRect trackRect(rect.x() + 0.25, verticalRenderingPosition + 0.25, rect.width() - 0.5, progressBarHeight - 0.5);
+    FloatRect trackRect(rect.x() + 0.25f, verticalRenderingPosition + 0.25f, rect.width() - 0.5f, progressBarHeight - 0.5f);
     FloatSize roundedCornerRadius(5, 4);
     trackPath.addRoundedRect(trackRect, roundedCornerRadius);
     context.drawPath(trackPath);
@@ -936,9 +936,9 @@
     paintInfo.context().clipRoundedRect(FloatRoundedRect(border, roundedCornerRadius, roundedCornerRadius, roundedCornerRadius, roundedCornerRadius));
 
     float upperGradientHeight = progressBarHeight / 2.;
-    auto upperGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5), FloatPoint(rect.x(), verticalRenderingPosition + upperGradientHeight - 1.5) });
-    upperGradient->addColorStop(0.0, makeSimpleColor(133, 133, 133, 188));
-    upperGradient->addColorStop(1.0, makeSimpleColor(18, 18, 18, 51));
+    auto upperGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5f), FloatPoint(rect.x(), verticalRenderingPosition + upperGradientHeight - 1.5) });
+    upperGradient->addColorStop({ 0.0f, makeSimpleColor(133, 133, 133, 188) });
+    upperGradient->addColorStop({ 1.0f, makeSimpleColor(18, 18, 18, 51) });
     context.setFillGradient(WTFMove(upperGradient));
 
     context.fillRect(FloatRect(rect.x(), verticalRenderingPosition, rect.width(), upperGradientHeight));
@@ -947,20 +947,20 @@
     if (renderProgress.isDeterminate()) {
         // 2) Draw the progress bar.
         double position = clampTo(renderProgress.position(), 0.0, 1.0);
-        double barWidth = position * rect.width();
-        auto barGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) });
-        barGradient->addColorStop(0.0, makeSimpleColor(195, 217, 247));
-        barGradient->addColorStop(0.45, makeSimpleColor(118, 164, 228));
-        barGradient->addColorStop(0.49, makeSimpleColor(118, 164, 228));
-        barGradient->addColorStop(0.51, makeSimpleColor(36, 114, 210));
-        barGradient->addColorStop(0.55, makeSimpleColor(36, 114, 210));
-        barGradient->addColorStop(1.0, makeSimpleColor(57, 142, 244));
+        float barWidth = position * rect.width();
+        auto barGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5f), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) });
+        barGradient->addColorStop({ 0.0f, makeSimpleColor(195, 217, 247) });
+        barGradient->addColorStop({ 0.45f, makeSimpleColor(118, 164, 228) });
+        barGradient->addColorStop({ 0.49f, makeSimpleColor(118, 164, 228) });
+        barGradient->addColorStop({ 0.51f, makeSimpleColor(36, 114, 210) });
+        barGradient->addColorStop({ 0.55f, makeSimpleColor(36, 114, 210) });
+        barGradient->addColorStop({ 1.0f, makeSimpleColor(57, 142, 244) });
         context.setFillGradient(WTFMove(barGradient));
 
         auto barStrokeGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) });
-        barStrokeGradient->addColorStop(0.0, makeSimpleColor(95, 107, 183));
-        barStrokeGradient->addColorStop(0.5, makeSimpleColor(66, 106, 174, 240));
-        barStrokeGradient->addColorStop(1.0, makeSimpleColor(38, 104, 166));
+        barStrokeGradient->addColorStop({ 0.0f, makeSimpleColor(95, 107, 183) });
+        barStrokeGradient->addColorStop({ 0.5f, makeSimpleColor(66, 106, 174, 240) });
+        barStrokeGradient->addColorStop({ 1.0f, makeSimpleColor(38, 104, 166) });
         context.setStrokeGradient(WTFMove(barStrokeGradient));
 
         Path barPath;
@@ -967,7 +967,7 @@
         int left = rect.x();
         if (!renderProgress.style().isLeftToRightDirection())
             left = rect.maxX() - barWidth;
-        FloatRect barRect(left + 0.25, verticalRenderingPosition + 0.25, std::max(barWidth - 0.5, 0.0), progressBarHeight - 0.5);
+        FloatRect barRect(left + 0.25f, verticalRenderingPosition + 0.25f, std::max(barWidth - 0.5f, 0.0f), progressBarHeight - 0.5f);
         barPath.addRoundedRect(barRect, roundedCornerRadius);
         context.drawPath(barPath);
     }

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp (264279 => 264280)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -234,12 +234,10 @@
 
 void RenderSVGResourceGradient::addStops(GradientData* gradientData, const Vector<Gradient::ColorStop>& stops, const RenderStyle& style) const
 {
+    ASSERT(gradientData);
     ASSERT(gradientData->gradient);
-
-    for (Gradient::ColorStop stop : stops) {
-        stop.color = style.colorByApplyingColorFilter(stop.color);
-        gradientData->gradient->addColorStop(stop);
-    }
+    for (auto& stop : stops)
+        gradientData->gradient->addColorStop({ stop.offset, style.colorByApplyingColorFilter(stop.color) });
 }
 
 GradientSpreadMethod RenderSVGResourceGradient::platformSpreadMethodFromSVGType(SVGSpreadMethodType method) const

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h (264279 => 264280)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h	2020-07-12 17:28:02 UTC (rev 264280)
@@ -21,7 +21,6 @@
 
 #pragma once
 
-#include "Gradient.h"
 #include "ImageBuffer.h"
 #include "RenderSVGResourceContainer.h"
 #include "SVGGradientElement.h"

Modified: trunk/Source/WebCore/svg/SVGGradientElement.cpp (264279 => 264280)


--- trunk/Source/WebCore/svg/SVGGradientElement.cpp	2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/svg/SVGGradientElement.cpp	2020-07-12 17:28:02 UTC (rev 264280)
@@ -102,18 +102,11 @@
 {
     Vector<Gradient::ColorStop> stops;
     float previousOffset = 0.0f;
-
     for (auto& stop : childrenOfType<SVGStopElement>(*this)) {
-        const Color& color = stop.stopColorIncludingOpacity();
-
-        // Figure out right monotonic offset.
-        float offset = stop.offset();
-        offset = std::min(std::max(previousOffset, offset), 1.0f);
-        previousOffset = offset;
-
-        stops.append(Gradient::ColorStop(offset, color));
+        auto monotonicallyIncreasingOffset = std::clamp(stop.offset(), previousOffset, 1.0f);
+        previousOffset = monotonicallyIncreasingOffset;
+        stops.append({ monotonicallyIncreasingOffset, stop.stopColorIncludingOpacity() });
     }
-
     return stops;
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to