Title: [273776] trunk
Revision
273776
Author
[email protected]
Date
2021-03-02 17:25:52 -0800 (Tue, 02 Mar 2021)

Log Message

Reduce the size of extended colors by storing the color space in free bits of the owning Color
https://bugs.webkit.org/show_bug.cgi?id=222584

Reviewed by Darin Adler.

Source/WebCore:

Reduce the size of non-SRBGA<uint8_t> colors by moving the color space from the ref counted
out-of-line bit into the free bits of the Color itself.

Also, take the opertunity to move and rename the out of line bit from it's own file named
ExtendedColor to a private nested type called OutOfLineComponents.

Color now encodes the following data:
    |   8 bits   |   8 bits   |          48 (or 32) bits          |
    | ColorSpace |    Flags   |   InlineColorDataOrOutOfLinePtr   |

ColorSpace actually only uses 4 bits, so if we need more room for flags
in the future, we could pack things even more tightly.

Additionally, take the opportunity to remove the isInline/isExtended and
asInline/asExtended functions. The functionality of isInline/asInline
is still necessary in some places, but can be replaced by a single
tryGetAsSRGBABytes which returns an Optional<SRGBA<uint8_t>> with a
valid value when the stored value is inline.

Since ExtendedColor is no longer accessible, a few tests that checked things like
the ref count of the ExtendedColor had to be changed.

* Headers.cmake:
* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/Color.cpp:
(WebCore::Color::Color):
(WebCore::Color::operator=):
(WebCore::Color::semanticColor const):
(WebCore::Color::colorSpaceAndComponents const):
* platform/graphics/Color.h:
(WebCore::Color::Color):
(WebCore::Color::isOpaque const):
(WebCore::Color::isVisible const):
(WebCore::Color::alphaByte const):
(WebCore::Color::alphaAsFloat const):
(WebCore::Color::OutOfLineComponents::create):
(WebCore::Color::OutOfLineComponents::alpha const):
(WebCore::Color::OutOfLineComponents::components const):
(WebCore::Color::OutOfLineComponents::OutOfLineComponents):
(WebCore::Color::setOutOfLineComponents):
(WebCore::operator==):
(WebCore::outOfLineComponentsEqual):
(WebCore::outOfLineComponentsEqualIgnoringSemanticColor):
(WebCore::equalIgnoringSemanticColor):
(WebCore::Color::~Color):
(WebCore::Color::hash const):
(WebCore::Color::colorSpace const):
(WebCore::Color::callOnUnderlyingType const):
(WebCore::Color::isOutOfLine const):
(WebCore::Color::isInline const):
(WebCore::Color::asOutOfLine const):
(WebCore::Color::asOutOfLineRef const):
(WebCore::Color::tryGetAsSRGBABytes const):
(WebCore::Color::encodedFlags):
(WebCore::Color::encodedColorSpace):
(WebCore::Color::encodedOutOfLineComponents):
(WebCore::Color::decodedFlags):
(WebCore::Color::decodedColorSpace):
(WebCore::Color::decodedOutOfLineComponents):
(WebCore::Color::setColor):
(WebCore::Color::encode const):
(WebCore::Color::decode):
(WebCore::Color::setExtendedColor): Deleted.
(WebCore::extendedColorsEqual): Deleted.
(WebCore::extendedColorsEqualIgnoringSemanticColor): Deleted.
(WebCore::Color::isExtended const): Deleted.
(WebCore::Color::asExtended const): Deleted.
(WebCore::Color::asExtendedRef const): Deleted.
(WebCore::Color::encodedExtendedColor): Deleted.
(WebCore::Color::decodedExtendedColor): Deleted.
* platform/graphics/ColorSerialization.cpp:
* platform/graphics/ExtendedColor.h: Removed.
* platform/graphics/cg/ColorCG.cpp:
(WebCore::cachedCGColor):
* platform/graphics/cg/GradientCG.cpp:
(WebCore::Gradient::createCGGradient):
* platform/graphics/displaylists/DisplayListItems.cpp:
(WebCore::DisplayList::SetInlineFillGradient::SetInlineFillGradient):
(WebCore::DisplayList::SetInlineFillGradient::isInline):
* platform/graphics/displaylists/DisplayListRecorder.cpp:
(WebCore::DisplayList::containsOnlyInlineStateChanges):
(WebCore::DisplayList::Recorder::appendStateChangeItem):
* platform/graphics/mac/ColorMac.mm:
(WebCore::nsColor):

Tools:

* TestWebKitAPI/CMakeLists.txt:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/ColorTests.cpp:
(TestWebKitAPI::TEST):
(TestWebKitAPI::makeColor):
* TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp:
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp: Removed.
Update tests to account for removal of the ExtendedColor class.
Merge ExtendedColorTests.cpp that still make sense into ColorTests.cpp

Modified Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (273775 => 273776)


--- trunk/Source/WebCore/ChangeLog	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Source/WebCore/ChangeLog	2021-03-03 01:25:52 UTC (rev 273776)
@@ -1,3 +1,95 @@
+2021-03-02  Sam Weinig  <[email protected]>
+
+        Reduce the size of extended colors by storing the color space in free bits of the owning Color
+        https://bugs.webkit.org/show_bug.cgi?id=222584
+
+        Reviewed by Darin Adler.
+
+        Reduce the size of non-SRBGA<uint8_t> colors by moving the color space from the ref counted
+        out-of-line bit into the free bits of the Color itself.
+        
+        Also, take the opertunity to move and rename the out of line bit from it's own file named
+        ExtendedColor to a private nested type called OutOfLineComponents.
+
+        Color now encodes the following data:
+            |   8 bits   |   8 bits   |          48 (or 32) bits          |
+            | ColorSpace |    Flags   |   InlineColorDataOrOutOfLinePtr   |
+
+        ColorSpace actually only uses 4 bits, so if we need more room for flags
+        in the future, we could pack things even more tightly.
+
+        Additionally, take the opportunity to remove the isInline/isExtended and
+        asInline/asExtended functions. The functionality of isInline/asInline
+        is still necessary in some places, but can be replaced by a single
+        tryGetAsSRGBABytes which returns an Optional<SRGBA<uint8_t>> with a 
+        valid value when the stored value is inline.
+
+        Since ExtendedColor is no longer accessible, a few tests that checked things like
+        the ref count of the ExtendedColor had to be changed.
+
+        * Headers.cmake:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/Color.cpp:
+        (WebCore::Color::Color):
+        (WebCore::Color::operator=):
+        (WebCore::Color::semanticColor const):
+        (WebCore::Color::colorSpaceAndComponents const):
+        * platform/graphics/Color.h:
+        (WebCore::Color::Color):
+        (WebCore::Color::isOpaque const):
+        (WebCore::Color::isVisible const):
+        (WebCore::Color::alphaByte const):
+        (WebCore::Color::alphaAsFloat const):
+        (WebCore::Color::OutOfLineComponents::create):
+        (WebCore::Color::OutOfLineComponents::alpha const):
+        (WebCore::Color::OutOfLineComponents::components const):
+        (WebCore::Color::OutOfLineComponents::OutOfLineComponents):
+        (WebCore::Color::setOutOfLineComponents):
+        (WebCore::operator==):
+        (WebCore::outOfLineComponentsEqual):
+        (WebCore::outOfLineComponentsEqualIgnoringSemanticColor):
+        (WebCore::equalIgnoringSemanticColor):
+        (WebCore::Color::~Color):
+        (WebCore::Color::hash const):
+        (WebCore::Color::colorSpace const):
+        (WebCore::Color::callOnUnderlyingType const):
+        (WebCore::Color::isOutOfLine const):
+        (WebCore::Color::isInline const):
+        (WebCore::Color::asOutOfLine const):
+        (WebCore::Color::asOutOfLineRef const):
+        (WebCore::Color::tryGetAsSRGBABytes const):
+        (WebCore::Color::encodedFlags):
+        (WebCore::Color::encodedColorSpace):
+        (WebCore::Color::encodedOutOfLineComponents):
+        (WebCore::Color::decodedFlags):
+        (WebCore::Color::decodedColorSpace):
+        (WebCore::Color::decodedOutOfLineComponents):
+        (WebCore::Color::setColor):
+        (WebCore::Color::encode const):
+        (WebCore::Color::decode):
+        (WebCore::Color::setExtendedColor): Deleted.
+        (WebCore::extendedColorsEqual): Deleted.
+        (WebCore::extendedColorsEqualIgnoringSemanticColor): Deleted.
+        (WebCore::Color::isExtended const): Deleted.
+        (WebCore::Color::asExtended const): Deleted.
+        (WebCore::Color::asExtendedRef const): Deleted.
+        (WebCore::Color::encodedExtendedColor): Deleted.
+        (WebCore::Color::decodedExtendedColor): Deleted.
+        * platform/graphics/ColorSerialization.cpp:
+        * platform/graphics/ExtendedColor.h: Removed.
+        * platform/graphics/cg/ColorCG.cpp:
+        (WebCore::cachedCGColor):
+        * platform/graphics/cg/GradientCG.cpp:
+        (WebCore::Gradient::createCGGradient):
+        * platform/graphics/displaylists/DisplayListItems.cpp:
+        (WebCore::DisplayList::SetInlineFillGradient::SetInlineFillGradient):
+        (WebCore::DisplayList::SetInlineFillGradient::isInline):
+        * platform/graphics/displaylists/DisplayListRecorder.cpp:
+        (WebCore::DisplayList::containsOnlyInlineStateChanges):
+        (WebCore::DisplayList::Recorder::appendStateChangeItem):
+        * platform/graphics/mac/ColorMac.mm:
+        (WebCore::nsColor):
+
 2021-03-02  Simon Fraser  <[email protected]>
 
         Rename ForcePageRenderingUpdatesAt60FPSEnabled preference to PreferPageRenderingUpdatesNear60FPSEnabled

