⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 273776 in webkit


Ignore:
Timestamp:
Mar 2, 2021, 5:25:52 PM (6 years ago)
Author:
weinig@apple.com
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

Location:
trunk
Files:
2 deleted
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r273773 r273776  
     12021-03-02  Sam Weinig  <weinig@apple.com>
     2
     3        Reduce the size of extended colors by storing the color space in free bits of the owning Color
     4        https://bugs.webkit.org/show_bug.cgi?id=222584
     5
     6        Reviewed by Darin Adler.
     7
     8        Reduce the size of non-SRBGA<uint8_t> colors by moving the color space from the ref counted
     9        out-of-line bit into the free bits of the Color itself.
     10       
     11        Also, take the opertunity to move and rename the out of line bit from it's own file named
     12        ExtendedColor to a private nested type called OutOfLineComponents.
     13
     14        Color now encodes the following data:
     15            |   8 bits   |   8 bits   |          48 (or 32) bits          |
     16            | ColorSpace |    Flags   |   InlineColorDataOrOutOfLinePtr   |
     17
     18        ColorSpace actually only uses 4 bits, so if we need more room for flags
     19        in the future, we could pack things even more tightly.
     20
     21        Additionally, take the opportunity to remove the isInline/isExtended and
     22        asInline/asExtended functions. The functionality of isInline/asInline
     23        is still necessary in some places, but can be replaced by a single
     24        tryGetAsSRGBABytes which returns an Optional<SRGBA<uint8_t>> with a
     25        valid value when the stored value is inline.
     26
     27        Since ExtendedColor is no longer accessible, a few tests that checked things like
     28        the ref count of the ExtendedColor had to be changed.
     29
     30        * Headers.cmake:
     31        * WebCore.xcodeproj/project.pbxproj:
     32        * platform/graphics/Color.cpp:
     33        (WebCore::Color::Color):
     34        (WebCore::Color::operator=):
     35        (WebCore::Color::semanticColor const):
     36        (WebCore::Color::colorSpaceAndComponents const):
     37        * platform/graphics/Color.h:
     38        (WebCore::Color::Color):
     39        (WebCore::Color::isOpaque const):
     40        (WebCore::Color::isVisible const):
     41        (WebCore::Color::alphaByte const):
     42        (WebCore::Color::alphaAsFloat const):
     43        (WebCore::Color::OutOfLineComponents::create):
     44        (WebCore::Color::OutOfLineComponents::alpha const):
     45        (WebCore::Color::OutOfLineComponents::components const):
     46        (WebCore::Color::OutOfLineComponents::OutOfLineComponents):
     47        (WebCore::Color::setOutOfLineComponents):
     48        (WebCore::operator==):
     49        (WebCore::outOfLineComponentsEqual):
     50        (WebCore::outOfLineComponentsEqualIgnoringSemanticColor):
     51        (WebCore::equalIgnoringSemanticColor):
     52        (WebCore::Color::~Color):
     53        (WebCore::Color::hash const):
     54        (WebCore::Color::colorSpace const):
     55        (WebCore::Color::callOnUnderlyingType const):
     56        (WebCore::Color::isOutOfLine const):
     57        (WebCore::Color::isInline const):
     58        (WebCore::Color::asOutOfLine const):
     59        (WebCore::Color::asOutOfLineRef const):
     60        (WebCore::Color::tryGetAsSRGBABytes const):
     61        (WebCore::Color::encodedFlags):
     62        (WebCore::Color::encodedColorSpace):
     63        (WebCore::Color::encodedOutOfLineComponents):
     64        (WebCore::Color::decodedFlags):
     65        (WebCore::Color::decodedColorSpace):
     66        (WebCore::Color::decodedOutOfLineComponents):
     67        (WebCore::Color::setColor):
     68        (WebCore::Color::encode const):
     69        (WebCore::Color::decode):
     70        (WebCore::Color::setExtendedColor): Deleted.
     71        (WebCore::extendedColorsEqual): Deleted.
     72        (WebCore::extendedColorsEqualIgnoringSemanticColor): Deleted.
     73        (WebCore::Color::isExtended const): Deleted.
     74        (WebCore::Color::asExtended const): Deleted.
     75        (WebCore::Color::asExtendedRef const): Deleted.
     76        (WebCore::Color::encodedExtendedColor): Deleted.
     77        (WebCore::Color::decodedExtendedColor): Deleted.
     78        * platform/graphics/ColorSerialization.cpp:
     79        * platform/graphics/ExtendedColor.h: Removed.
     80        * platform/graphics/cg/ColorCG.cpp:
     81        (WebCore::cachedCGColor):
     82        * platform/graphics/cg/GradientCG.cpp:
     83        (WebCore::Gradient::createCGGradient):
     84        * platform/graphics/displaylists/DisplayListItems.cpp:
     85        (WebCore::DisplayList::SetInlineFillGradient::SetInlineFillGradient):
     86        (WebCore::DisplayList::SetInlineFillGradient::isInline):
     87        * platform/graphics/displaylists/DisplayListRecorder.cpp:
     88        (WebCore::DisplayList::containsOnlyInlineStateChanges):
     89        (WebCore::DisplayList::Recorder::appendStateChangeItem):
     90        * platform/graphics/mac/ColorMac.mm:
     91        (WebCore::nsColor):
     92
    1932021-03-02  Simon Fraser  <simon.fraser@apple.com>
    294
  • trunk/Source/WebCore/Headers.cmake

    r273683 r273776  
    11821182    platform/graphics/DisplayRefreshMonitorClient.h
    11831183    platform/graphics/DisplayRefreshMonitorManager.h
    1184     platform/graphics/ExtendedColor.h
    11851184    platform/graphics/ExtensionsGL.h
    11861185    platform/graphics/FloatPoint.h
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r273758 r273776  
    969969                31C0FF3E0E4CEFAC007D6FE5 /* JSWebKitAnimationEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 31C0FF3A0E4CEFAC007D6FE5 /* JSWebKitAnimationEvent.h */; };
    970970                31C0FF400E4CEFAC007D6FE5 /* JSWebKitTransitionEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 31C0FF3C0E4CEFAC007D6FE5 /* JSWebKitTransitionEvent.h */; };
    971                 31DCDF441DA1C45400EA5B93 /* ExtendedColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 31DCDF421DA1C45400EA5B93 /* ExtendedColor.h */; settings = {ATTRIBUTES = (Private, ); }; };
    972971                31DEA4561B39F4D900F77178 /* WebSystemBackdropLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 31DEA4541B39F4D900F77178 /* WebSystemBackdropLayer.h */; };
    973972                31EAF97E121435A400E7C1BF /* DeviceMotionClientIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 31EAF97C121435A400E7C1BF /* DeviceMotionClientIOS.h */; };
    … …  
    75087507                31D26BC51F86D268008FF255 /* JSImageBitmapOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSImageBitmapOptions.h; sourceTree = "<group>"; };
    75097508                31D26BC61F86D269008FF255 /* JSImageBitmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSImageBitmap.cpp; sourceTree = "<group>"; };
    7510                 31DCDF421DA1C45400EA5B93 /* ExtendedColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtendedColor.h; sourceTree = "<group>"; };
    75117509                31DEA4531B39F4D900F77178 /* WebSystemBackdropLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebSystemBackdropLayer.mm; sourceTree = "<group>"; };
    75127510                31DEA4541B39F4D900F77178 /* WebSystemBackdropLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSystemBackdropLayer.h; sourceTree = "<group>"; };
    … …  
    2669226690                                2D29ECC3192ECC8300984B78 /* DisplayRefreshMonitorManager.cpp */,
    2669326691                                2D29ECC4192ECC8300984B78 /* DisplayRefreshMonitorManager.h */,
    26694                                 31DCDF421DA1C45400EA5B93 /* ExtendedColor.h */,
    2669526692                                6E67D2A81280E8BD008758F7 /* ExtensionsGL.h */,
    2669626693                                B275353A0B053814002CE64F /* FloatPoint.cpp */,
    … …  
    3218632183                                93D196311D6CAB7600FC7E47 /* ExceptionOr.h in Headers */,
    3218732184                                837FB3451F9EA06D00D0FC31 /* ExtendableMessageEvent.h in Headers */,
    32188                                 31DCDF441DA1C45400EA5B93 /* ExtendedColor.h in Headers */,
    3218932185                                6E67D2A91280E8BD008758F7 /* ExtensionsGL.h in Headers */,
    3219032186                                6E72F550229DCD1700B3E151 /* ExtensionsGLANGLE.h in Headers */,
  • trunk/Source/WebCore/platform/graphics/Color.cpp

    r273683 r273776  
    4040    : m_colorAndFlags(other.m_colorAndFlags)
    4141{
    42     if (isExtended())
    43         asExtended().ref();
     42    if (isOutOfLine())
     43        asOutOfLine().ref();
    4444}
    4545
    … …  
    5454        return *this;
    5555
    56     if (isExtended())
    57         asExtended().deref();
     56    if (isOutOfLine())
     57        asOutOfLine().deref();
    5858
    5959    m_colorAndFlags = other.m_colorAndFlags;
    6060
    61     if (isExtended())
    62         asExtended().ref();
     61    if (isOutOfLine())
     62        asOutOfLine().ref();
    6363
    6464    return *this;
    … …  
    7070        return *this;
    7171
    72     if (isExtended())
    73         asExtended().deref();
     72    if (isOutOfLine())
     73        asOutOfLine().deref();
    7474
    7575    m_colorAndFlags = other.m_colorAndFlags;
    … …  
    167167        return *this;
    168168   
    169     if (isExtended())
    170         return { asExtendedRef(), Flags::Semantic };
     169    if (isOutOfLine())
     170        return { asOutOfLineRef(), colorSpace(), Flags::Semantic };
    171171    return { asInline(), Flags::Semantic };
    172172}
    … …  
    174174std::pair<ColorSpace, ColorComponents<float>> Color::colorSpaceAndComponents() const
    175175{
    176     if (isExtended())
    177         return { asExtended().colorSpace(), asExtended().components() };
     176    if (isOutOfLine())
     177        return { colorSpace(), asOutOfLine().components() };
    178178    return { ColorSpace::SRGB, asColorComponents(convertColor<SRGBA<float>>(asInline())) };
    179179}
  • trunk/Source/WebCore/platform/graphics/Color.h

    r273683 r273776  
    2626#pragma once
    2727
     28#include "ColorConversion.h"
    2829#include "ColorSpace.h"
    2930#include "ColorUtilities.h"
    30 #include "ExtendedColor.h"
     31#include <functional>
    3132#include <wtf/Forward.h>
    3233#include <wtf/HashFunctions.h>
    … …  
    3435#include <wtf/OptionSet.h>
    3536#include <wtf/Optional.h>
     37#include <wtf/Ref.h>
     38#include <wtf/RefCounted.h>
    3639#include <wtf/StdLibExtras.h>
    3740
    … …  
    7275    Color(SRGBA<uint8_t>, OptionSet<Flags> = { });
    7376    Color(Optional<SRGBA<uint8_t>>, OptionSet<Flags> = { });
    74 
    75     Color(ColorComponents<float>, ColorSpace, OptionSet<Flags> = { });
    7677   
    7778    template<typename ColorType, typename std::enable_if_t<IsColorTypeWithComponentType<ColorType, float>>* = nullptr>
    … …  
    99100    bool usesColorFunctionSerialization() const;
    100101
    101     bool isOpaque() const { return isExtended() ? asExtended().alpha() == 1.0 : asInline().alpha == 255; }
    102     bool isVisible() const { return isExtended() ? asExtended().alpha() > 0.0 : asInline().alpha > 0; }
    103     uint8_t alphaByte() const { return isExtended() ? convertFloatAlphaTo<uint8_t>(asExtended().alpha()) : asInline().alpha; }
    104     float alphaAsFloat() const { return isExtended() ? asExtended().alpha() : convertByteAlphaTo<float>(asInline().alpha); }
     102    ColorSpace colorSpace() const;
     103
     104    bool isOpaque() const { return isOutOfLine() ? asOutOfLine().alpha() == 1.0 : asInline().alpha == 255; }
     105    bool isVisible() const { return isOutOfLine() ? asOutOfLine().alpha() > 0.0 : asInline().alpha > 0; }
     106    uint8_t alphaByte() const { return isOutOfLine() ? convertFloatAlphaTo<uint8_t>(asOutOfLine().alpha()) : asInline().alpha; }
     107    float alphaAsFloat() const { return isOutOfLine() ? asOutOfLine().alpha() : convertByteAlphaTo<float>(asInline().alpha); }
    105108
    106109    WEBCORE_EXPORT float luminance() const;
    … …  
    137140    Color semanticColor() const;
    138141
     142    // Returns the underlying color if its type is SRGBA<uint8_t>.
     143    Optional<SRGBA<uint8_t>> tryGetAsSRGBABytes() const;
     144
    139145#if PLATFORM(GTK)
    140146    Color(const GdkRGBA&);
    … …  
    143149
    144150#if USE(CG)
    145     WEBCORE_EXPORT Color(CGColorRef);
    146     WEBCORE_EXPORT Color(CGColorRef, OptionSet<Flags>);
     151    WEBCORE_EXPORT Color(CGColorRef, OptionSet<Flags> = { });
    147152#endif
    148153
    … …  
    168173    static constexpr auto orange = SRGBA<uint8_t> { 255, 128, 0 };
    169174
    170     bool isExtended() const;
    171     bool isInline() const;
    172 
    173     const ExtendedColor& asExtended() const;
    174     SRGBA<uint8_t> asInline() const;
    175 
    176     // Extended and non-extended colors will always be non-equal.
     175    static bool isBlackColor(const Color&);
     176    static bool isWhiteColor(const Color&);
     177
     178    // Out of line and inline colors will always be non-equal.
    177179    friend bool operator==(const Color& a, const Color& b);
    178180    friend bool equalIgnoringSemanticColor(const Color& a, const Color& b);
    179     friend bool extendedColorsEqual(const Color&, const Color&);
    180     friend bool extendedColorsEqualIgnoringSemanticColor(const Color&, const Color&);
    181 
    182     static bool isBlackColor(const Color&);
    183     static bool isWhiteColor(const Color&);
     181    friend bool outOfLineComponentssEqual(const Color&, const Color&);
     182    friend bool outOfLineComponentssEqualIgnoringSemanticColor(const Color&, const Color&);
    184183
    185184    template<class Encoder> void encode(Encoder&) const;
    … …  
    187186
    188187private:
    189     Color(Ref<ExtendedColor>&&, OptionSet<Flags> = { });
    190 
    191     enum class FlagsIncludingPrivate : uint16_t {
    192         Semantic                        = static_cast<uint16_t>(Flags::Semantic),
    193         UseColorFunctionSerialization   = static_cast<uint16_t>(Flags::UseColorFunctionSerialization),
     188    class OutOfLineComponents : public RefCounted<OutOfLineComponents> {
     189    public:
     190        static Ref<OutOfLineComponents> create(ColorComponents<float> components)
     191        {
     192            return adoptRef(*new OutOfLineComponents(components));
     193        }
     194
     195        float alpha() const { return m_components[3]; }
     196        ColorComponents<float> components() const { return m_components; }
     197
     198    private:
     199        OutOfLineComponents(ColorComponents<float> components)
     200            : m_components(components)
     201        {
     202        }
     203
     204        ColorComponents<float> m_components;
     205    };
     206    Color(Ref<OutOfLineComponents>&&, ColorSpace, OptionSet<Flags> = { });
     207
     208    enum class FlagsIncludingPrivate : uint8_t {
     209        Semantic                        = static_cast<uint8_t>(Flags::Semantic),
     210        UseColorFunctionSerialization   = static_cast<uint8_t>(Flags::UseColorFunctionSerialization),
    194211        Valid                           = 1 << 2,
    195         Extended                        = 1 << 3,
     212        OutOfLine                       = 1 << 3,
    196213        HashTableEmptyValue             = 1 << 4,
    197214        HashTableDeletedValue           = 1 << 5,
    … …  
    200217
    201218    OptionSet<FlagsIncludingPrivate> flags() const;
     219    bool isOutOfLine() const;
     220    bool isInline() const;
    202221
    203222    void setColor(SRGBA<uint8_t>, OptionSet<FlagsIncludingPrivate> = { });
    204     void setExtendedColor(Ref<ExtendedColor>&&, OptionSet<FlagsIncludingPrivate> = { });
    205 
     223    void setOutOfLineComponents(Ref<OutOfLineComponents>&&, ColorSpace, OptionSet<FlagsIncludingPrivate> = { });
     224
     225    SRGBA<uint8_t> asInline() const;
    206226    PackedColor::RGBA asPackedInline() const;
    207     Ref<ExtendedColor> asExtendedRef() const;
     227
     228    const OutOfLineComponents& asOutOfLine() const;
     229    Ref<OutOfLineComponents> asOutOfLineRef() const;
    208230
    209231#if CPU(ADDRESS64)
    … …  
    213235#endif
    214236    static constexpr uint64_t colorValueMask = (1ULL << maxNumberOfBitsInPointer) - 1;
     237    static constexpr uint64_t flagsSize = sizeof(FlagsIncludingPrivate) * 8;
     238    static constexpr uint64_t flagsShift = maxNumberOfBitsInPointer;
     239    static constexpr uint64_t colorSpaceSize = sizeof(ColorSpace) * 8;
     240    static constexpr uint64_t colorSpaceShift = flagsShift + flagsSize;
     241    static_assert(flagsSize + colorSpaceSize + maxNumberOfBitsInPointer <= 64);
    215242
    216243    static uint64_t encodedFlags(OptionSet<FlagsIncludingPrivate>);
     244    static uint64_t encodedColorSpace(ColorSpace);
    217245    static uint64_t encodedInlineColor(SRGBA<uint8_t>);
    218246    static uint64_t encodedPackedInlineColor(PackedColor::RGBA);
    219     static uint64_t encodedExtendedColor(Ref<ExtendedColor>&&);
     247    static uint64_t encodedOutOfLineComponents(Ref<OutOfLineComponents>&&);
    220248
    221249    static OptionSet<FlagsIncludingPrivate> decodedFlags(uint64_t);
     250    static ColorSpace decodedColorSpace(uint64_t);
    222251    static SRGBA<uint8_t> decodedInlineColor(uint64_t);
    223252    static PackedColor::RGBA decodedPackedInlineColor(uint64_t);
    224     static ExtendedColor& decodedExtendedColor(uint64_t);
     253    static OutOfLineComponents& decodedOutOfLineComponents(uint64_t);
    225254
    226255    static constexpr uint64_t invalidColorAndFlags = 0;
    … …  
    231260bool operator!=(const Color&, const Color&);
    232261
    233 // One or both must be extended colors.
    234 bool extendedColorsEqual(const Color&, const Color&);
    235 bool extendedColorsEqualIgnoringSemanticColor(const Color&, const Color&);
     262// One or both must be out of line colors.
     263bool outOfLineComponentssEqual(const Color&, const Color&);
     264bool outOfLineComponentssEqualIgnoringSemanticColor(const Color&, const Color&);
    236265
    237266#if USE(CG)
    … …  
    243272inline bool operator==(const Color& a, const Color& b)
    244273{
    245     if (a.isExtended() || b.isExtended())
    246         return extendedColorsEqual(a, b);
     274    if (a.isOutOfLine() || b.isOutOfLine())
     275        return outOfLineComponentssEqual(a, b);
    247276    return a.m_colorAndFlags == b.m_colorAndFlags;
    248277}
    … …  
    253282}
    254283
    255 inline bool extendedColorsEqual(const Color& a, const Color& b)
    256 {
    257     if (a.isExtended() && b.isExtended())
    258         return a.asExtended() == b.asExtended() && a.flags() == b.flags();
    259 
    260     ASSERT(a.isExtended() || b.isExtended());
     284inline bool outOfLineComponentssEqual(const Color& a, const Color& b)
     285{
     286    if (a.isOutOfLine() && b.isOutOfLine())
     287        return a.asOutOfLine().components() == b.asOutOfLine().components() && a.colorSpace() == b.colorSpace() && a.flags() == b.flags();
     288
     289    ASSERT(a.isOutOfLine() || b.isOutOfLine());
    261290    return false;
    262291}
    263292
    264 inline bool extendedColorsEqualIgnoringSemanticColor(const Color& a, const Color& b)
    265 {
    266     if (a.isExtended() && b.isExtended()) {
     293inline bool outOfLineComponentssEqualIgnoringSemanticColor(const Color& a, const Color& b)
     294{
     295    if (a.isOutOfLine() && b.isOutOfLine()) {
    267296        auto aFlags = a.flags() - Color::FlagsIncludingPrivate::Semantic;
    268297        auto bFlags = b.flags() - Color::FlagsIncludingPrivate::Semantic;
    269         return a.asExtended() == b.asExtended() && aFlags == bFlags;
     298        return a.asOutOfLine().components() == b.asOutOfLine().components() && a.colorSpace() == b.colorSpace() && aFlags == bFlags;
    270299    }
    271300
    272     ASSERT(a.isExtended() || b.isExtended());
     301    ASSERT(a.isOutOfLine() || b.isOutOfLine());
    273302    return false;
    274303}
    … …  
    276305inline bool equalIgnoringSemanticColor(const Color& a, const Color& b)
    277306{
    278     if (a.isExtended() || b.isExtended())
    279         return extendedColorsEqualIgnoringSemanticColor(a, b);
     307    if (a.isOutOfLine() || b.isOutOfLine())
     308        return outOfLineComponentssEqualIgnoringSemanticColor(a, b);
    280309
    281310    auto aFlags = a.flags() - Color::FlagsIncludingPrivate::Semantic;
    … …  
    295324}
    296325
    297 inline Color::Color(ColorComponents<float> components, ColorSpace colorSpace, OptionSet<Flags> flags)
    298 {
    299     setExtendedColor(ExtendedColor::create(components, colorSpace), toFlagsIncludingPrivate(flags));
    300 }
    301 
    302326template<typename ColorType, typename std::enable_if_t<IsColorTypeWithComponentType<ColorType, float>>*>
    303327inline Color::Color(const ColorType& color, OptionSet<Flags> flags)
    304328{
    305     setExtendedColor(ExtendedColor::create(color), toFlagsIncludingPrivate(flags));
     329    setOutOfLineComponents(OutOfLineComponents::create(asColorComponents(color)), ColorSpaceFor<ColorType>, toFlagsIncludingPrivate(flags));
    306330}
    307331
    … …  
    310334{
    311335    if (color)
    312         setExtendedColor(ExtendedColor::create(*color), toFlagsIncludingPrivate(flags));
    313 }
    314 
    315 inline Color::Color(Ref<ExtendedColor>&& extendedColor, OptionSet<Flags> flags)
    316 {
    317     setExtendedColor(WTFMove(extendedColor), toFlagsIncludingPrivate(flags));
     336        setOutOfLineComponents(OutOfLineComponents::create(asColorComponents(*color)), ColorSpaceFor<ColorType>, toFlagsIncludingPrivate(flags));
     337}
     338
     339inline Color::Color(Ref<OutOfLineComponents>&& outOfLineComponents, ColorSpace colorSpace, OptionSet<Flags> flags)
     340{
     341    setOutOfLineComponents(WTFMove(outOfLineComponents), colorSpace, toFlagsIncludingPrivate(flags));
    318342}
    319343
    … …  
    335359inline Color::~Color()
    336360{
    337     if (isExtended())
    338         asExtended().deref();
     361    if (isOutOfLine())
     362        asOutOfLine().deref();
    339363}
    340364
    341365inline unsigned Color::hash() const
    342366{
    343     if (isExtended())
    344         return computeHash(asExtended().components(), asExtended().colorSpace(), flags().toRaw());
     367    if (isOutOfLine())
     368        return computeHash(asOutOfLine().components(), colorSpace(), flags().toRaw());
    345369    return computeHash(asPackedInline().value, flags().toRaw());
    346370}
    … …  
    361385}
    362386
     387inline ColorSpace Color::colorSpace() const
     388{
     389    return decodedColorSpace(m_colorAndFlags);
     390}
     391
    363392template<typename Functor> decltype(auto) Color::callOnUnderlyingType(Functor&& functor) const
    364393{
    365     if (isExtended())
    366         return asExtended().callOnUnderlyingType(std::forward<Functor>(functor));
     394    if (isOutOfLine())
     395        return callWithColorType(asOutOfLine().components(), colorSpace(), std::forward<Functor>(functor));
    367396    return std::invoke(std::forward<Functor>(functor), asInline());
    368397}
    … …  
    400429}
    401430
    402 inline bool Color::isExtended() const
    403 {
    404     return flags().contains(FlagsIncludingPrivate::Extended);
     431inline bool Color::isOutOfLine() const
     432{
     433    return flags().contains(FlagsIncludingPrivate::OutOfLine);
    405434}
    406435
    407436inline bool Color::isInline() const
    408437{
    409     return !flags().contains(FlagsIncludingPrivate::Extended);
    410 }
    411 
    412 inline const ExtendedColor& Color::asExtended() const
    413 {
    414     ASSERT(isExtended());
    415     return decodedExtendedColor(m_colorAndFlags);
    416 }
    417 
    418 inline Ref<ExtendedColor> Color::asExtendedRef() const
    419 {
    420     ASSERT(isExtended());
    421     return decodedExtendedColor(m_colorAndFlags);
     438    return !flags().contains(FlagsIncludingPrivate::OutOfLine);
     439}
     440
     441inline const Color::OutOfLineComponents& Color::asOutOfLine() const
     442{
     443    ASSERT(isOutOfLine());
     444    return decodedOutOfLineComponents(m_colorAndFlags);
     445}
     446
     447inline Ref<Color::OutOfLineComponents> Color::asOutOfLineRef() const
     448{
     449    ASSERT(isOutOfLine());
     450    return decodedOutOfLineComponents(m_colorAndFlags);
    422451}
    423452
    … …  
    434463}
    435464
     465inline Optional<SRGBA<uint8_t>> Color::tryGetAsSRGBABytes() const
     466{
     467    if (isInline())
     468        return asInline();
     469    return WTF::nullopt;
     470}
     471
    436472inline uint64_t Color::encodedFlags(OptionSet<FlagsIncludingPrivate> flags)
    437473{
    438     return static_cast<uint64_t>(flags.toRaw()) << maxNumberOfBitsInPointer;
     474    return static_cast<uint64_t>(flags.toRaw()) << flagsShift;
     475}
     476
     477inline uint64_t Color::encodedColorSpace(ColorSpace colorSpace)
     478{
     479    return static_cast<uint64_t>(colorSpace) << colorSpaceShift;
    439480}
    440481
    … …  
    449490}
    450491
    451 inline uint64_t Color::encodedExtendedColor(Ref<ExtendedColor>&& extendedColor)
     492inline uint64_t Color::encodedOutOfLineComponents(Ref<OutOfLineComponents>&& outOfLineComponents)
    452493{
    453494#if CPU(ADDRESS64)
    454     return bitwise_cast<uint64_t>(&extendedColor.leakRef());
     495    return bitwise_cast<uint64_t>(&outOfLineComponents.leakRef());
    455496#else
    456     return bitwise_cast<uint32_t>(&extendedColor.leakRef());
     497    return bitwise_cast<uint32_t>(&outOfLineComponents.leakRef());
    457498#endif
    458499}
    … …  
    460501inline OptionSet<Color::FlagsIncludingPrivate> Color::decodedFlags(uint64_t value)
    461502{
    462     return OptionSet<Color::FlagsIncludingPrivate>::fromRaw(static_cast<unsigned>(value >> maxNumberOfBitsInPointer));
     503    return OptionSet<Color::FlagsIncludingPrivate>::fromRaw(static_cast<uint8_t>(value >> flagsShift));
     504}
     505
     506inline ColorSpace Color::decodedColorSpace(uint64_t value)
     507{
     508    return static_cast<ColorSpace>(static_cast<uint8_t>(value >> colorSpaceShift));
    463509}
    464510
    … …  
    473519}
    474520
    475 inline ExtendedColor& Color::decodedExtendedColor(uint64_t value)
     521inline Color::OutOfLineComponents& Color::decodedOutOfLineComponents(uint64_t value)
    476522{
    477523#if CPU(ADDRESS64)
    478     return *bitwise_cast<ExtendedColor*>(value & colorValueMask);
     524    return *bitwise_cast<OutOfLineComponents*>(value & colorValueMask);
    479525#else
    480     return *bitwise_cast<ExtendedColor*>(static_cast<uint32_t>(value & colorValueMask));
     526    return *bitwise_cast<OutOfLineComponents*>(static_cast<uint32_t>(value & colorValueMask));
    481527#endif
    482528}
    … …  
    485531{
    486532    flags.add({ FlagsIncludingPrivate::Valid });
    487     m_colorAndFlags = encodedInlineColor(color) | encodedFlags(flags);
     533    m_colorAndFlags = encodedInlineColor(color) | encodedColorSpace(ColorSpace::SRGB) | encodedFlags(flags);
    488534    ASSERT(isInline());
    489535}
    490536
    491 inline void Color::setExtendedColor(Ref<ExtendedColor>&& color, OptionSet<FlagsIncludingPrivate> flags)
    492 {
    493     flags.add({ FlagsIncludingPrivate::Valid, FlagsIncludingPrivate::Extended });
    494     m_colorAndFlags = encodedExtendedColor(WTFMove(color)) | encodedFlags(flags);
    495     ASSERT(isExtended());
     537inline void Color::setOutOfLineComponents(Ref<OutOfLineComponents>&& color, ColorSpace colorSpace, OptionSet<FlagsIncludingPrivate> flags)
     538{
     539    flags.add({ FlagsIncludingPrivate::Valid, FlagsIncludingPrivate::OutOfLine });
     540    m_colorAndFlags = encodedOutOfLineComponents(WTFMove(color)) | encodedColorSpace(colorSpace) | encodedFlags(flags);
     541    ASSERT(isOutOfLine());
    496542}
    497543
    … …  
    506552    encoder << flags().contains(FlagsIncludingPrivate::Semantic);
    507553    encoder << flags().contains(FlagsIncludingPrivate::UseColorFunctionSerialization);
    508 
    509     if (isExtended()) {
     554   
     555    if (isOutOfLine()) {
    510556        encoder << true;
    511 
    512         auto& extendedColor = asExtended();
    513         auto [c1, c2, c3, alpha] = extendedColor.components();
     557        encoder << colorSpace();
     558
     559        auto& outOfLineComponents = asOutOfLine();
     560        auto [c1, c2, c3, alpha] = outOfLineComponents.components();
    514561        encoder << c1;
    515562        encoder << c2;
    516563        encoder << c3;
    517564        encoder << alpha;
    518         encoder << extendedColor.colorSpace();
    519565        return;
    520566    }
    … …  
    549595        flags.add(Flags::UseColorFunctionSerialization);
    550596
    551     bool isExtended;
    552     if (!decoder.decode(isExtended))
     597    bool isOutOfLine;
     598    if (!decoder.decode(isOutOfLine))
    553599        return WTF::nullopt;
    554600
    555     if (isExtended) {
     601    if (isOutOfLine) {
     602        ColorSpace colorSpace;
     603        if (!decoder.decode(colorSpace))
     604            return WTF::nullopt;
    556605        float c1;
    557         float c2;
    558         float c3;
    559         float alpha;
    560         ColorSpace colorSpace;
    561606        if (!decoder.decode(c1))
    562607            return WTF::nullopt;
     608        float c2;
    563609        if (!decoder.decode(c2))
    564610            return WTF::nullopt;
     611        float c3;
    565612        if (!decoder.decode(c3))
    566613            return WTF::nullopt;
     614        float alpha;
    567615        if (!decoder.decode(alpha))
    568616            return WTF::nullopt;
    569         if (!decoder.decode(colorSpace))
    570             return WTF::nullopt;
    571         return Color { ExtendedColor::create({ c1, c2, c3, alpha }, colorSpace), flags };
     617        return Color { OutOfLineComponents::create({ c1, c2, c3, alpha }), colorSpace, flags };
    572618    }
    573619
  • trunk/Source/WebCore/platform/graphics/ColorSerialization.cpp

    r273211 r273776  
    2828
    2929#include "Color.h"
    30 #include "ExtendedColor.h"
    3130#include <wtf/Assertions.h>
    3231#include <wtf/HexNumber.h>
  • trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp

    r273211 r273776  
    8585}
    8686
    87 Color::Color(CGColorRef color)
    88     : Color(roundAndClampToSRGBALossy(color))
    89 {
    90 }
    91 
    9287Color::Color(CGColorRef color, OptionSet<Flags> flags)
    9388    : Color(roundAndClampToSRGBALossy(color), flags)
    … …  
    129124CGColorRef cachedCGColor(const Color& color)
    130125{
    131     if (color.isInline()) {
    132         switch (PackedColor::RGBA { color.asInline() }.value) {
     126    if (auto srgb = color.tryGetAsSRGBABytes()) {
     127        switch (PackedColor::RGBA { *srgb }.value) {
    133128        case PackedColor::RGBA { Color::transparentBlack }.value: {
    134129            static CGColorRef transparentCGColor = leakCGColor(color);
  • trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp

    r272736 r273776  
    5555    colorComponents.reserveInitialCapacity(numStops * 4);
    5656
    57     bool hasExtendedColors = false;
     57    // FIXME: Consider making this into two loops to avoid unnecessary allocation of the
     58    // CGColorRefs in the common case of all ColorSpace::SRGB.
     59
     60    bool hasOnlyBoundedSRGBColorStops = true;
    5861    for (const auto& stop : m_stops) {
    59 
    60         // If all the stops are sRGB, it is faster to create a gradient using
    61         // components than CGColors.
    62         // FIXME: Rather than just check for extended colors, we should check the actual
    63         // color space, and whether or not the components are outside [0-1].
    64         // <rdar://problem/32926606>
    65 
    66         if (stop.color.isExtended())
    67             hasExtendedColors = true;
     62        // If all the stops are bounded sRGB (as represented by the color having the color space
     63        // ColorSpace::SRGB, it is faster to create a gradient using components than CGColors.
     64        if (stop.color.colorSpace() != ColorSpace::SRGB)
     65            hasOnlyBoundedSRGBColorStops = false;
    6866
    6967        auto [colorSpace, components] = stop.color.colorSpaceAndComponents();
    … …  
    8482#endif
    8583
    86     if (hasExtendedColors)
     84    if (hasOnlyBoundedSRGBColorStops)
     85        m_gradient = adoptCF(CGGradientCreateWithColorComponents(sRGBColorSpaceRef(), colorComponents.data(), locations.data(), numStops));
     86    else
    8787        m_gradient = adoptCF(CGGradientCreateWithColors(extendedColorsGradientColorSpace, colorsArray.get(), locations.data()));
    88     else
    89         m_gradient = adoptCF(CGGradientCreateWithColorComponents(sRGBColorSpaceRef(), colorComponents.data(), locations.data(), numStops));
    9088}
    9189
  • trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp

    r273291 r273776  
    125125    for (uint8_t i = 0; i < m_colorStopCount; ++i) {
    126126        m_offsets[i] = gradient.stops()[i].offset;
    127         m_colors[i] = gradient.stops()[i].color.asInline();
     127        m_colors[i] = *gradient.stops()[i].color.tryGetAsSRGBABytes();
    128128    }
    129129}
    … …  
    163163
    164164    for (auto& colorStop : gradient.stops()) {
    165         if (!colorStop.color.isInline())
     165        if (!colorStop.color.tryGetAsSRGBABytes())
    166166            return false;
    167167    }
  • trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp

    r273291 r273776  
    7373        return false;
    7474
    75     if (changeFlags.contains(GraphicsContextState::StrokeColorChange) && !changes.m_state.strokeColor.isInline())
     75    if (changeFlags.contains(GraphicsContextState::StrokeColorChange) && !changes.m_state.strokeColor.tryGetAsSRGBABytes())
    7676        return false;
    7777
    78     if (changeFlags.contains(GraphicsContextState::FillColorChange) && !changes.m_state.fillColor.isInline())
     78    if (changeFlags.contains(GraphicsContextState::FillColorChange) && !changes.m_state.fillColor.tryGetAsSRGBABytes())
    7979        return false;
    8080
    … …  
    105105
    106106    if (changeFlags.contains(GraphicsContextState::StrokeColorChange))
    107         append<SetInlineStrokeColor>(changes.m_state.strokeColor.asInline());
     107        append<SetInlineStrokeColor>(*changes.m_state.strokeColor.tryGetAsSRGBABytes());
    108108
    109109    if (changeFlags.contains(GraphicsContextState::StrokeThicknessChange))
    … …  
    111111
    112112    if (changeFlags.contains(GraphicsContextState::FillColorChange))
    113         append<SetInlineFillColor>(changes.m_state.fillColor.asInline());
     113        append<SetInlineFillColor>(*changes.m_state.fillColor.tryGetAsSRGBABytes());
    114114
    115115    if (changeFlags.contains(GraphicsContextState::FillGradientChange))
  • trunk/Source/WebCore/platform/graphics/mac/ColorMac.mm

    r273610 r273776  
    114114NSColor *nsColor(const Color& color)
    115115{
    116     if (color.isInline()) {
    117         switch (PackedColor::RGBA { color.asInline() }.value) {
     116    if (auto srgb = color.tryGetAsSRGBABytes()) {
     117        switch (PackedColor::RGBA { *srgb }.value) {
    118118        case PackedColor::RGBA { Color::transparentBlack }.value: {
    119119            static NeverDestroyed<RetainPtr<NSColor>> clearColor = [NSColor colorWithSRGBRed:0 green:0 blue:0 alpha:0];
  • trunk/Tools/ChangeLog

    r273774 r273776  
     12021-03-02  Sam Weinig  <weinig@apple.com>
     2
     3        Reduce the size of extended colors by storing the color space in free bits of the owning Color
     4        https://bugs.webkit.org/show_bug.cgi?id=222584
     5
     6        Reviewed by Darin Adler.
     7
     8        * TestWebKitAPI/CMakeLists.txt:
     9        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     10        * TestWebKitAPI/Tests/WebCore/ColorTests.cpp:
     11        (TestWebKitAPI::TEST):
     12        (TestWebKitAPI::makeColor):
     13        * TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp:
     14        (TestWebKitAPI::TEST):
     15        * TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp: Removed.
     16        Update tests to account for removal of the ExtendedColor class.
     17        Merge ExtendedColorTests.cpp that still make sense into ColorTests.cpp
     18
    1192021-03-02  Jonathan Bedard  <jbedard@apple.com>
    220
  • trunk/Tools/TestWebKitAPI/CMakeLists.txt

    r272732 r273776  
    171171        Tests/WebCore/ComplexTextController.cpp
    172172        Tests/WebCore/ContextMenuAction.cpp
    173         Tests/WebCore/ExtendedColorTests.cpp
    174173        Tests/WebCore/FileMonitor.cpp
    175174        Tests/WebCore/FloatPointTests.cpp
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r273711 r273776  
    198198                3128A8152376413300D90D40 /* image.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 3128A814237640FD00D90D40 /* image.html */; };
    199199                313C3A0221E567C300DBA86E /* SystemPreviewBlobNaming.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 313C3A0121E5677A00DBA86E /* SystemPreviewBlobNaming.html */; };
    200                 315118101DB1AE4000176304 /* ExtendedColorTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3151180F1DB1ADD500176304 /* ExtendedColorTests.cpp */; };
    201200                31B76E4323298E2C007FED2C /* SystemPreview.mm in Sources */ = {isa = PBXBuildFile; fileRef = 31B76E4223298E2B007FED2C /* SystemPreview.mm */; };
    202201                31B76E4523299BDC007FED2C /* system-preview-trigger.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 31B76E4423299BA3007FED2C /* system-preview-trigger.html */; };
    … …  
    19331932                3128A814237640FD00D90D40 /* image.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = image.html; sourceTree = "<group>"; };
    19341933                313C3A0121E5677A00DBA86E /* SystemPreviewBlobNaming.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = SystemPreviewBlobNaming.html; sourceTree = "<group>"; };
    1935                 3151180F1DB1ADD500176304 /* ExtendedColorTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExtendedColorTests.cpp; sourceTree = "<group>"; };
    19361934                31B76E4223298E2B007FED2C /* SystemPreview.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SystemPreview.mm; sourceTree = "<group>"; };
    19371935                31B76E4423299BA3007FED2C /* system-preview-trigger.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "system-preview-trigger.html"; sourceTree = "<group>"; };
    … …  
    35863584                                F4094CC625545BD5003D73E3 /* DisplayListTests.cpp */,
    35873585                                93915A1624DB66C70019FF43 /* DocumentOrder.cpp */,
    3588                                 3151180F1DB1ADD500176304 /* ExtendedColorTests.cpp */,
    35893586                                579651E6216BFD53006EBFE5 /* FidoHidMessageTest.cpp */,
    35903587                                572B40352176A029000AD43E /* FidoTestData.h */,
    … …  
    52925289                                CDA29B2920FD2A9900F15CED /* ExitFullscreenOnEnterPiP.mm in Sources */,
    52935290                                1D12BEC0245BEF85004C0B7A /* ExitPiPOnSuspendVideoElement.mm in Sources */,
    5294                                 315118101DB1AE4000176304 /* ExtendedColorTests.cpp in Sources */,
    52955291                                7CCE7EF11A411AE600447C4C /* FailedLoad.cpp in Sources */,
    52965292                                579651E7216BFDED006EBFE5 /* FidoHidMessageTest.cpp in Sources */,
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/ColorTests.cpp

    r273683 r273776  
    11/*
    2  * Copyright (C) 2011, 2012, 2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2021 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
    … …  
    2727
    2828#include "Test.h"
     29#include "WTFStringUtilities.h"
    2930#include <WebCore/Color.h>
    3031#include <WebCore/ColorConversion.h>
     32#include <WebCore/ColorSerialization.h>
    3133#include <WebCore/ColorTypes.h>
     34#include <wtf/MathExtras.h>
    3235
    3336using namespace WebCore;
    … …  
    167170    Color invalidColor;
    168171    EXPECT_FALSE(invalidColor.isValid());
    169     EXPECT_FALSE(invalidColor.isExtended());
    170172
    171173    Color otherInvalidColor = invalidColor;
    172174    EXPECT_FALSE(otherInvalidColor.isValid());
    173     EXPECT_FALSE(otherInvalidColor.isExtended());
    174175
    175176    Color validColor = Color::red;
    176177    EXPECT_TRUE(validColor.isValid());
    177     EXPECT_FALSE(validColor.isExtended());
    178178
    179179    Color otherValidColor = validColor;
    180180    EXPECT_TRUE(otherValidColor.isValid());
    181     EXPECT_FALSE(otherValidColor.isExtended());
    182181
    183182    validColor = SRGBA<uint8_t> { 1, 2, 3, 4 };
    184183    EXPECT_TRUE(validColor.isValid());
    185     EXPECT_FALSE(validColor.isExtended());
    186184    auto validColorComponents = validColor.toSRGBALossy<uint8_t>();
    187185    EXPECT_EQ(validColorComponents.red, 1);
    … …  
    192190    Color yetAnotherValidColor(WTFMove(validColor));
    193191    EXPECT_TRUE(yetAnotherValidColor.isValid());
    194     EXPECT_FALSE(yetAnotherValidColor.isExtended());
    195192    auto yetAnotherValidColorComponents = yetAnotherValidColor.toSRGBALossy<uint8_t>();
    196193    EXPECT_EQ(yetAnotherValidColorComponents.red, 1);
    … …  
    201198    otherValidColor = WTFMove(yetAnotherValidColor);
    202199    EXPECT_TRUE(otherValidColor.isValid());
    203     EXPECT_FALSE(otherValidColor.isExtended());
    204200    auto otherValidColorComponents = otherValidColor.toSRGBALossy<uint8_t>();
    205201    EXPECT_EQ(otherValidColorComponents.red, 1);
    … …  
    234230}
    235231
     232TEST(Color, Constructor)
     233{
     234    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     235
     236    auto [colorSpace, components] = c1.colorSpaceAndComponents();
     237    auto [r, g, b, alpha] = components;
     238
     239    EXPECT_FLOAT_EQ(1.0, r);
     240    EXPECT_FLOAT_EQ(0.5, g);
     241    EXPECT_FLOAT_EQ(0.25, b);
     242    EXPECT_FLOAT_EQ(1.0, alpha);
     243    EXPECT_EQ(serializationForCSS(c1), "color(display-p3 1 0.5 0.25)");
     244}
     245
     246TEST(Color, CopyConstructor)
     247{
     248    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     249    Color c2(c1);
     250
     251    auto [colorSpace, components] = c2.colorSpaceAndComponents();
     252    auto [r, g, b, alpha] = components;
     253
     254    EXPECT_FLOAT_EQ(1.0, r);
     255    EXPECT_FLOAT_EQ(0.5, g);
     256    EXPECT_FLOAT_EQ(0.25, b);
     257    EXPECT_FLOAT_EQ(1.0, alpha);
     258    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
     259}
     260
     261TEST(Color, Assignment)
     262{
     263    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     264    Color c2 = c1;
     265
     266    auto [colorSpace, components] = c2.colorSpaceAndComponents();
     267    auto [r, g, b, alpha] = components;
     268
     269    EXPECT_FLOAT_EQ(1.0, r);
     270    EXPECT_FLOAT_EQ(0.5, g);
     271    EXPECT_FLOAT_EQ(0.25, b);
     272    EXPECT_FLOAT_EQ(1.0, alpha);
     273    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
     274}
     275
     276TEST(Color, Equality)
     277{
     278    {
     279        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     280        Color c2 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     281        EXPECT_EQ(c1, c2);
     282    }
     283
     284    {
     285        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     286        Color c2 { SRGBA<float> { 1.0, 0.5, 0.25, 1.0 } };
     287        EXPECT_NE(c1, c2);
     288    }
     289
     290    auto componentBytes = SRGBA<uint8_t> { 255, 128, 63, 127 };
     291    Color rgb1 { convertColor<SRGBA<float>>(componentBytes) };
     292    Color rgb2 { componentBytes };
     293    EXPECT_NE(rgb1, rgb2);
     294    EXPECT_NE(rgb2, rgb1);
     295}
     296
     297TEST(Color, Hash)
     298{
     299    {
     300        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     301        Color c2 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     302        EXPECT_EQ(c1.hash(), c2.hash());
     303    }
     304
     305    {
     306        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     307        Color c2 { SRGBA<float> { 1.0, 0.5, 0.25, 1.0 } };
     308        EXPECT_NE(c1.hash(), c2.hash());
     309    }
     310
     311    auto componentBytes = SRGBA<uint8_t> { 255, 128, 63, 127 };
     312    Color rgb1 { convertColor<SRGBA<float>>(componentBytes) };
     313    Color rgb2 { componentBytes };
     314    EXPECT_NE(rgb1.hash(), rgb2.hash());
     315}
     316
     317TEST(Color, MoveConstructor)
     318{
     319    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     320    Color c2(WTFMove(c1));
     321
     322    // We should have moved the out of line color pointer into c2,
     323    // and set c1 to invalid so that it doesn't cause deletion.
     324    EXPECT_FALSE(c1.isValid());
     325
     326    auto [colorSpace, components] = c2.colorSpaceAndComponents();
     327    EXPECT_EQ(colorSpace, ColorSpace::DisplayP3);
     328
     329    auto [r, g, b, alpha] = components;
     330
     331    EXPECT_FLOAT_EQ(1.0, r);
     332    EXPECT_FLOAT_EQ(0.5, g);
     333    EXPECT_FLOAT_EQ(0.25, b);
     334    EXPECT_FLOAT_EQ(1.0, alpha);
     335    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
     336}
     337
     338TEST(Color, MoveAssignment)
     339{
     340    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     341    Color c2 = WTFMove(c1);
     342
     343    // We should have moved the out of line color pointer into c2,
     344    // and set c1 to invalid so that it doesn't cause deletion.
     345    EXPECT_FALSE(c1.isValid());
     346
     347    auto [colorSpace, components] = c2.colorSpaceAndComponents();
     348    EXPECT_EQ(colorSpace, ColorSpace::DisplayP3);
     349
     350    auto [r, g, b, alpha] = components;
     351
     352    EXPECT_FLOAT_EQ(1.0, r);
     353    EXPECT_FLOAT_EQ(0.5, g);
     354    EXPECT_FLOAT_EQ(0.25, b);
     355    EXPECT_FLOAT_EQ(1.0, alpha);
     356    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
     357}
     358
     359Color makeColor()
     360{
     361    return Color { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     362}
     363
     364TEST(Color, ReturnValues)
     365{
     366    Color c2 = makeColor();
     367    EXPECT_EQ(serializationForCSS(c2), "color(display-p3 1 0.5 0.25)");
     368}
     369
     370TEST(Color, P3ConversionToSRGB)
     371{
     372    Color p3Color { DisplayP3<float> { 1.0, 0.5, 0.25, 0.75 } };
     373    auto sRGBAColor = p3Color.toSRGBALossy<float>();
     374    EXPECT_FLOAT_EQ(sRGBAColor.red, 1.0f);
     375    EXPECT_FLOAT_EQ(sRGBAColor.green, 0.46253282f);
     376    EXPECT_FLOAT_EQ(sRGBAColor.blue, 0.14912748f);
     377    EXPECT_FLOAT_EQ(sRGBAColor.alpha, 0.75f);
     378}
     379
     380TEST(Color, LinearSRGBConversionToSRGB)
     381{
     382    Color linearSRGBAColor { LinearSRGBA<float> { 1.0, 0.5, 0.25, 0.75 } };
     383    auto sRGBAColor = linearSRGBAColor.toSRGBALossy<float>();
     384    EXPECT_FLOAT_EQ(sRGBAColor.red, 1.0f);
     385    EXPECT_FLOAT_EQ(sRGBAColor.green, 0.735356927f);
     386    EXPECT_FLOAT_EQ(sRGBAColor.blue, 0.537098706f);
     387    EXPECT_FLOAT_EQ(sRGBAColor.alpha, 0.75f);
     388}
     389
     390TEST(Color, ColorWithAlphaMultipliedBy)
     391{
     392    Color color { SRGBA<float> { 0., 0., 1., 0.6 } };
     393
     394    {
     395        Color colorWithAlphaMultipliedBy = color.colorWithAlphaMultipliedBy(1.);
     396        EXPECT_EQ(color, colorWithAlphaMultipliedBy);
     397    }
     398
     399    {
     400        Color colorWithAlphaMultipliedBy = color.colorWithAlphaMultipliedBy(0.5);
     401        auto [colorSpace, components] = colorWithAlphaMultipliedBy.colorSpaceAndComponents();
     402        EXPECT_EQ(colorSpace, ColorSpace::SRGB);
     403        auto [r, g, b, a] = components;
     404        EXPECT_FLOAT_EQ(r, 0.);
     405        EXPECT_FLOAT_EQ(g, 0.);
     406        EXPECT_FLOAT_EQ(b, 1.);
     407        EXPECT_FLOAT_EQ(a, 0.3);
     408    }
     409
     410    {
     411        Color colorWithAlphaMultipliedBy = color.colorWithAlphaMultipliedBy(0.);
     412        auto [colorSpace, components] = colorWithAlphaMultipliedBy.colorSpaceAndComponents();
     413        EXPECT_EQ(colorSpace, ColorSpace::SRGB);
     414        auto [r, g, b, a] = components;
     415        EXPECT_FLOAT_EQ(r, 0.);
     416        EXPECT_FLOAT_EQ(g, 0.);
     417        EXPECT_FLOAT_EQ(b, 1.);
     418        EXPECT_FLOAT_EQ(a, 0.);
     419    }
     420}
     421
    236422} // namespace TestWebKitAPI
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/DisplayListTests.cpp

    r271757 r273776  
    153153
    154154        auto& item = handle->get<FillRectWithColor>();
    155         EXPECT_EQ(item.color().asInline(), Color::black);
     155        EXPECT_EQ(*item.color().tryGetAsSRGBABytes(), Color::black);
    156156        EXPECT_EQ(item.rect(), FloatRect(0, 0, 100, 100));
    157157    }
Note: See TracChangeset for help on using the changeset viewer.