Bug 214221

Summary: Simplify and improve Gradient, some other small color-related removals
Product: WebKit Reporter: Darin Adler <darin>
Component: Layout and RenderingAssignee: Darin Adler <darin>
Status: RESOLVED FIXED    
Severity: Normal CC: bfulgham, cdumez, changseok, dino, esprehn+autocc, ews-watchlist, fmalita, glenn, gyuyoung.kim, hi, joepeck, kondapallykalyan, macpherson, menard, mifenton, pdr, sabouhallawa, sam, schenney, sergio, simon.fraser, webkit-bug-importer, zalan
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: All   
OS: All   
See Also: https://bugs.webkit.org/show_bug.cgi?id=214259
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Patch
sam: review+
Patch
none
Patch none

Description Darin Adler 2020-07-11 09:50:03 PDT
Simplify and improve Gradient, some other small color-related removals
Comment 1 Darin Adler 2020-07-11 11:41:52 PDT Comment hidden (obsolete)
Comment 2 Darin Adler 2020-07-11 13:59:42 PDT Comment hidden (obsolete)
Comment 3 Darin Adler 2020-07-11 14:12:49 PDT Comment hidden (obsolete)
Comment 4 Darin Adler 2020-07-11 15:41:48 PDT
Created attachment 404073 [details]
Patch
Comment 5 Sam Weinig 2020-07-11 16:12:35 PDT
Comment on attachment 404073 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=404073&action=review

> Source/WebCore/platform/graphics/Gradient.h:107
>      WEBCORE_EXPORT static Ref<Gradient> create(LinearData&&);
>      WEBCORE_EXPORT static Ref<Gradient> create(RadialData&&);
> -    WEBCORE_EXPORT static Ref<Gradient> create(ConicData&&);
> +    WEBCORE_EXPORT static Ref<Gradient> create(Data&&);

The inconsistency here bugs me. Why do we still need the create functions taking LinearData or RadialData?

> Source/WebCore/platform/graphics/Gradient.h:166
>  
>      mutable unsigned m_cachedHash { 0 };

Might be able save a byte or two if we re-order things so m_stopsSorted, m_spreadMethod and m_cachedHash pack next to each other.

> Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp:238
>  void RenderSVGResourceGradient::addStops(GradientData* gradientData, const Vector<Gradient::ColorStop>& stops, const RenderStyle& style) const
>  {
> +    ASSERT(gradientData);
>      ASSERT(gradientData->gradient);

Not sure how far you want to go, but it looks like all the callers can prove GradientData to be non-null so this could be switched to pass by reference.
Comment 6 Darin Adler 2020-07-12 09:05:45 PDT
Comment on attachment 404073 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=404073&action=review

>> Source/WebCore/platform/graphics/Gradient.h:107
>> +    WEBCORE_EXPORT static Ref<Gradient> create(Data&&);
> 
> The inconsistency here bugs me. Why do we still need the create functions taking LinearData or RadialData?

We don’t need them; for some reason I just didn’t think of removing them. I can, and should.

>> Source/WebCore/platform/graphics/Gradient.h:166
>>      mutable unsigned m_cachedHash { 0 };
> 
> Might be able save a byte or two if we re-order things so m_stopsSorted, m_spreadMethod and m_cachedHash pack next to each other.

Yes, right now they are in a sort of "logical" order rather than a packing order, since the hash isn’t part of the gradient’s state. I am not sure I want to make the change, but I really don’t object either.

>> Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp:238
>>      ASSERT(gradientData->gradient);
> 
> Not sure how far you want to go, but it looks like all the callers can prove GradientData to be non-null so this could be switched to pass by reference.

That’s what I had in mind when I wrote the assertion. Any time a function asserts a pointer argument is non-null, to me that says "need to change the interface". But I was trying to stick to Gradient.h for this patch.
Comment 7 Darin Adler 2020-07-12 09:48:20 PDT
Comment on attachment 404073 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=404073&action=review

>>> Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp:238
>>>      ASSERT(gradientData->gradient);
>> 
>> Not sure how far you want to go, but it looks like all the callers can prove GradientData to be non-null so this could be switched to pass by reference.
> 
> That’s what I had in mind when I wrote the assertion. Any time a function asserts a pointer argument is non-null, to me that says "need to change the interface". But I was trying to stick to Gradient.h for this patch.

I started down the rabbit hole, but pulled back. Things I ran into:

- GradientData struct uses WTF_MAKE_FAST_ALLOCATED but should use WTF_MAKE_STRUCT_FAST_ALLOCATED
- RenderSVGResourceGradient::addStops should take Gradient& argument, not a GradientData*.
- RenderSVGResourceGradient::buildGradient should return a Ref<Gradient>, not take a GradientData* argument, allowing us to remove unnecessary null check from RenderSVGResourceGradient::applyResource.
- RenderSVGResourceGradient::applyResource should use ensure and a lambda construct the GradientData initialized rather than first constructing it and then initializing it.
- RenderSVGResourceGradient::m_gradientMap should probably contain GradientData rather than std::unique_ptr<GradientData>.
Comment 8 Darin Adler 2020-07-12 09:55:01 PDT Comment hidden (obsolete)
Comment 9 Darin Adler 2020-07-12 10:13:23 PDT
Created attachment 404104 [details]
Patch
Comment 10 Darin Adler 2020-07-12 10:28:07 PDT
Committed r264280: <https://trac.webkit.org/changeset/264280>
Comment 11 Radar WebKit Bug Importer 2020-07-12 10:29:16 PDT
<rdar://problem/65436807>