Modified: trunk/Source/WebCore/Headers.cmake (273775 => 273776)


--- trunk/Source/WebCore/Headers.cmake	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Source/WebCore/Headers.cmake	2021-03-03 01:25:52 UTC (rev 273776)
@@ -1181,7 +1181,6 @@
     platform/graphics/DisplayRefreshMonitor.h
     platform/graphics/DisplayRefreshMonitorClient.h
     platform/graphics/DisplayRefreshMonitorManager.h
-    platform/graphics/ExtendedColor.h
     platform/graphics/ExtensionsGL.h
     platform/graphics/FloatPoint.h
     platform/graphics/FloatPoint3D.h

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (273775 => 273776)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-03-03 01:25:52 UTC (rev 273776)
@@ -968,7 +968,6 @@
 		31C0FF250E4CEB6E007D6FE5 /* WebKitTransitionEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 31C0FF1F0E4CEB6E007D6FE5 /* WebKitTransitionEvent.h */; };
 		31C0FF3E0E4CEFAC007D6FE5 /* JSWebKitAnimationEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 31C0FF3A0E4CEFAC007D6FE5 /* JSWebKitAnimationEvent.h */; };
 		31C0FF400E4CEFAC007D6FE5 /* JSWebKitTransitionEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 31C0FF3C0E4CEFAC007D6FE5 /* JSWebKitTransitionEvent.h */; };
-		31DCDF441DA1C45400EA5B93 /* ExtendedColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 31DCDF421DA1C45400EA5B93 /* ExtendedColor.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		31DEA4561B39F4D900F77178 /* WebSystemBackdropLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 31DEA4541B39F4D900F77178 /* WebSystemBackdropLayer.h */; };
 		31EAF97E121435A400E7C1BF /* DeviceMotionClientIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 31EAF97C121435A400E7C1BF /* DeviceMotionClientIOS.h */; };
 		31EB54DF1E7DC74400C1623B /* RTCRtpTransceiverDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 31EB54DD1E7DC74400C1623B /* RTCRtpTransceiverDirection.h */; };
@@ -7507,7 +7506,6 @@
 		31D26BC41F86D266008FF255 /* JSImageBitmapOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSImageBitmapOptions.cpp; sourceTree = "<group>"; };
 		31D26BC51F86D268008FF255 /* JSImageBitmapOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSImageBitmapOptions.h; sourceTree = "<group>"; };
 		31D26BC61F86D269008FF255 /* JSImageBitmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSImageBitmap.cpp; sourceTree = "<group>"; };
-		31DCDF421DA1C45400EA5B93 /* ExtendedColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtendedColor.h; sourceTree = "<group>"; };
 		31DEA4531B39F4D900F77178 /* WebSystemBackdropLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebSystemBackdropLayer.mm; sourceTree = "<group>"; };
 		31DEA4541B39F4D900F77178 /* WebSystemBackdropLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSystemBackdropLayer.h; sourceTree = "<group>"; };
 		31EAF97C121435A400E7C1BF /* DeviceMotionClientIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceMotionClientIOS.h; sourceTree = "<group>"; };
@@ -26691,7 +26689,6 @@
 				2D29ECC2192ECC8300984B78 /* DisplayRefreshMonitorClient.h */,
 				2D29ECC3192ECC8300984B78 /* DisplayRefreshMonitorManager.cpp */,
 				2D29ECC4192ECC8300984B78 /* DisplayRefreshMonitorManager.h */,
-				31DCDF421DA1C45400EA5B93 /* ExtendedColor.h */,
 				6E67D2A81280E8BD008758F7 /* ExtensionsGL.h */,
 				B275353A0B053814002CE64F /* FloatPoint.cpp */,
 				B275353B0B053814002CE64F /* FloatPoint.h */,
@@ -32185,7 +32182,6 @@
 				2D29386B235F6B6900C7F3B2 /* ExceptionDetails.h in Headers */,
 				93D196311D6CAB7600FC7E47 /* ExceptionOr.h in Headers */,
 				837FB3451F9EA06D00D0FC31 /* ExtendableMessageEvent.h in Headers */,
-				31DCDF441DA1C45400EA5B93 /* ExtendedColor.h in Headers */,
 				6E67D2A91280E8BD008758F7 /* ExtensionsGL.h in Headers */,
 				6E72F550229DCD1700B3E151 /* ExtensionsGLANGLE.h in Headers */,
 				E47E276516036ED200EE2AFB /* ExtensionStyleSheets.h in Headers */,

Modified: trunk/Source/WebCore/platform/graphics/Color.cpp (273775 => 273776)


--- trunk/Source/WebCore/platform/graphics/Color.cpp	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Source/WebCore/platform/graphics/Color.cpp	2021-03-03 01:25:52 UTC (rev 273776)
@@ -39,8 +39,8 @@
 Color::Color(const Color& other)
     : m_colorAndFlags(other.m_colorAndFlags)
 {
-    if (isExtended())
-        asExtended().ref();
+    if (isOutOfLine())
+        asOutOfLine().ref();
 }
 
 Color::Color(Color&& other)
@@ -53,13 +53,13 @@
     if (*this == other)
         return *this;
 
-    if (isExtended())
-        asExtended().deref();
+    if (isOutOfLine())
+        asOutOfLine().deref();
 
     m_colorAndFlags = other.m_colorAndFlags;
 
-    if (isExtended())
-        asExtended().ref();
+    if (isOutOfLine())
+        asOutOfLine().ref();
 
     return *this;
 }
@@ -69,8 +69,8 @@
     if (*this == other)
         return *this;
 
-    if (isExtended())
-        asExtended().deref();
+    if (isOutOfLine())
+        asOutOfLine().deref();
 
     m_colorAndFlags = other.m_colorAndFlags;
     other.m_colorAndFlags = invalidColorAndFlags;
@@ -166,15 +166,15 @@
     if (isSemantic())
         return *this;
     
-    if (isExtended())
-        return { asExtendedRef(), Flags::Semantic };
+    if (isOutOfLine())
+        return { asOutOfLineRef(), colorSpace(), Flags::Semantic };
     return { asInline(), Flags::Semantic };
 }
 
 std::pair<ColorSpace, ColorComponents<float>> Color::colorSpaceAndComponents() const
 {
-    if (isExtended())
-        return { asExtended().colorSpace(), asExtended().components() };
+    if (isOutOfLine())
+        return { colorSpace(), asOutOfLine().components() };
     return { ColorSpace::SRGB, asColorComponents(convertColor<SRGBA<float>>(asInline())) };
 }
 

Modified: trunk/Source/WebCore/platform/graphics/Color.h (273775 => 273776)


--- trunk/Source/WebCore/platform/graphics/Color.h	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Source/WebCore/platform/graphics/Color.h	2021-03-03 01:25:52 UTC (rev 273776)
@@ -25,14 +25,17 @@
 
 #pragma once
 
+#include "ColorConversion.h"
 #include "ColorSpace.h"
 #include "ColorUtilities.h"
-#include "ExtendedColor.h"
+#include <functional>
 #include <wtf/Forward.h>
 #include <wtf/HashFunctions.h>
 #include <wtf/Hasher.h>
 #include <wtf/OptionSet.h>
 #include <wtf/Optional.h>
+#include <wtf/Ref.h>
+#include <wtf/RefCounted.h>
 #include <wtf/StdLibExtras.h>
 
 #if USE(CG)
@@ -71,8 +74,6 @@
 
     Color(SRGBA<uint8_t>, OptionSet<Flags> = { });
     Color(Optional<SRGBA<uint8_t>>, OptionSet<Flags> = { });
-
-    Color(ColorComponents<float>, ColorSpace, OptionSet<Flags> = { });
     
     template<typename ColorType, typename std::enable_if_t<IsColorTypeWithComponentType<ColorType, float>>* = nullptr>
     Color(const ColorType&, OptionSet<Flags> = { });
@@ -98,11 +99,13 @@
     bool isSemantic() const;
     bool usesColorFunctionSerialization() const;
 
-    bool isOpaque() const { return isExtended() ? asExtended().alpha() == 1.0 : asInline().alpha == 255; }
-    bool isVisible() const { return isExtended() ? asExtended().alpha() > 0.0 : asInline().alpha > 0; }
-    uint8_t alphaByte() const { return isExtended() ? convertFloatAlphaTo<uint8_t>(asExtended().alpha()) : asInline().alpha; }
-    float alphaAsFloat() const { return isExtended() ? asExtended().alpha() : convertByteAlphaTo<float>(asInline().alpha); }
+    ColorSpace colorSpace() const;
 
+    bool isOpaque() const { return isOutOfLine() ? asOutOfLine().alpha() == 1.0 : asInline().alpha == 255; }
+    bool isVisible() const { return isOutOfLine() ? asOutOfLine().alpha() > 0.0 : asInline().alpha > 0; }
+    uint8_t alphaByte() const { return isOutOfLine() ? convertFloatAlphaTo<uint8_t>(asOutOfLine().alpha()) : asInline().alpha; }
+    float alphaAsFloat() const { return isOutOfLine() ? asOutOfLine().alpha() : convertByteAlphaTo<float>(asInline().alpha); }
+
     WEBCORE_EXPORT float luminance() const;
     WEBCORE_EXPORT float lightness() const; // FIXME: Replace remaining uses with luminance.
     WEBCORE_EXPORT static float contrastRatio(const Color&, const Color&);
