| Index: src/core/SkColorSpace.cpp
|
| diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp
|
| index b956c7fe3e342255641a64f9530538c0a68e9c0c..e90254c969eee6746b5b5d8d95b89f68047edb0d 100644
|
| --- a/src/core/SkColorSpace.cpp
|
| +++ b/src/core/SkColorSpace.cpp
|
| @@ -7,8 +7,8 @@
|
|
|
| #include "SkColorSpace.h"
|
| #include "SkColorSpace_Base.h"
|
| +#include "SkColorSpace_XYZ.h"
|
| #include "SkColorSpacePriv.h"
|
| -#include "SkColorSpaceXform_Base.h"
|
| #include "SkOnce.h"
|
| #include "SkPoint3.h"
|
|
|
| @@ -83,23 +83,8 @@ bool SkColorSpacePrimaries::toXYZD50(SkMatrix44* toXYZ_D50) const {
|
|
|
| ///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
| -SkColorSpace_Base::SkColorSpace_Base(SkGammaNamed gammaNamed, const SkMatrix44& toXYZD50)
|
| - : fGammaNamed(gammaNamed)
|
| - , fGammas(nullptr)
|
| - , fProfileData(nullptr)
|
| - , fToXYZD50(toXYZD50)
|
| - , fFromXYZD50(SkMatrix44::kUninitialized_Constructor)
|
| -{}
|
| -
|
| -SkColorSpace_Base::SkColorSpace_Base(sk_sp<SkColorLookUpTable> colorLUT, SkGammaNamed gammaNamed,
|
| - sk_sp<SkGammas> gammas, const SkMatrix44& toXYZD50,
|
| - sk_sp<SkData> profileData)
|
| - : fColorLUT(std::move(colorLUT))
|
| - , fGammaNamed(gammaNamed)
|
| - , fGammas(std::move(gammas))
|
| - , fProfileData(std::move(profileData))
|
| - , fToXYZD50(toXYZD50)
|
| - , fFromXYZD50(SkMatrix44::kUninitialized_Constructor)
|
| +SkColorSpace_Base::SkColorSpace_Base(sk_sp<SkData> profileData)
|
| + : fProfileData(std::move(profileData))
|
| {}
|
|
|
| static constexpr float gSRGB_toXYZD50[] {
|
| @@ -163,8 +148,8 @@ sk_sp<SkColorSpace> SkColorSpace::NewRGB(const float values[3], const SkMatrix44
|
| gammas->fRedData.fValue = values[0];
|
| gammas->fGreenData.fValue = values[1];
|
| gammas->fBlueData.fValue = values[2];
|
| - return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr, kNonStandard_SkGammaNamed, gammas,
|
| - toXYZD50, nullptr));
|
| + return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(kNonStandard_SkGammaNamed,
|
| + gammas, toXYZD50, nullptr));
|
| }
|
|
|
| return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50);
|
| @@ -194,7 +179,7 @@ sk_sp<SkColorSpace> SkColorSpace_Base::NewRGB(SkGammaNamed gammaNamed, const SkM
|
| break;
|
| }
|
|
|
| - return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammaNamed, toXYZD50));
|
| + return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(gammaNamed, toXYZD50));
|
| }
|
|
|
| sk_sp<SkColorSpace> SkColorSpace::NewRGB(RenderTargetGamma gamma, const SkMatrix44& toXYZD50) {
|
| @@ -235,8 +220,8 @@ sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkColorSpaceTransferFn& coeffs,
|
| gammas->fRedData = data;
|
| gammas->fGreenData = data;
|
| gammas->fBlueData = data;
|
| - return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr, kNonStandard_SkGammaNamed,
|
| - std::move(gammas), toXYZD50, nullptr));
|
| + return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(kNonStandard_SkGammaNamed,
|
| + std::move(gammas), toXYZD50, nullptr));
|
| }
|
|
|
| static SkColorSpace* gAdobeRGB;
|
| @@ -256,7 +241,7 @@ sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
|
|
|
| // Force the mutable type mask to be computed. This avoids races.
|
| (void)srgbToxyzD50.getType();
|
| - gSRGB = new SkColorSpace_Base(kSRGB_SkGammaNamed, srgbToxyzD50);
|
| + gSRGB = new SkColorSpace_XYZ(kSRGB_SkGammaNamed, srgbToxyzD50);
|
| });
|
| return sk_ref_sp<SkColorSpace>(gSRGB);
|
| }
|
| @@ -267,7 +252,7 @@ sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
|
|
|
| // Force the mutable type mask to be computed. This avoids races.
|
| (void)adobergbToxyzD50.getType();
|
| - gAdobeRGB = new SkColorSpace_Base(k2Dot2Curve_SkGammaNamed, adobergbToxyzD50);
|
| + gAdobeRGB = new SkColorSpace_XYZ(k2Dot2Curve_SkGammaNamed, adobergbToxyzD50);
|
| });
|
| return sk_ref_sp<SkColorSpace>(gAdobeRGB);
|
| }
|
| @@ -278,7 +263,7 @@ sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
|
|
|
| // Force the mutable type mask to be computed. This avoids races.
|
| (void)srgbToxyzD50.getType();
|
| - gSRGBLinear = new SkColorSpace_Base(kLinear_SkGammaNamed, srgbToxyzD50);
|
| + gSRGBLinear = new SkColorSpace_XYZ(kLinear_SkGammaNamed, srgbToxyzD50);
|
| });
|
| return sk_ref_sp<SkColorSpace>(gSRGBLinear);
|
| }
|
| @@ -288,53 +273,14 @@ sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
|
| return nullptr;
|
| }
|
|
|
| -sk_sp<SkColorSpace> SkColorSpace_Base::makeLinearGamma() {
|
| - if (this->gammaIsLinear()) {
|
| - return sk_ref_sp(this);
|
| - }
|
| - return SkColorSpace_Base::NewRGB(kLinear_SkGammaNamed, as_CSB(this)->fToXYZD50);
|
| -}
|
| -
|
| ///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
| bool SkColorSpace::gammaCloseToSRGB() const {
|
| - return kSRGB_SkGammaNamed == as_CSB(this)->fGammaNamed ||
|
| - k2Dot2Curve_SkGammaNamed == as_CSB(this)->fGammaNamed;
|
| + return as_CSB(this)->onGammaCloseToSRGB();
|
| }
|
|
|
| bool SkColorSpace::gammaIsLinear() const {
|
| - return kLinear_SkGammaNamed == as_CSB(this)->fGammaNamed;
|
| -}
|
| -
|
| -const SkMatrix44& SkColorSpace_Base::fromXYZD50() const {
|
| - fFromXYZOnce([this] {
|
| - if (!fToXYZD50.invert(&fFromXYZD50)) {
|
| - // If a client gives us a dst gamut with a transform that we can't invert, we will
|
| - // simply give them back a transform to sRGB gamut.
|
| - SkDEBUGFAIL("Non-invertible XYZ matrix, defaulting to sRGB");
|
| - SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor);
|
| - srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50);
|
| - srgbToxyzD50.invert(&fFromXYZD50);
|
| - }
|
| - });
|
| - return fFromXYZD50;
|
| -}
|
| -
|
| -void SkColorSpace_Base::toDstGammaTables(const uint8_t* tables[3], sk_sp<SkData>* storage,
|
| - int numTables) const {
|
| - fToDstGammaOnce([this, numTables] {
|
| - const bool gammasAreMatching = numTables <= 1;
|
| - fDstStorage =
|
| - SkData::MakeUninitialized(numTables * SkColorSpaceXform_Base::kDstGammaTableSize);
|
| - SkColorSpaceXform_Base::BuildDstGammaTables(fToDstGammaTables,
|
| - (uint8_t*) fDstStorage->writable_data(), this,
|
| - gammasAreMatching);
|
| - });
|
| -
|
| - *storage = fDstStorage;
|
| - tables[0] = fToDstGammaTables[0];
|
| - tables[1] = fToDstGammaTables[1];
|
| - tables[2] = fToDstGammaTables[2];
|
| + return as_CSB(this)->onGammaIsLinear();
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| @@ -403,51 +349,52 @@ size_t SkColorSpace::writeToMemory(void* memory) const {
|
| // Start by trying the serialization fast path. If we haven't saved ICC profile data,
|
| // we must have a profile that we can serialize easily.
|
| if (!as_CSB(this)->fProfileData) {
|
| + // Profile data is mandatory for A2B0 color spaces.
|
| + SkASSERT(SkColorSpace_Base::Type::kXYZ == as_CSB(this)->type());
|
| + const SkColorSpace_XYZ* thisXYZ = static_cast<const SkColorSpace_XYZ*>(this);
|
| // If we have a named profile, only write the enum.
|
| + const SkGammaNamed gammaNamed = thisXYZ->gammaNamed();
|
| if (this == gSRGB) {
|
| if (memory) {
|
| *((ColorSpaceHeader*) memory) =
|
| - ColorSpaceHeader::Pack(k0_Version, kSRGB_Named,
|
| - as_CSB(this)->fGammaNamed, 0);
|
| + ColorSpaceHeader::Pack(k0_Version, kSRGB_Named, gammaNamed, 0);
|
| }
|
| return sizeof(ColorSpaceHeader);
|
| } else if (this == gAdobeRGB) {
|
| if (memory) {
|
| *((ColorSpaceHeader*) memory) =
|
| - ColorSpaceHeader::Pack(k0_Version, kAdobeRGB_Named,
|
| - as_CSB(this)->fGammaNamed, 0);
|
| + ColorSpaceHeader::Pack(k0_Version, kAdobeRGB_Named, gammaNamed, 0);
|
| }
|
| return sizeof(ColorSpaceHeader);
|
| } else if (this == gSRGBLinear) {
|
| if (memory) {
|
| - *((ColorSpaceHeader*)memory) =
|
| - ColorSpaceHeader::Pack(k0_Version, kSRGBLinear_Named,
|
| - as_CSB(this)->fGammaNamed, 0);
|
| + *((ColorSpaceHeader*) memory) =
|
| + ColorSpaceHeader::Pack(k0_Version, kSRGBLinear_Named, gammaNamed, 0);
|
| }
|
| return sizeof(ColorSpaceHeader);
|
| }
|
|
|
| // If we have a named gamma, write the enum and the matrix.
|
| - switch (as_CSB(this)->fGammaNamed) {
|
| + switch (gammaNamed) {
|
| case kSRGB_SkGammaNamed:
|
| case k2Dot2Curve_SkGammaNamed:
|
| case kLinear_SkGammaNamed: {
|
| if (memory) {
|
| *((ColorSpaceHeader*) memory) =
|
| - ColorSpaceHeader::Pack(k0_Version, 0, as_CSB(this)->fGammaNamed,
|
| + ColorSpaceHeader::Pack(k0_Version, 0, gammaNamed,
|
| ColorSpaceHeader::kMatrix_Flag);
|
| memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader));
|
| - as_CSB(this)->fToXYZD50.as3x4RowMajorf((float*) memory);
|
| + thisXYZ->toXYZD50()->as3x4RowMajorf((float*) memory);
|
| }
|
| return sizeof(ColorSpaceHeader) + 12 * sizeof(float);
|
| }
|
| default:
|
| - const SkGammas* gammas = as_CSB(this)->gammas();
|
| + const SkGammas* gammas = thisXYZ->gammas();
|
| SkASSERT(gammas);
|
| if (gammas->isValue(0) && gammas->isValue(1) && gammas->isValue(2)) {
|
| if (memory) {
|
| *((ColorSpaceHeader*) memory) =
|
| - ColorSpaceHeader::Pack(k0_Version, 0, as_CSB(this)->fGammaNamed,
|
| + ColorSpaceHeader::Pack(k0_Version, 0, thisXYZ->fGammaNamed,
|
| ColorSpaceHeader::kFloatGamma_Flag);
|
| memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader));
|
|
|
| @@ -456,7 +403,7 @@ size_t SkColorSpace::writeToMemory(void* memory) const {
|
| *(((float*) memory) + 2) = gammas->fBlueData.fValue;
|
| memory = SkTAddOffset<void>(memory, 3 * sizeof(float));
|
|
|
| - as_CSB(this)->fToXYZD50.as3x4RowMajorf((float*) memory);
|
| + thisXYZ->fToXYZD50.as3x4RowMajorf((float*) memory);
|
| }
|
|
|
| return sizeof(ColorSpaceHeader) + 15 * sizeof(float);
|
| @@ -469,7 +416,7 @@ size_t SkColorSpace::writeToMemory(void* memory) const {
|
|
|
| if (memory) {
|
| *((ColorSpaceHeader*) memory) =
|
| - ColorSpaceHeader::Pack(k0_Version, 0, as_CSB(this)->fGammaNamed,
|
| + ColorSpaceHeader::Pack(k0_Version, 0, thisXYZ->fGammaNamed,
|
| ColorSpaceHeader::kTransferFn_Flag);
|
| memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader));
|
|
|
| @@ -482,7 +429,7 @@ size_t SkColorSpace::writeToMemory(void* memory) const {
|
| *(((float*) memory) + 6) = gammas->params(0).fG;
|
| memory = SkTAddOffset<void>(memory, 7 * sizeof(float));
|
|
|
| - as_CSB(this)->fToXYZD50.as3x4RowMajorf((float*) memory);
|
| + thisXYZ->fToXYZD50.as3x4RowMajorf((float*) memory);
|
| }
|
|
|
| return sizeof(ColorSpaceHeader) + 19 * sizeof(float);
|
| @@ -624,23 +571,26 @@ bool SkColorSpace::Equals(const SkColorSpace* src, const SkColorSpace* dst) {
|
| return false;
|
| }
|
|
|
| - // It's important to check fProfileData before named gammas. Some profiles may have named
|
| - // gammas, but also include other wacky features that cause us to save the data.
|
| - switch (as_CSB(src)->fGammaNamed) {
|
| + // profiles are mandatory for A2B0 color spaces
|
| + SkASSERT(as_CSB(src)->type() == SkColorSpace_Base::Type::kXYZ);
|
| + const SkColorSpace_XYZ* srcXYZ = static_cast<const SkColorSpace_XYZ*>(src);
|
| + const SkColorSpace_XYZ* dstXYZ = static_cast<const SkColorSpace_XYZ*>(dst);
|
| +
|
| + switch (srcXYZ->gammaNamed()) {
|
| case kSRGB_SkGammaNamed:
|
| case k2Dot2Curve_SkGammaNamed:
|
| case kLinear_SkGammaNamed:
|
| - return (as_CSB(src)->fGammaNamed == as_CSB(dst)->fGammaNamed) &&
|
| - (as_CSB(src)->fToXYZD50 == as_CSB(dst)->fToXYZD50);
|
| + return (srcXYZ->gammaNamed() == dstXYZ->gammaNamed()) &&
|
| + (*srcXYZ->toXYZD50() == *dstXYZ->toXYZD50());
|
| default:
|
| - if (as_CSB(src)->fGammaNamed != as_CSB(dst)->fGammaNamed) {
|
| + if (srcXYZ->gammaNamed() != dstXYZ->gammaNamed()) {
|
| return false;
|
| }
|
| -
|
| // It is unlikely that we will reach this case.
|
| - sk_sp<SkData> srcData = src->serialize();
|
| - sk_sp<SkData> dstData = dst->serialize();
|
| - return srcData->size() == dstData->size() &&
|
| - 0 == memcmp(srcData->data(), dstData->data(), srcData->size());
|
| + sk_sp<SkData> serializedSrcData = src->serialize();
|
| + sk_sp<SkData> serializedDstData = dst->serialize();
|
| + return serializedSrcData->size() == serializedDstData->size() &&
|
| + 0 == memcmp(serializedSrcData->data(), serializedDstData->data(),
|
| + serializedSrcData->size());
|
| }
|
| }
|
|
|