@@ -136,6 +139,9 @@
 
     Color semanticColor() const;
 
+    // Returns the underlying color if its type is SRGBA<uint8_t>.
+    Optional<SRGBA<uint8_t>> tryGetAsSRGBABytes() const;
+
 #if PLATFORM(GTK)
     Color(const GdkRGBA&);
     operator GdkRGBA() const;
@@ -142,8 +148,7 @@
 #endif
 
 #if USE(CG)
-    WEBCORE_EXPORT Color(CGColorRef);
-    WEBCORE_EXPORT Color(CGColorRef, OptionSet<Flags>);
+    WEBCORE_EXPORT Color(CGColorRef, OptionSet<Flags> = { });
 #endif
 
 #if PLATFORM(WIN)
@@ -167,32 +172,44 @@
     static constexpr auto darkGreen = SRGBA<uint8_t> { 0, 128, 0 };
     static constexpr auto orange = SRGBA<uint8_t> { 255, 128, 0 };
 
-    bool isExtended() const;
-    bool isInline() const;
+    static bool isBlackColor(const Color&);
+    static bool isWhiteColor(const Color&);
 
-    const ExtendedColor& asExtended() const;
-    SRGBA<uint8_t> asInline() const;
-
-    // Extended and non-extended colors will always be non-equal.
+    // Out of line and inline colors will always be non-equal.
     friend bool operator==(const Color& a, const Color& b);
     friend bool equalIgnoringSemanticColor(const Color& a, const Color& b);
-    friend bool extendedColorsEqual(const Color&, const Color&);
-    friend bool extendedColorsEqualIgnoringSemanticColor(const Color&, const Color&);
+    friend bool outOfLineComponentssEqual(const Color&, const Color&);
+    friend bool outOfLineComponentssEqualIgnoringSemanticColor(const Color&, const Color&);
 
-    static bool isBlackColor(const Color&);
-    static bool isWhiteColor(const Color&);
-
     template<class Encoder> void encode(Encoder&) const;
     template<class Decoder> static Optional<Color> decode(Decoder&);
 
 private:
-    Color(Ref<ExtendedColor>&&, OptionSet<Flags> = { });
+    class OutOfLineComponents : public RefCounted<OutOfLineComponents> {
+    public:
+        static Ref<OutOfLineComponents> create(ColorComponents<float> components)
+        {
+            return adoptRef(*new OutOfLineComponents(components));
+        }
 
-    enum class FlagsIncludingPrivate : uint16_t {
-        Semantic                        = static_cast<uint16_t>(Flags::Semantic),
-        UseColorFunctionSerialization   = static_cast<uint16_t>(Flags::UseColorFunctionSerialization),
+        float alpha() const { return m_components[3]; }
+        ColorComponents<float> components() const { return m_components; }
+
+    private:
+        OutOfLineComponents(ColorComponents<float> components)
+            : m_components(components)
+        {
+        }
+
+        ColorComponents<float> m_components;
+    };
+    Color(Ref<OutOfLineComponents>&&, ColorSpace, OptionSet<Flags> = { });
+
+    enum class FlagsIncludingPrivate : uint8_t {
+        Semantic                        = static_cast<uint8_t>(Flags::Semantic),
+        UseColorFunctionSerialization   = static_cast<uint8_t>(Flags::UseColorFunctionSerialization),
         Valid                           = 1 << 2,
-        Extended                        = 1 << 3,
+        OutOfLine                       = 1 << 3,
         HashTableEmptyValue             = 1 << 4,
         HashTableDeletedValue           = 1 << 5,
     };
@@ -199,13 +216,18 @@
     static OptionSet<FlagsIncludingPrivate> toFlagsIncludingPrivate(OptionSet<Flags> flags) { return OptionSet<FlagsIncludingPrivate>::fromRaw(flags.toRaw()); }
 
     OptionSet<FlagsIncludingPrivate> flags() const;
+    bool isOutOfLine() const;
+    bool isInline() const;
 
     void setColor(SRGBA<uint8_t>, OptionSet<FlagsIncludingPrivate> = { });
-    void setExtendedColor(Ref<ExtendedColor>&&, OptionSet<FlagsIncludingPrivate> = { });
+    void setOutOfLineComponents(Ref<OutOfLineComponents>&&, ColorSpace, OptionSet<FlagsIncludingPrivate> = { });
 
+    SRGBA<uint8_t> asInline() const;
     PackedColor::RGBA asPackedInline() const;
-    Ref<ExtendedColor> asExtendedRef() const;
 
+    const OutOfLineComponents& asOutOfLine() const;
+    Ref<OutOfLineComponents> asOutOfLineRef() const;
+
 #if CPU(ADDRESS64)
     static constexpr unsigned maxNumberOfBitsInPointer = 48;
 #else
@@ -212,16 +234,23 @@
     static constexpr unsigned maxNumberOfBitsInPointer = 32;
 #endif
     static constexpr uint64_t colorValueMask = (1ULL << maxNumberOfBitsInPointer) - 1;
+    static constexpr uint64_t flagsSize = sizeof(FlagsIncludingPrivate) * 8;
+    static constexpr uint64_t flagsShift = maxNumberOfBitsInPointer;
+    static constexpr uint64_t colorSpaceSize = sizeof(ColorSpace) * 8;
+    static constexpr uint64_t colorSpaceShift = flagsShift + flagsSize;
+    static_assert(flagsSize + colorSpaceSize + maxNumberOfBitsInPointer <= 64);
 
     static uint64_t encodedFlags(OptionSet<FlagsIncludingPrivate>);
+    static uint64_t encodedColorSpace(ColorSpace);
     static uint64_t encodedInlineColor(SRGBA<uint8_t>);
     static uint64_t encodedPackedInlineColor(PackedColor::RGBA);
-    static uint64_t encodedExtendedColor(Ref<ExtendedColor>&&);
+    static uint64_t encodedOutOfLineComponents(Ref<OutOfLineComponents>&&);
 
     static OptionSet<FlagsIncludingPrivate> decodedFlags(uint64_t);
+    static ColorSpace decodedColorSpace(uint64_t);
     static SRGBA<uint8_t> decodedInlineColor(uint64_t);
     static PackedColor::RGBA decodedPackedInlineColor(uint64_t);
-    static ExtendedColor& decodedExtendedColor(uint64_t);
+    static OutOfLineComponents& decodedOutOfLineComponents(uint64_t);
 
     static constexpr uint64_t invalidColorAndFlags = 0;
     uint64_t m_colorAndFlags { invalidColorAndFlags };
@@ -230,9 +259,9 @@
 bool operator==(const Color&, const Color&);
 bool operator!=(const Color&, const Color&);
 
-// One or both must be extended colors.
-bool extendedColorsEqual(const Color&, const Color&);
-bool extendedColorsEqualIgnoringSemanticColor(const Color&, const Color&);
+// One or both must be out of line colors.
+bool outOfLineComponentssEqual(const Color&, const Color&);
+bool outOfLineComponentssEqualIgnoringSemanticColor(const Color&, const Color&);
 
 #if USE(CG)
 WEBCORE_EXPORT CGColorRef cachedCGColor(const Color&);
@@ -242,8 +271,8 @@
 
 inline bool operator==(const Color& a, const Color& b)
 {
-    if (a.isExtended() || b.isExtended())
-        return extendedColorsEqual(a, b);
+    if (a.isOutOfLine() || b.isOutOfLine())
+        return outOfLineComponentssEqual(a, b);
     return a.m_colorAndFlags == b.m_colorAndFlags;
 }
 
@@ -252,31 +281,31 @@
     return !(a == b);
 }
 
-inline bool extendedColorsEqual(const Color& a, const Color& b)
+inline bool outOfLineComponentssEqual(const Color& a, const Color& b)
 {
-    if (a.isExtended() && b.isExtended())
-        return a.asExtended() == b.asExtended() && a.flags() == b.flags();
+    if (a.isOutOfLine() && b.isOutOfLine())
+        return a.asOutOfLine().components() == b.asOutOfLine().components() && a.colorSpace() == b.colorSpace() && a.flags() == b.flags();
 
-    ASSERT(a.isExtended() || b.isExtended());
+    ASSERT(a.isOutOfLine() || b.isOutOfLine());
     return false;
 }
 
-inline bool extendedColorsEqualIgnoringSemanticColor(const Color& a, const Color& b)
+inline bool outOfLineComponentssEqualIgnoringSemanticColor(const Color& a, const Color& b)
 {
-    if (a.isExtended() && b.isExtended()) {
+    if (a.isOutOfLine() && b.isOutOfLine()) {
         auto aFlags = a.flags() - Color::FlagsIncludingPrivate::Semantic;
         auto bFlags = b.flags() - Color::FlagsIncludingPrivate::Semantic;
-        return a.asExtended() == b.asExtended() && aFlags == bFlags;
+        return a.asOutOfLine().components() == b.asOutOfLine().components() && a.colorSpace() == b.colorSpace() && aFlags == bFlags;
     }
 
-    ASSERT(a.isExtended() || b.isExtended());
+    ASSERT(a.isOutOfLine() || b.isOutOfLine());
     return false;
 }
 
 inline bool equalIgnoringSemanticColor(const Color& a, const Color& b)
 {
-    if (a.isExtended() || b.isExtended())
-        return extendedColorsEqualIgnoringSemanticColor(a, b);
+    if (a.isOutOfLine() || b.isOutOfLine())
+        return outOfLineComponentssEqualIgnoringSemanticColor(a, b);
 
     auto aFlags = a.flags() - Color::FlagsIncludingPrivate::Semantic;
     auto bFlags = b.flags() - Color::FlagsIncludingPrivate::Semantic;
@@ -294,15 +323,10 @@
         setColor(*color, toFlagsIncludingPrivate(flags));
 }
 
-inline Color::Color(ColorComponents<float> components, ColorSpace colorSpace, OptionSet<Flags> flags)
-{
-    setExtendedColor(ExtendedColor::create(components, colorSpace), toFlagsIncludingPrivate(flags));
-}
-
 template<typename ColorType, typename std::enable_if_t<IsColorTypeWithComponentType<ColorType, float>>*>
 inline Color::Color(const ColorType& color, OptionSet<Flags> flags)
 {
-    setExtendedColor(ExtendedColor::create(color), toFlagsIncludingPrivate(flags));
+    setOutOfLineComponents(OutOfLineComponents::create(asColorComponents(color)), ColorSpaceFor<ColorType>, toFlagsIncludingPrivate(flags));
 }
 
 template<typename ColorType, typename std::enable_if_t<IsColorTypeWithComponentType<ColorType, float>>*>
@@ -309,12 +333,12 @@
 inline Color::Color(const Optional<ColorType>& color, OptionSet<Flags> flags)
 {
     if (color)
-        setExtendedColor(ExtendedColor::create(*color), toFlagsIncludingPrivate(flags));
+        setOutOfLineComponents(OutOfLineComponents::create(asColorComponents(*color)), ColorSpaceFor<ColorType>, toFlagsIncludingPrivate(flags));
 }
 
-inline Color::Color(Ref<ExtendedColor>&& extendedColor, OptionSet<Flags> flags)
+inline Color::Color(Ref<OutOfLineComponents>&& outOfLineComponents, ColorSpace colorSpace, OptionSet<Flags> flags)
 {
-    setExtendedColor(WTFMove(extendedColor), toFlagsIncludingPrivate(flags));
+    setOutOfLineComponents(WTFMove(outOfLineComponents), colorSpace, toFlagsIncludingPrivate(flags));
 }
 
 inline Color::Color(WTF::HashTableEmptyValueType)
@@ -334,14 +358,14 @@
 
 inline Color::~Color()
 {
-    if (isExtended())
-        asExtended().deref();
+    if (isOutOfLine())
+        asOutOfLine().deref();
 }
 
 inline unsigned Color::hash() const
 {
-    if (isExtended())
-        return computeHash(asExtended().components(), asExtended().colorSpace(), flags().toRaw());
+    if (isOutOfLine())
+        return computeHash(asOutOfLine().components(), colorSpace(), flags().toRaw());
     return computeHash(asPackedInline().value, flags().toRaw());
 }
 
@@ -360,10 +384,15 @@
     return flags().contains(FlagsIncludingPrivate::UseColorFunctionSerialization);
 }
 
+inline ColorSpace Color::colorSpace() const
+{
+    return decodedColorSpace(m_colorAndFlags);
+}
+
 template<typename Functor> decltype(auto) Color::callOnUnderlyingType(Functor&& functor) const
 {
-    if (isExtended())
-        return asExtended().callOnUnderlyingType(std::forward<Functor>(functor));
+    if (isOutOfLine())
+        return callWithColorType(asOutOfLine().components(), colorSpace(), std::forward<Functor>(functor));
     return std::invoke(std::forward<Functor>(functor), asInline());
 }
 
@@ -399,26 +428,26 @@
     return decodedFlags(m_colorAndFlags);
 }
 
-inline bool Color::isExtended() const
+inline bool Color::isOutOfLine() const
 {
-    return flags().contains(FlagsIncludingPrivate::Extended);
+    return flags().contains(FlagsIncludingPrivate::OutOfLine);
 }
 
 inline bool Color::isInline() const
 {
-    return !flags().contains(FlagsIncludingPrivate::Extended);
+    return !flags().contains(FlagsIncludingPrivate::OutOfLine);
 }
 
-inline const ExtendedColor& Color::asExtended() const
+inline const Color::OutOfLineComponents& Color::asOutOfLine() const
 {
-    ASSERT(isExtended());
-    return decodedExtendedColor(m_colorAndFlags);
+    ASSERT(isOutOfLine());
+    return decodedOutOfLineComponents(m_colorAndFlags);
 }
 
-inline Ref<ExtendedColor> Color::asExtendedRef() const
+inline Ref<Color::OutOfLineComponents> Color::asOutOfLineRef() const
 {
-    ASSERT(isExtended());
-    return decodedExtendedColor(m_colorAndFlags);
+    ASSERT(isOutOfLine());
+    return decodedOutOfLineComponents(m_colorAndFlags);
 }
 
 inline SRGBA<uint8_t> Color::asInline() const
@@ -433,11 +462,23 @@
     return decodedPackedInlineColor(m_colorAndFlags);
 }
 
+inline Optional<SRGBA<uint8_t>> Color::tryGetAsSRGBABytes() const
+{
+    if (isInline())
+        return asInline();
+    return WTF::nullopt;
+}
+
 inline uint64_t Color::encodedFlags(OptionSet<FlagsIncludingPrivate> flags)
 {
-    return static_cast<uint64_t>(flags.toRaw()) << maxNumberOfBitsInPointer;
+    return static_cast<uint64_t>(flags.toRaw()) << flagsShift;
 }
 
+inline uint64_t Color::encodedColorSpace(ColorSpace colorSpace)
+{
+    return static_cast<uint64_t>(colorSpace) << colorSpaceShift;
+}
+
 inline uint64_t Color::encodedInlineColor(SRGBA<uint8_t> color)
 {
     return encodedPackedInlineColor(PackedColor::RGBA { color });
@@ -448,20 +489,25 @@
     return color.value;
 }
 
-inline uint64_t Color::encodedExtendedColor(Ref<ExtendedColor>&& extendedColor)
+inline uint64_t Color::encodedOutOfLineComponents(Ref<OutOfLineComponents>&& outOfLineComponents)
 {
 #if CPU(ADDRESS64)
-    return bitwise_cast<uint64_t>(&extendedColor.leakRef());
+    return bitwise_cast<uint64_t>(&outOfLineComponents.leakRef());
 #else
-    return bitwise_cast<uint32_t>(&extendedColor.leakRef());
+    return bitwise_cast<uint32_t>(&outOfLineComponents.leakRef());
 #endif
 }
 
 inline OptionSet<Color::FlagsIncludingPrivate> Color::decodedFlags(uint64_t value)
 {
-    return OptionSet<Color::FlagsIncludingPrivate>::fromRaw(static_cast<unsigned>(value >> maxNumberOfBitsInPointer));
+    return OptionSet<Color::FlagsIncludingPrivate>::fromRaw(static_cast<uint8_t>(value >> flagsShift));
 }
 
+inline ColorSpace Color::decodedColorSpace(uint64_t value)
+{
+    return static_cast<ColorSpace>(static_cast<uint8_t>(value >> colorSpaceShift));
+}
+
 inline SRGBA<uint8_t> Color::decodedInlineColor(uint64_t value)
 {
     return asSRGBA(decodedPackedInlineColor(value));
@@ -472,12 +518,12 @@
     return PackedColor::RGBA { static_cast<uint32_t>(value & colorValueMask) };
 }
 
-inline ExtendedColor& Color::decodedExtendedColor(uint64_t value)
+inline Color::OutOfLineComponents& Color::decodedOutOfLineComponents(uint64_t value)
 {
 #if CPU(ADDRESS64)
-    return *bitwise_cast<ExtendedColor*>(value & colorValueMask);
+    return *bitwise_cast<OutOfLineComponents*>(value & colorValueMask);
 #else
-    return *bitwise_cast<ExtendedColor*>(static_cast<uint32_t>(value & colorValueMask));
+    return *bitwise_cast<OutOfLineComponents*>(static_cast<uint32_t>(value & colorValueMask));
 #endif
 }
 
@@ -484,15 +530,15 @@
 inline void Color::setColor(SRGBA<uint8_t> color, OptionSet<FlagsIncludingPrivate> flags)
 {
     flags.add({ FlagsIncludingPrivate::Valid });
-    m_colorAndFlags = encodedInlineColor(color) | encodedFlags(flags);
+    m_colorAndFlags = encodedInlineColor(color) | encodedColorSpace(ColorSpace::SRGB) | encodedFlags(flags);
     ASSERT(isInline());
 }
 
-inline void Color::setExtendedColor(Ref<ExtendedColor>&& color, OptionSet<FlagsIncludingPrivate> flags)
+inline void Color::setOutOfLineComponents(Ref<OutOfLineComponents>&& color, ColorSpace colorSpace, OptionSet<FlagsIncludingPrivate> flags)
 {
-    flags.add({ FlagsIncludingPrivate::Valid, FlagsIncludingPrivate::Extended });
-    m_colorAndFlags = encodedExtendedColor(WTFMove(color)) | encodedFlags(flags);
-    ASSERT(isExtended());
+    flags.add({ FlagsIncludingPrivate::Valid, FlagsIncludingPrivate::OutOfLine });
+    m_colorAndFlags = encodedOutOfLineComponents(WTFMove(color)) | encodedColorSpace(colorSpace) | encodedFlags(flags);
+    ASSERT(isOutOfLine());
 }
 
 template<class Encoder> void Color::encode(Encoder& encoder) const
@@ -505,17 +551,17 @@
 
     encoder << flags().contains(FlagsIncludingPrivate::Semantic);
     encoder << flags().contains(FlagsIncludingPrivate::UseColorFunctionSerialization);
-
-    if (isExtended()) {
+    
+    if (isOutOfLine()) {
         encoder << true;
+        encoder << colorSpace();
 
-        auto& extendedColor = asExtended();
-        auto [c1, c2, c3, alpha] = extendedColor.components();
+        auto& outOfLineComponents = asOutOfLine();
+        auto [c1, c2, c3, alpha] = outOfLineComponents.components();
         encoder << c1;
         encoder << c2;
         encoder << c3;
         encoder << alpha;
-        encoder << extendedColor.colorSpace();
         return;
     }
     encoder << false;
@@ -548,27 +594,27 @@
     if (usesColorFunctionSerialization)
         flags.add(Flags::UseColorFunctionSerialization);
 
-    bool isExtended;
-    if (!decoder.decode(isExtended))
+    bool isOutOfLine;
+    if (!decoder.decode(isOutOfLine))
         return WTF::nullopt;
 
-    if (isExtended) {
+    if (isOutOfLine) {
+        ColorSpace colorSpace;
+        if (!decoder.decode(colorSpace))
+            return WTF::nullopt;
         float c1;
-        float c2;
-        float c3;
-        float alpha;
-        ColorSpace colorSpace;
         if (!decoder.decode(c1))
             return WTF::nullopt;
+        float c2;
         if (!decoder.decode(c2))
             return WTF::nullopt;
+        float c3;
         if (!decoder.decode(c3))
             return WTF::nullopt;
+        float alpha;
         if (!decoder.decode(alpha))
             return WTF::nullopt;
-        if (!decoder.decode(colorSpace))
-            return WTF::nullopt;
-        return Color { ExtendedColor::create({ c1, c2, c3, alpha }, colorSpace), flags };
+        return Color { OutOfLineComponents::create({ c1, c2, c3, alpha }), colorSpace, flags };
     }
 
     uint32_t value;

Modified: trunk/Source/WebCore/platform/graphics/ColorSerialization.cpp (273775 => 273776)


--- trunk/Source/WebCore/platform/graphics/ColorSerialization.cpp	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Source/WebCore/platform/graphics/ColorSerialization.cpp	2021-03-03 01:25:52 UTC (rev 273776)
@@ -27,7 +27,6 @@
 #include "ColorSerialization.h"
 
 #include "Color.h"
-#include "ExtendedColor.h"
 #include <wtf/Assertions.h>
 #include <wtf/HexNumber.h>
 #include <wtf/MathExtras.h>

Deleted: trunk/Source/WebCore/platform/graphics/ExtendedColor.h (273775 => 273776)


--- trunk/Source/WebCore/platform/graphics/ExtendedColor.h	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Source/WebCore/platform/graphics/ExtendedColor.h	2021-03-03 01:25:52 UTC (rev 273776)
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include "ColorComponents.h"
-#include "ColorConversion.h"
-#include "ColorSpace.h"
-#include "ColorTypes.h"
-#include <functional>
-#include <wtf/Ref.h>
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class ExtendedColor : public RefCounted<ExtendedColor> {
-public:
-    template<typename ColorType> static Ref<ExtendedColor> create(const ColorType&);
-    static Ref<ExtendedColor> create(ColorComponents<float>, ColorSpace);
-    
-    float alpha() const { return m_components[3]; }
-
-    const ColorComponents<float>& components() const { return m_components; }
-    ColorSpace colorSpace() const { return m_colorSpace; }
-
-    template<typename Functor> decltype(auto) callOnUnderlyingType(Functor&&) const;
-
-private:
-    ExtendedColor(ColorComponents<float>, ColorSpace);
-
-    ColorComponents<float> m_components;
-    ColorSpace m_colorSpace;
-};
-
-inline bool operator==(const ExtendedColor& a, const ExtendedColor& b)
-{
-    return a.colorSpace() == b.colorSpace() && a.components() == b.components();
-}
-
-inline bool operator!=(const ExtendedColor& a, const ExtendedColor& b)
-{
-    return !(a == b);
-}
-
-template<typename ColorType> inline Ref<ExtendedColor> ExtendedColor::create(const ColorType& color)
-{
-    return adoptRef(*new ExtendedColor(asColorComponents(color), ColorSpaceFor<ColorType>));
-}
-
-inline Ref<ExtendedColor> ExtendedColor::create(ColorComponents<float> components, ColorSpace colorSpace)
-{
-    return adoptRef(*new ExtendedColor(components, colorSpace));
-}
-
-inline ExtendedColor::ExtendedColor(ColorComponents<float> components, ColorSpace colorSpace)
-    : m_components(components)
-    , m_colorSpace(colorSpace)
-{
-}
-
-template<typename Functor> decltype(auto) ExtendedColor::callOnUnderlyingType(Functor&& functor) const
-{
-    return callWithColorType(m_components, m_colorSpace, std::forward<Functor>(functor));
-}
-
-}

Modified: trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp (273775 => 273776)


--- trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp	2021-03-03 01:25:52 UTC (rev 273776)
@@ -84,11 +84,6 @@
     return convertColor<SRGBA<uint8_t>>(SRGBA<float> { r, g, b, a });
 }
 
-Color::Color(CGColorRef color)
-    : Color(roundAndClampToSRGBALossy(color))
-{
-}
-
 Color::Color(CGColorRef color, OptionSet<Flags> flags)
     : Color(roundAndClampToSRGBALossy(color), flags)
 {
@@ -128,8 +123,8 @@
 
 CGColorRef cachedCGColor(const Color& color)
 {
-    if (color.isInline()) {
-        switch (PackedColor::RGBA { color.asInline() }.value) {
+    if (auto srgb = color.tryGetAsSRGBABytes()) {
+        switch (PackedColor::RGBA { *srgb }.value) {
         case PackedColor::RGBA { Color::transparentBlack }.value: {
             static CGColorRef transparentCGColor = leakCGColor(color);
             return transparentCGColor;

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


--- trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp	2021-03-03 01:25:52 UTC (rev 273776)
@@ -54,18 +54,16 @@
     Vector<CGFloat, 4 * reservedStops> colorComponents;
     colorComponents.reserveInitialCapacity(numStops * 4);
 
-    bool hasExtendedColors = false;
+    // FIXME: Consider making this into two loops to avoid unnecessary allocation of the
+    // CGColorRefs in the common case of all ColorSpace::SRGB.
+
+    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;
 
-        // If all the stops are sRGB, it is faster to create a gradient using
-        // components than CGColors.
-        // FIXME: Rather than just check for extended colors, we should check the actual
-        // color space, and whether or not the components are outside [0-1].
-        // <rdar://problem/32926606>
-
-        if (stop.color.isExtended())
-            hasExtendedColors = true;
-
         auto [colorSpace, components] = stop.color.colorSpaceAndComponents();
         auto [r, g, b, a] = components;
         colorComponents.uncheckedAppend(r);
@@ -83,10 +81,10 @@
     auto extendedColorsGradientColorSpace = sRGBColorSpaceRef();
 #endif
 
-    if (hasExtendedColors)
+    if (hasOnlyBoundedSRGBColorStops)
+        m_gradient = adoptCF(CGGradientCreateWithColorComponents(sRGBColorSpaceRef(), colorComponents.data(), locations.data(), numStops));
+    else
         m_gradient = adoptCF(CGGradientCreateWithColors(extendedColorsGradientColorSpace, colorsArray.get(), locations.data()));
-    else
-        m_gradient = adoptCF(CGGradientCreateWithColorComponents(sRGBColorSpaceRef(), colorComponents.data(), locations.data(), numStops));
 }
 
 void Gradient::fill(GraphicsContext& context, const FloatRect& rect)

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp (273775 => 273776)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp	2021-03-03 01:25:52 UTC (rev 273776)
@@ -124,7 +124,7 @@
     RELEASE_ASSERT(m_colorStopCount <= maxColorStopCount);
     for (uint8_t i = 0; i < m_colorStopCount; ++i) {
         m_offsets[i] = gradient.stops()[i].offset;
-        m_colors[i] = gradient.stops()[i].color.asInline();
+        m_colors[i] = *gradient.stops()[i].color.tryGetAsSRGBABytes();
     }
 }
 
@@ -162,7 +162,7 @@
         return false;
 
     for (auto& colorStop : gradient.stops()) {
-        if (!colorStop.color.isInline())
+        if (!colorStop.color.tryGetAsSRGBABytes())
             return false;
     }
 

Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp (273775 => 273776)


--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp	2021-03-03 01:25:52 UTC (rev 273776)
@@ -72,10 +72,10 @@
     if (changeFlags != (changeFlags & inlineStateChangeFlags))
         return false;
 
-    if (changeFlags.contains(GraphicsContextState::StrokeColorChange) && !changes.m_state.strokeColor.isInline())
+    if (changeFlags.contains(GraphicsContextState::StrokeColorChange) && !changes.m_state.strokeColor.tryGetAsSRGBABytes())
         return false;
 
-    if (changeFlags.contains(GraphicsContextState::FillColorChange) && !changes.m_state.fillColor.isInline())
+    if (changeFlags.contains(GraphicsContextState::FillColorChange) && !changes.m_state.fillColor.tryGetAsSRGBABytes())
         return false;
 
     if (changeFlags.contains(GraphicsContextState::FillGradientChange)
@@ -104,13 +104,13 @@
     }
 
     if (changeFlags.contains(GraphicsContextState::StrokeColorChange))
-        append<SetInlineStrokeColor>(changes.m_state.strokeColor.asInline());
+        append<SetInlineStrokeColor>(*changes.m_state.strokeColor.tryGetAsSRGBABytes());
 
     if (changeFlags.contains(GraphicsContextState::StrokeThicknessChange))
         append<SetStrokeThickness>(changes.m_state.strokeThickness);
 
     if (changeFlags.contains(GraphicsContextState::FillColorChange))
-        append<SetInlineFillColor>(changes.m_state.fillColor.asInline());
+        append<SetInlineFillColor>(*changes.m_state.fillColor.tryGetAsSRGBABytes());
 
     if (changeFlags.contains(GraphicsContextState::FillGradientChange))
         append<SetInlineFillGradient>(*changes.m_state.fillGradient, changes.m_state.fillGradientSpaceTransform);

Modified: trunk/Source/WebCore/platform/graphics/mac/ColorMac.mm (273775 => 273776)


--- trunk/Source/WebCore/platform/graphics/mac/ColorMac.mm	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Source/WebCore/platform/graphics/mac/ColorMac.mm	2021-03-03 01:25:52 UTC (rev 273776)
@@ -113,8 +113,8 @@
 
 NSColor *nsColor(const Color& color)
 {
-    if (color.isInline()) {
-        switch (PackedColor::RGBA { color.asInline() }.value) {
+    if (auto srgb = color.tryGetAsSRGBABytes()) {
+        switch (PackedColor::RGBA { *srgb }.value) {
         case PackedColor::RGBA { Color::transparentBlack }.value: {
             static NeverDestroyed<RetainPtr<NSColor>> clearColor = [NSColor colorWithSRGBRed:0 green:0 blue:0 alpha:0];
             return clearColor.get().get();

Modified: trunk/Tools/ChangeLog (273775 => 273776)


--- trunk/Tools/ChangeLog	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Tools/ChangeLog	2021-03-03 01:25:52 UTC (rev 273776)
@@ -1,3 +1,21 @@
+2021-03-02  Sam Weinig  <[email protected]>
+
+        Reduce the size of extended colors by storing the color space in free bits of the owning Color
+        https://bugs.webkit.org/show_bug.cgi?id=222584
+
+        Reviewed by Darin Adler.
+
+        * TestWebKitAPI/CMakeLists.txt:
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/ColorTests.cpp:
+        (TestWebKitAPI::TEST):
+        (TestWebKitAPI::makeColor):
+        * TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp:
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp: Removed.
+        Update tests to account for removal of the ExtendedColor class.
+        Merge ExtendedColorTests.cpp that still make sense into ColorTests.cpp
+
 2021-03-02  Jonathan Bedard  <[email protected]>
 
         [git-webkit] Better logging when attempting to convert tag to identifier

Modified: trunk/Tools/TestWebKitAPI/CMakeLists.txt (273775 => 273776)


--- trunk/Tools/TestWebKitAPI/CMakeLists.txt	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Tools/TestWebKitAPI/CMakeLists.txt	2021-03-03 01:25:52 UTC (rev 273776)
@@ -170,7 +170,6 @@
         Tests/WebCore/ColorTests.cpp
         Tests/WebCore/ComplexTextController.cpp
         Tests/WebCore/ContextMenuAction.cpp
-        Tests/WebCore/ExtendedColorTests.cpp
         Tests/WebCore/FileMonitor.cpp
         Tests/WebCore/FloatPointTests.cpp
         Tests/WebCore/FloatRectTests.cpp

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (273775 => 273776)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-03-03 01:25:52 UTC (rev 273776)
@@ -197,7 +197,6 @@
 		3128A81323763FAC00D90D40 /* link-with-image.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 3128A81223763F0B00D90D40 /* link-with-image.html */; };
 		3128A8152376413300D90D40 /* image.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 3128A814237640FD00D90D40 /* image.html */; };
 		313C3A0221E567C300DBA86E /* SystemPreviewBlobNaming.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 313C3A0121E5677A00DBA86E /* SystemPreviewBlobNaming.html */; };
-		315118101DB1AE4000176304 /* ExtendedColorTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3151180F1DB1ADD500176304 /* ExtendedColorTests.cpp */; };
 		31B76E4323298E2C007FED2C /* SystemPreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = 31B76E4223298E2B007FED2C /* SystemPreview.mm */; };
 		31B76E4523299BDC007FED2C /* system-preview-trigger.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 31B76E4423299BA3007FED2C /* system-preview-trigger.html */; };
 		31E9BDA1247F4C62002E51A2 /* WebGLPrepareDisplayOnWebThread.mm in Sources */ = {isa = PBXBuildFile; fileRef = 31E9BDA0247F4C62002E51A2 /* WebGLPrepareDisplayOnWebThread.mm */; };
@@ -1932,7 +1931,6 @@
 		3128A81223763F0B00D90D40 /* link-with-image.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "link-with-image.html"; sourceTree = "<group>"; };
 		3128A814237640FD00D90D40 /* image.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = image.html; sourceTree = "<group>"; };
 		313C3A0121E5677A00DBA86E /* SystemPreviewBlobNaming.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = SystemPreviewBlobNaming.html; sourceTree = "<group>"; };
-		3151180F1DB1ADD500176304 /* ExtendedColorTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExtendedColorTests.cpp; sourceTree = "<group>"; };
 		31B76E4223298E2B007FED2C /* SystemPreview.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SystemPreview.mm; sourceTree = "<group>"; };
 		31B76E4423299BA3007FED2C /* system-preview-trigger.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "system-preview-trigger.html"; sourceTree = "<group>"; };
 		31E9BDA0247F4C62002E51A2 /* WebGLPrepareDisplayOnWebThread.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WebGLPrepareDisplayOnWebThread.mm; sourceTree = "<group>"; };
@@ -3585,7 +3583,6 @@
 				26F6E1EF1ADC749B00DE696B /* DFAMinimizer.cpp */,
 				F4094CC625545BD5003D73E3 /* DisplayListTests.cpp */,
 				93915A1624DB66C70019FF43 /* DocumentOrder.cpp */,
-				3151180F1DB1ADD500176304 /* ExtendedColorTests.cpp */,
 				579651E6216BFD53006EBFE5 /* FidoHidMessageTest.cpp */,
 				572B40352176A029000AD43E /* FidoTestData.h */,
 				7A32D7491F02151500162C44 /* FileMonitor.cpp */,
@@ -5291,7 +5288,6 @@
 				5C7964101EB0278D0075D74C /* EventModifiers.cpp in Sources */,
 				CDA29B2920FD2A9900F15CED /* ExitFullscreenOnEnterPiP.mm in Sources */,
 				1D12BEC0245BEF85004C0B7A /* ExitPiPOnSuspendVideoElement.mm in Sources */,
-				315118101DB1AE4000176304 /* ExtendedColorTests.cpp in Sources */,
 				7CCE7EF11A411AE600447C4C /* FailedLoad.cpp in Sources */,
 				579651E7216BFDED006EBFE5 /* FidoHidMessageTest.cpp in Sources */,
 				7A32D74A1F02151500162C44 /* FileMonitor.cpp in Sources */,

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/ColorTests.cpp (273775 => 273776)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ColorTests.cpp	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ColorTests.cpp	2021-03-03 01:25:52 UTC (rev 273776)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,9 +26,12 @@
 #include "config.h"
 
 #include "Test.h"
+#include "WTFStringUtilities.h"
 #include <WebCore/Color.h>
 #include <WebCore/ColorConversion.h>
+#include <WebCore/ColorSerialization.h>
 #include <WebCore/ColorTypes.h>
+#include <wtf/MathExtras.h>
 
 using namespace WebCore;
 
@@ -166,23 +169,18 @@
 {
     Color invalidColor;
     EXPECT_FALSE(invalidColor.isValid());
-    EXPECT_FALSE(invalidColor.isExtended());
 
     Color otherInvalidColor = invalidColor;
     EXPECT_FALSE(otherInvalidColor.isValid());
-    EXPECT_FALSE(otherInvalidColor.isExtended());
 
     Color validColor = Color::red;
     EXPECT_TRUE(validColor.isValid());
-    EXPECT_FALSE(validColor.isExtended());
 
     Color otherValidColor = validColor;
     EXPECT_TRUE(otherValidColor.isValid());
-    EXPECT_FALSE(otherValidColor.isExtended());
 
     validColor = SRGBA<uint8_t> { 1, 2, 3, 4 };
     EXPECT_TRUE(validColor.isValid());
-    EXPECT_FALSE(validColor.isExtended());
     auto validColorComponents = validColor.toSRGBALossy<uint8_t>();
     EXPECT_EQ(validColorComponents.red, 1);
     EXPECT_EQ(validColorComponents.green, 2);
@@ -191,7 +189,6 @@
 
     Color yetAnotherValidColor(WTFMove(validColor));
     EXPECT_TRUE(yetAnotherValidColor.isValid());
-    EXPECT_FALSE(yetAnotherValidColor.isExtended());
     auto yetAnotherValidColorComponents = yetAnotherValidColor.toSRGBALossy<uint8_t>();
     EXPECT_EQ(yetAnotherValidColorComponents.red, 1);
     EXPECT_EQ(yetAnotherValidColorComponents.green, 2);
@@ -200,7 +197,6 @@
 
     otherValidColor = WTFMove(yetAnotherValidColor);
     EXPECT_TRUE(otherValidColor.isValid());
-    EXPECT_FALSE(otherValidColor.isExtended());
     auto otherValidColorComponents = otherValidColor.toSRGBALossy<uint8_t>();
     EXPECT_EQ(otherValidColorComponents.red, 1);
     EXPECT_EQ(otherValidColorComponents.green, 2);
@@ -233,4 +229,194 @@
     EXPECT_EQ(cDarkened.blue, 76);
 }
 
+TEST(Color, Constructor)
+{
+    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
+
+    auto [colorSpace, components] = c1.colorSpaceAndComponents();
+    auto [r, g, b, alpha] = components;
+
+    EXPECT_FLOAT_EQ(1.0, r);
+    EXPECT_FLOAT_EQ(0.5, g);
+    EXPECT_FLOAT_EQ(0.25, b);
+    EXPECT_FLOAT_EQ(1.0, alpha);
+    EXPECT_EQ(serializationForCSS(c1), "color(display-p3 1 0.5 0.25)");
+}
+
+TEST(Color, CopyConstructor)
+{
+    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
+    Color c2(c1);
+
+    auto [colorSpace, components] = c2.colorSpaceAndComponents();
+    auto [r, g, b, alpha] = components;
+
+    EXPECT_FLOAT_EQ(1.0, r);
+    EXPECT_FLOAT_EQ(0.5, g);
+    EXPECT_FLOAT_EQ(0.25, b);
+    EXPECT_FLOAT_EQ(1.0, alpha);
+    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
+}
+
+TEST(Color, Assignment)
+{
+    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
+    Color c2 = c1;
+
+    auto [colorSpace, components] = c2.colorSpaceAndComponents();
+    auto [r, g, b, alpha] = components;
+
+    EXPECT_FLOAT_EQ(1.0, r);
+    EXPECT_FLOAT_EQ(0.5, g);
+    EXPECT_FLOAT_EQ(0.25, b);
+    EXPECT_FLOAT_EQ(1.0, alpha);
+    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
+}
+
+TEST(Color, Equality)
+{
+    {
+        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
+        Color c2 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
+        EXPECT_EQ(c1, c2);
+    }
+
+    {
+        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
+        Color c2 { SRGBA<float> { 1.0, 0.5, 0.25, 1.0 } };
+        EXPECT_NE(c1, c2);
+    }
+
+    auto componentBytes = SRGBA<uint8_t> { 255, 128, 63, 127 };
+    Color rgb1 { convertColor<SRGBA<float>>(componentBytes) };
+    Color rgb2 { componentBytes };
+    EXPECT_NE(rgb1, rgb2);
+    EXPECT_NE(rgb2, rgb1);
+}
+
+TEST(Color, Hash)
+{
+    {
+        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
+        Color c2 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
+        EXPECT_EQ(c1.hash(), c2.hash());
+    }
+
+    {
+        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
+        Color c2 { SRGBA<float> { 1.0, 0.5, 0.25, 1.0 } };
+        EXPECT_NE(c1.hash(), c2.hash());
+    }
+
+    auto componentBytes = SRGBA<uint8_t> { 255, 128, 63, 127 };
+    Color rgb1 { convertColor<SRGBA<float>>(componentBytes) };
+    Color rgb2 { componentBytes };
+    EXPECT_NE(rgb1.hash(), rgb2.hash());
+}
+
+TEST(Color, MoveConstructor)
+{
+    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
+    Color c2(WTFMove(c1));
+
+    // We should have moved the out of line color pointer into c2,
+    // and set c1 to invalid so that it doesn't cause deletion.
+    EXPECT_FALSE(c1.isValid());
+
+    auto [colorSpace, components] = c2.colorSpaceAndComponents();
+    EXPECT_EQ(colorSpace, ColorSpace::DisplayP3);
+
+    auto [r, g, b, alpha] = components;
+
+    EXPECT_FLOAT_EQ(1.0, r);
+    EXPECT_FLOAT_EQ(0.5, g);
+    EXPECT_FLOAT_EQ(0.25, b);
+    EXPECT_FLOAT_EQ(1.0, alpha);
+    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
+}
+
+TEST(Color, MoveAssignment)
+{
+    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
+    Color c2 = WTFMove(c1);
+
+    // We should have moved the out of line color pointer into c2,
+    // and set c1 to invalid so that it doesn't cause deletion.
+    EXPECT_FALSE(c1.isValid());
+
+    auto [colorSpace, components] = c2.colorSpaceAndComponents();
+    EXPECT_EQ(colorSpace, ColorSpace::DisplayP3);
+
+    auto [r, g, b, alpha] = components;
+
+    EXPECT_FLOAT_EQ(1.0, r);
+    EXPECT_FLOAT_EQ(0.5, g);
+    EXPECT_FLOAT_EQ(0.25, b);
+    EXPECT_FLOAT_EQ(1.0, alpha);
+    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
+}
+
+Color makeColor()
+{
+    return Color { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
+}
+
+TEST(Color, ReturnValues)
+{
+    Color c2 = makeColor();
+    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
+}
+
+TEST(Color, P3ConversionToSRGB)
+{
+    Color p3Color { DisplayP3<float> { 1.0, 0.5, 0.25, 0.75 } };
+    auto sRGBAColor = p3Color.toSRGBALossy<float>();
+    EXPECT_FLOAT_EQ(sRGBAColor.red, 1.0f);
+    EXPECT_FLOAT_EQ(sRGBAColor.green, 0.46253282f);
+    EXPECT_FLOAT_EQ(sRGBAColor.blue, 0.14912748f);
+    EXPECT_FLOAT_EQ(sRGBAColor.alpha, 0.75f);
+}
+
+TEST(Color, LinearSRGBConversionToSRGB)
+{
+    Color linearSRGBAColor { LinearSRGBA<float> { 1.0, 0.5, 0.25, 0.75 } };
+    auto sRGBAColor = linearSRGBAColor.toSRGBALossy<float>();
+    EXPECT_FLOAT_EQ(sRGBAColor.red, 1.0f);
+    EXPECT_FLOAT_EQ(sRGBAColor.green, 0.735356927f);
+    EXPECT_FLOAT_EQ(sRGBAColor.blue, 0.537098706f);
+    EXPECT_FLOAT_EQ(sRGBAColor.alpha, 0.75f);
+}
+
+TEST(Color, ColorWithAlphaMultipliedBy)
+{
+    Color color { SRGBA<float> { 0., 0., 1., 0.6 } };
+
+    {
+        Color colorWithAlphaMultipliedBy = color.colorWithAlphaMultipliedBy(1.);
+        EXPECT_EQ(color, colorWithAlphaMultipliedBy);
+    }
+
+    {
+        Color colorWithAlphaMultipliedBy = color.colorWithAlphaMultipliedBy(0.5);
+        auto [colorSpace, components] = colorWithAlphaMultipliedBy.colorSpaceAndComponents();
+        EXPECT_EQ(colorSpace, ColorSpace::SRGB);
+        auto [r, g, b, a] = components;
+        EXPECT_FLOAT_EQ(r, 0.);
+        EXPECT_FLOAT_EQ(g, 0.);
+        EXPECT_FLOAT_EQ(b, 1.);
+        EXPECT_FLOAT_EQ(a, 0.3);
+    }
+
+    {
+        Color colorWithAlphaMultipliedBy = color.colorWithAlphaMultipliedBy(0.);
+        auto [colorSpace, components] = colorWithAlphaMultipliedBy.colorSpaceAndComponents();
+        EXPECT_EQ(colorSpace, ColorSpace::SRGB);
+        auto [r, g, b, a] = components;
+        EXPECT_FLOAT_EQ(r, 0.);
+        EXPECT_FLOAT_EQ(g, 0.);
+        EXPECT_FLOAT_EQ(b, 1.);
+        EXPECT_FLOAT_EQ(a, 0.);
+    }
+}
+
 } // namespace TestWebKitAPI

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp (273775 => 273776)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp	2021-03-03 01:25:52 UTC (rev 273776)
@@ -152,7 +152,7 @@
         EXPECT_TRUE(handle->is<FillRectWithColor>());
 
         auto& item = handle->get<FillRectWithColor>();
-        EXPECT_EQ(item.color().asInline(), Color::black);
+        EXPECT_EQ(*item.color().tryGetAsSRGBABytes(), Color::black);
         EXPECT_EQ(item.rect(), FloatRect(0, 0, 100, 100));
     }
 

Deleted: trunk/Tools/TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp (273775 => 273776)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp	2021-03-03 01:12:53 UTC (rev 273775)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp	2021-03-03 01:25:52 UTC (rev 273776)
@@ -1,290 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "Test.h"
-#include "WTFStringUtilities.h"
-#include <WebCore/Color.h>
-#include <WebCore/ColorSerialization.h>
-#include <wtf/MathExtras.h>
-
-using namespace WebCore;
-
-namespace TestWebKitAPI {
-
-TEST(ExtendedColor, Constructor)
-{
-    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
-    EXPECT_TRUE(c1.isExtended());
-
-    auto [r, g, b, alpha] = c1.asExtended().components();
-
-    EXPECT_FLOAT_EQ(1.0, r);
-    EXPECT_FLOAT_EQ(0.5, g);
-    EXPECT_FLOAT_EQ(0.25, b);
-    EXPECT_FLOAT_EQ(1.0, alpha);
-    EXPECT_EQ(1u, c1.asExtended().refCount());
-    EXPECT_EQ(serializationForCSS(c1), "color(display-p3 1 0.5 0.25)");
-}
-
-TEST(ExtendedColor, CopyConstructor)
-{
-    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
-    EXPECT_TRUE(c1.isExtended());
-
-    Color c2(c1);
-
-    auto [r, g, b, alpha] = c2.asExtended().components();
-
-    EXPECT_FLOAT_EQ(1.0, r);
-    EXPECT_FLOAT_EQ(0.5, g);
-    EXPECT_FLOAT_EQ(0.25, b);
-    EXPECT_FLOAT_EQ(1.0, alpha);
-    EXPECT_EQ(2u, c1.asExtended().refCount());
-    EXPECT_EQ(2u, c2.asExtended().refCount());
-    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
-}
-
-TEST(ExtendedColor, Assignment)
-{
-    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
-    EXPECT_TRUE(c1.isExtended());
-
-    Color c2 = c1;
-
-    auto [r, g, b, alpha] = c2.asExtended().components();
-
-    EXPECT_FLOAT_EQ(1.0, r);
-    EXPECT_FLOAT_EQ(0.5, g);
-    EXPECT_FLOAT_EQ(0.25, b);
-    EXPECT_FLOAT_EQ(1.0, alpha);
-    EXPECT_EQ(2u, c1.asExtended().refCount());
-    EXPECT_EQ(2u, c2.asExtended().refCount());
-    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
-}
-
-TEST(ExtendedColor, Equality)
-{
-    {
-        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
-        EXPECT_TRUE(c1.isExtended());
-
-        Color c2 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
-        EXPECT_TRUE(c1.isExtended());
-
-        EXPECT_EQ(c1, c2);
-    }
-
-    {
-        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
-        EXPECT_TRUE(c1.isExtended());
-
-        Color c2 { SRGBA<float> { 1.0, 0.5, 0.25, 1.0 } };
-        EXPECT_TRUE(c1.isExtended());
-
-        EXPECT_NE(c1, c2);
-    }
-
-    auto componentBytes = SRGBA<uint8_t> { 255, 128, 63, 127 };
-    Color rgb1 { convertColor<SRGBA<float>>(componentBytes) };
-    Color rgb2 { componentBytes };
-    EXPECT_NE(rgb1, rgb2);
-    EXPECT_NE(rgb2, rgb1);
-}
-
-TEST(ExtendedColor, Hash)
-{
-    {
-        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
-        EXPECT_TRUE(c1.isExtended());
-
-        Color c2 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
-        EXPECT_TRUE(c1.isExtended());
-
-        EXPECT_EQ(c1.hash(), c2.hash());
-    }
-
-    {
-        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
-        EXPECT_TRUE(c1.isExtended());
-
-        Color c2 { SRGBA<float> { 1.0, 0.5, 0.25, 1.0 } };
-        EXPECT_TRUE(c1.isExtended());
-
-        EXPECT_NE(c1.hash(), c2.hash());
-    }
-
-    auto componentBytes = SRGBA<uint8_t> { 255, 128, 63, 127 };
-    Color rgb1 { convertColor<SRGBA<float>>(componentBytes) };
-    Color rgb2 { componentBytes };
-    EXPECT_NE(rgb1.hash(), rgb2.hash());
-}
-
-TEST(ExtendedColor, MoveConstructor)
-{
-    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
-    EXPECT_TRUE(c1.isExtended());
-
-    Color c2(WTFMove(c1));
-    // We should have moved the extended color pointer into c2,
-    // and set c1 to invalid so that it doesn't cause deletion.
-    EXPECT_FALSE(c1.isExtended());
-    EXPECT_FALSE(c1.isValid());
-
-    auto [r, g, b, alpha] = c2.asExtended().components();
-
-    EXPECT_FLOAT_EQ(1.0, r);
-    EXPECT_FLOAT_EQ(0.5, g);
-    EXPECT_FLOAT_EQ(0.25, b);
-    EXPECT_FLOAT_EQ(1.0, alpha);
-    EXPECT_EQ(1u, c2.asExtended().refCount());
-    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
-}
-
-TEST(ExtendedColor, MoveAssignment)
-{
-    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
-    EXPECT_TRUE(c1.isExtended());
-
-    Color c2 = WTFMove(c1);
-
-    // We should have moved the extended color pointer into c2,
-    // and set c1 to invalid so that it doesn't cause deletion.
-    EXPECT_FALSE(c1.isExtended());
-    EXPECT_FALSE(c1.isValid());
-
-    auto [r, g, b, alpha] = c2.asExtended().components();
-
-    EXPECT_FLOAT_EQ(1.0, r);
-    EXPECT_FLOAT_EQ(0.5, g);
-    EXPECT_FLOAT_EQ(0.25, b);
-    EXPECT_FLOAT_EQ(1.0, alpha);
-    EXPECT_EQ(1u, c2.asExtended().refCount());
-    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
-}
-
-TEST(ExtendedColor, BasicReferenceCounting)
-{
-    Color* c1 = new Color { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
-    
-    EXPECT_TRUE(c1->isExtended());
-
-    Color* c2 = new Color(*c1);
-    Color* c3 = new Color(*c2);
-
-    auto [r, g, b, alpha] = c2->asExtended().components();
-
-    EXPECT_FLOAT_EQ(1.0, r);
-    EXPECT_FLOAT_EQ(0.5, g);
-    EXPECT_FLOAT_EQ(0.25, b);
-    EXPECT_FLOAT_EQ(1.0, alpha);
-    EXPECT_EQ(3u, c2->asExtended().refCount());
-    EXPECT_EQ(serializationForCSS(*c2), "color(display-p3 1 0.5 0.25)");
-
-    delete c1;
-    EXPECT_EQ(2u, c2->asExtended().refCount());
-
-    delete c2;
-    EXPECT_EQ(1u, c3->asExtended().refCount());
-
-    delete c3;
-}
-
-Color makeColor()
-{
-    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
-    EXPECT_TRUE(c1.isExtended());
-    EXPECT_EQ(1u, c1.asExtended().refCount());
-
-    return c1;
-}
-
-TEST(ExtendedColor, ReturnValues)
-{
-    Color c2 = makeColor();
-    EXPECT_TRUE(c2.isExtended());
-
-    EXPECT_EQ(1u, c2.asExtended().refCount());
-    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
-}
-
-TEST(ExtendedColor, P3ConversionToSRGB)
-{
-    Color p3Color { DisplayP3<float> { 1.0, 0.5, 0.25, 0.75 } };
-    EXPECT_TRUE(p3Color.isExtended());
-
-    auto sRGBAColor = p3Color.toSRGBALossy<float>();
-    EXPECT_FLOAT_EQ(sRGBAColor.red, 1.0f);
-    EXPECT_FLOAT_EQ(sRGBAColor.green, 0.46253282f);
-    EXPECT_FLOAT_EQ(sRGBAColor.blue, 0.14912748f);
-    EXPECT_FLOAT_EQ(sRGBAColor.alpha, 0.75f);
-}
-
-TEST(ExtendedColor, LinearSRGBConversionToSRGB)
-{
-    Color linearSRGBAColor { LinearSRGBA<float> { 1.0, 0.5, 0.25, 0.75 } };
-    EXPECT_TRUE(linearSRGBAColor.isExtended());
-
-    auto sRGBAColor = linearSRGBAColor.toSRGBALossy<float>();
-    EXPECT_FLOAT_EQ(sRGBAColor.red, 1.0f);
-    EXPECT_FLOAT_EQ(sRGBAColor.green, 0.735356927f);
-    EXPECT_FLOAT_EQ(sRGBAColor.blue, 0.537098706f);
-    EXPECT_FLOAT_EQ(sRGBAColor.alpha, 0.75f);
-}
-
-TEST(ExtendedColor, ColorWithAlphaMultipliedBy)
-{
-    Color color { SRGBA<float> { 0., 0., 1., 0.6 } };
-    EXPECT_TRUE(color.isExtended());
-
-    {
-        Color colorWithAlphaMultipliedBy = color.colorWithAlphaMultipliedBy(1.);
-        EXPECT_TRUE(colorWithAlphaMultipliedBy.isExtended());
-        EXPECT_EQ(color, colorWithAlphaMultipliedBy);
-    }
-
-    {
-        Color colorWithAlphaMultipliedBy = color.colorWithAlphaMultipliedBy(0.5);
-        EXPECT_TRUE(colorWithAlphaMultipliedBy.isExtended());
-        auto [r, g, b, a] = colorWithAlphaMultipliedBy.asExtended().components();
-        EXPECT_FLOAT_EQ(r, 0.);
-        EXPECT_FLOAT_EQ(g, 0.);
-        EXPECT_FLOAT_EQ(b, 1.);
-        EXPECT_FLOAT_EQ(a, 0.3);
-    }
-
-    {
-        Color colorWithAlphaMultipliedBy = color.colorWithAlphaMultipliedBy(0.);
-        EXPECT_TRUE(colorWithAlphaMultipliedBy.isExtended());
-        auto [r, g, b, a] = colorWithAlphaMultipliedBy.asExtended().components();
-        EXPECT_FLOAT_EQ(r, 0.);
-        EXPECT_FLOAT_EQ(g, 0.);
-        EXPECT_FLOAT_EQ(b, 1.);
-        EXPECT_FLOAT_EQ(a, 0.);
-    }
-}
-
-} // namespace TestWebKitAPI
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to