Revert "Fully embrace skcms types in SkColorSpace API"
This reverts commit 701522798a
.
Reason for revert: Maybe blocking the Android roll
Original change's description:
> Fully embrace skcms types in SkColorSpace API
>
> Remove the SkMatrix44 getter entirely.
>
> Change-Id: I25bfe68a7a9b21d8a8696415b517cb79fc2d7a94
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/252596
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Mike Klein <mtklein@google.com>
TBR=mtklein@google.com,brianosman@google.com,reed@google.com
Change-Id: Ic277d54d4ac8c84f00405946c927a3aee4e33068
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/252801
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
cfa4f60270
commit
6af9b1c673
@ -8,10 +8,6 @@ Milestone 80
|
||||
|
||||
<Insert new notes here- top is most recent.>
|
||||
|
||||
* Removed SkMatrix44 version of toXYZD50 from SkColorSpace. Switched to skcms types in
|
||||
transferFn, invTrasnferFn, and gamutTransformTo functions.
|
||||
https://review.skia.org/252596
|
||||
|
||||
* Removed rotation and YUV support from SkColorMatrix
|
||||
https://review.skia.org/252188
|
||||
|
||||
|
@ -1237,7 +1237,7 @@ struct Task {
|
||||
};
|
||||
|
||||
skcms_TransferFunction tf;
|
||||
cs->transferFn(&tf);
|
||||
cs->transferFn(&tf.g);
|
||||
switch (classify_transfer_fn(tf)) {
|
||||
case sRGBish_TF:
|
||||
if (tf.a == 1 && tf.b == 0 && tf.c == 0 && tf.d == 0 && tf.e == 0 && tf.f == 0) {
|
||||
|
@ -151,6 +151,8 @@ public:
|
||||
* Returns true and sets |toXYZD50| if the color gamut can be described as a matrix.
|
||||
* Returns false otherwise.
|
||||
*/
|
||||
bool toXYZD50(SkMatrix44* toXYZD50) const;
|
||||
|
||||
bool toXYZD50(skcms_Matrix3x3* toXYZD50) const;
|
||||
|
||||
/**
|
||||
@ -217,9 +219,9 @@ public:
|
||||
*/
|
||||
static bool Equals(const SkColorSpace*, const SkColorSpace*);
|
||||
|
||||
void transferFn(skcms_TransferFunction* fn) const;
|
||||
void invTransferFn(skcms_TransferFunction* fn) const;
|
||||
void gamutTransformTo(const SkColorSpace* dst, skcms_Matrix3x3* src_to_dst) const;
|
||||
void transferFn(float gabcdef[7]) const;
|
||||
void invTransferFn(float gabcdef[7]) const;
|
||||
void gamutTransformTo(const SkColorSpace* dst, float src_to_dst_row_major[9]) const;
|
||||
|
||||
uint32_t transferFnHash() const { return fTransferFnHash; }
|
||||
uint64_t hash() const { return (uint64_t)fTransferFnHash << 32 | fToXYZD50Hash; }
|
||||
@ -227,18 +229,19 @@ public:
|
||||
private:
|
||||
friend class SkColorSpaceSingletonFactory;
|
||||
|
||||
SkColorSpace(const skcms_TransferFunction& transferFn, const skcms_Matrix3x3& toXYZ);
|
||||
SkColorSpace(const float transferFn[7],
|
||||
const skcms_Matrix3x3& toXYZ);
|
||||
|
||||
void computeLazyDstFields() const;
|
||||
|
||||
uint32_t fTransferFnHash;
|
||||
uint32_t fToXYZD50Hash;
|
||||
|
||||
skcms_TransferFunction fTransferFn;
|
||||
skcms_Matrix3x3 fToXYZD50;
|
||||
float fTransferFn[7];
|
||||
float fToXYZD50_3x3[9]; // row-major
|
||||
|
||||
mutable skcms_TransferFunction fInvTransferFn;
|
||||
mutable skcms_Matrix3x3 fFromXYZD50;
|
||||
mutable float fInvTransferFn[7];
|
||||
mutable float fFromXYZD50_3x3[9]; // row-major
|
||||
mutable SkOnce fLazyDstFieldsOnce;
|
||||
};
|
||||
|
||||
|
@ -15,12 +15,13 @@ bool SkColorSpacePrimaries::toXYZD50(skcms_Matrix3x3* toXYZ_D50) const {
|
||||
return skcms_PrimariesToXYZD50(fRX, fRY, fGX, fGY, fBX, fBY, fWX, fWY, toXYZ_D50);
|
||||
}
|
||||
|
||||
SkColorSpace::SkColorSpace(const skcms_TransferFunction& transferFn,
|
||||
const skcms_Matrix3x3& toXYZD50)
|
||||
: fTransferFn(transferFn)
|
||||
, fToXYZD50(toXYZD50) {
|
||||
fTransferFnHash = SkOpts::hash_fn(&fTransferFn, 7*sizeof(float), 0);
|
||||
fToXYZD50Hash = SkOpts::hash_fn(&fToXYZD50, 9*sizeof(float), 0);
|
||||
SkColorSpace::SkColorSpace(const float transferFn[7],
|
||||
const skcms_Matrix3x3& toXYZD50) {
|
||||
memcpy(fToXYZD50_3x3, &toXYZD50.vals[0][0], 9*sizeof(float));
|
||||
fToXYZD50Hash = SkOpts::hash_fn(fToXYZD50_3x3, 9*sizeof(float), 0);
|
||||
|
||||
memcpy(fTransferFn, transferFn, 7*sizeof(float));
|
||||
fTransferFnHash = SkOpts::hash_fn(fTransferFn, 7*sizeof(float), 0);
|
||||
}
|
||||
|
||||
static bool xyz_almost_equal(const skcms_Matrix3x3& mA, const skcms_Matrix3x3& mB) {
|
||||
@ -41,30 +42,30 @@ sk_sp<SkColorSpace> SkColorSpace::MakeRGB(const skcms_TransferFunction& transfer
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const skcms_TransferFunction* tf = &transferFn;
|
||||
const float* tf = &transferFn.g;
|
||||
|
||||
if (is_almost_srgb(transferFn)) {
|
||||
if (xyz_almost_equal(toXYZ, SkNamedGamut::kSRGB)) {
|
||||
return SkColorSpace::MakeSRGB();
|
||||
}
|
||||
tf = &SkNamedTransferFn::kSRGB;
|
||||
tf = &SkNamedTransferFn::kSRGB.g;
|
||||
} else if (is_almost_2dot2(transferFn)) {
|
||||
tf = &SkNamedTransferFn::k2Dot2;
|
||||
tf = &SkNamedTransferFn::k2Dot2.g;
|
||||
} else if (is_almost_linear(transferFn)) {
|
||||
if (xyz_almost_equal(toXYZ, SkNamedGamut::kSRGB)) {
|
||||
return SkColorSpace::MakeSRGBLinear();
|
||||
}
|
||||
tf = &SkNamedTransferFn::kLinear;
|
||||
tf = &SkNamedTransferFn::kLinear.g;
|
||||
}
|
||||
|
||||
return sk_sp<SkColorSpace>(new SkColorSpace(*tf, toXYZ));
|
||||
return sk_sp<SkColorSpace>(new SkColorSpace(tf, toXYZ));
|
||||
}
|
||||
|
||||
class SkColorSpaceSingletonFactory {
|
||||
public:
|
||||
static SkColorSpace* Make(const skcms_TransferFunction& transferFn,
|
||||
const skcms_Matrix3x3& to_xyz) {
|
||||
return new SkColorSpace(transferFn, to_xyz);
|
||||
return new SkColorSpace(&transferFn.g, to_xyz);
|
||||
}
|
||||
};
|
||||
|
||||
@ -93,17 +94,22 @@ void SkColorSpace::computeLazyDstFields() const {
|
||||
|
||||
// Invert 3x3 gamut, defaulting to sRGB if we can't.
|
||||
{
|
||||
if (!skcms_Matrix3x3_invert(&fToXYZD50, &fFromXYZD50)) {
|
||||
SkAssertResult(skcms_Matrix3x3_invert(&skcms_sRGB_profile()->toXYZD50,
|
||||
&fFromXYZD50));
|
||||
skcms_Matrix3x3 fwd, inv;
|
||||
memcpy(&fwd, fToXYZD50_3x3, 9*sizeof(float));
|
||||
if (!skcms_Matrix3x3_invert(&fwd, &inv)) {
|
||||
SkAssertResult(skcms_Matrix3x3_invert(&skcms_sRGB_profile()->toXYZD50, &inv));
|
||||
}
|
||||
memcpy(fFromXYZD50_3x3, &inv, 9*sizeof(float));
|
||||
}
|
||||
|
||||
// Invert transfer function, defaulting to sRGB if we can't.
|
||||
{
|
||||
if (!skcms_TransferFunction_invert(&fTransferFn, &fInvTransferFn)) {
|
||||
fInvTransferFn = *skcms_sRGB_Inverse_TransferFunction();
|
||||
skcms_TransferFunction fwd, inv;
|
||||
this->transferFn(&fwd.g);
|
||||
if (!skcms_TransferFunction_invert(&fwd, &inv)) {
|
||||
inv = *skcms_sRGB_Inverse_TransferFunction();
|
||||
}
|
||||
memcpy(fInvTransferFn, &inv, 7*sizeof(float));
|
||||
}
|
||||
|
||||
});
|
||||
@ -113,27 +119,40 @@ bool SkColorSpace::isNumericalTransferFn(skcms_TransferFunction* coeffs) const {
|
||||
// TODO: Change transferFn/invTransferFn to just operate on skcms_TransferFunction (all callers
|
||||
// already pass pointers to an skcms struct). Then remove this function, and update the two
|
||||
// remaining callers to do the right thing with transferFn and classify.
|
||||
this->transferFn(coeffs);
|
||||
this->transferFn(&coeffs->g);
|
||||
return classify_transfer_fn(*coeffs) == sRGBish_TF;
|
||||
}
|
||||
|
||||
void SkColorSpace::transferFn(skcms_TransferFunction* fn) const {
|
||||
*fn = fTransferFn;
|
||||
void SkColorSpace::transferFn(float gabcdef[7]) const {
|
||||
memcpy(gabcdef, &fTransferFn, 7*sizeof(float));
|
||||
}
|
||||
|
||||
void SkColorSpace::invTransferFn(skcms_TransferFunction* fn) const {
|
||||
void SkColorSpace::invTransferFn(float gabcdef[7]) const {
|
||||
this->computeLazyDstFields();
|
||||
*fn = fInvTransferFn;
|
||||
memcpy(gabcdef, &fInvTransferFn, 7*sizeof(float));
|
||||
}
|
||||
|
||||
bool SkColorSpace::toXYZD50(skcms_Matrix3x3* toXYZD50) const {
|
||||
*toXYZD50 = fToXYZD50;
|
||||
bool SkColorSpace::toXYZD50(SkMatrix44* toXYZD50) const {
|
||||
toXYZD50->set3x3RowMajorf(fToXYZD50_3x3);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkColorSpace::gamutTransformTo(const SkColorSpace* dst, skcms_Matrix3x3* src_to_dst) const {
|
||||
bool SkColorSpace::toXYZD50(skcms_Matrix3x3* toXYZD50) const {
|
||||
memcpy(toXYZD50, fToXYZD50_3x3, 9*sizeof(float));
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkColorSpace::gamutTransformTo(const SkColorSpace* dst, float src_to_dst[9]) const {
|
||||
dst->computeLazyDstFields();
|
||||
*src_to_dst = skcms_Matrix3x3_concat(&dst->fFromXYZD50, &fToXYZD50);
|
||||
|
||||
skcms_Matrix3x3 toXYZD50,
|
||||
fromXYZD50;
|
||||
|
||||
memcpy(& toXYZD50, this-> fToXYZD50_3x3, 9*sizeof(float));
|
||||
memcpy(&fromXYZD50, dst ->fFromXYZD50_3x3, 9*sizeof(float));
|
||||
|
||||
skcms_Matrix3x3 srcToDst = skcms_Matrix3x3_concat(&fromXYZD50, &toXYZD50);
|
||||
memcpy(src_to_dst, &srcToDst, 9*sizeof(float));
|
||||
}
|
||||
|
||||
bool SkColorSpace::isSRGB() const {
|
||||
@ -142,26 +161,30 @@ bool SkColorSpace::isSRGB() const {
|
||||
|
||||
bool SkColorSpace::gammaCloseToSRGB() const {
|
||||
// Nearly-equal transfer functions were snapped at construction time, so just do an exact test
|
||||
return memcmp(&fTransferFn, &SkNamedTransferFn::kSRGB, 7*sizeof(float)) == 0;
|
||||
return memcmp(fTransferFn, &SkNamedTransferFn::kSRGB.g, 7*sizeof(float)) == 0;
|
||||
}
|
||||
|
||||
bool SkColorSpace::gammaIsLinear() const {
|
||||
// Nearly-equal transfer functions were snapped at construction time, so just do an exact test
|
||||
return memcmp(&fTransferFn, &SkNamedTransferFn::kLinear, 7*sizeof(float)) == 0;
|
||||
return memcmp(fTransferFn, &SkNamedTransferFn::kLinear.g, 7*sizeof(float)) == 0;
|
||||
}
|
||||
|
||||
sk_sp<SkColorSpace> SkColorSpace::makeLinearGamma() const {
|
||||
if (this->gammaIsLinear()) {
|
||||
return sk_ref_sp(const_cast<SkColorSpace*>(this));
|
||||
}
|
||||
return SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, fToXYZD50);
|
||||
skcms_Matrix3x3 gamut;
|
||||
this->toXYZD50(&gamut);
|
||||
return SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, gamut);
|
||||
}
|
||||
|
||||
sk_sp<SkColorSpace> SkColorSpace::makeSRGBGamma() const {
|
||||
if (this->gammaCloseToSRGB()) {
|
||||
return sk_ref_sp(const_cast<SkColorSpace*>(this));
|
||||
}
|
||||
return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, fToXYZD50);
|
||||
skcms_Matrix3x3 gamut;
|
||||
this->toXYZD50(&gamut);
|
||||
return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, gamut);
|
||||
}
|
||||
|
||||
sk_sp<SkColorSpace> SkColorSpace::makeColorSpin() const {
|
||||
@ -171,15 +194,24 @@ sk_sp<SkColorSpace> SkColorSpace::makeColorSpin() const {
|
||||
{ 0, 1, 0 },
|
||||
}};
|
||||
|
||||
skcms_Matrix3x3 spun = skcms_Matrix3x3_concat(&fToXYZD50, &spin);
|
||||
skcms_Matrix3x3 toXYZ;
|
||||
this->toXYZD50(&toXYZ);
|
||||
|
||||
skcms_Matrix3x3 spun = skcms_Matrix3x3_concat(&toXYZ, &spin);
|
||||
|
||||
return sk_sp<SkColorSpace>(new SkColorSpace(fTransferFn, spun));
|
||||
}
|
||||
|
||||
void SkColorSpace::toProfile(skcms_ICCProfile* profile) const {
|
||||
skcms_TransferFunction tf;
|
||||
skcms_Matrix3x3 toXYZD50;
|
||||
|
||||
memcpy(&tf, fTransferFn, 7*sizeof(float));
|
||||
memcpy(&toXYZD50, fToXYZD50_3x3, 9*sizeof(float));
|
||||
|
||||
skcms_Init (profile);
|
||||
skcms_SetTransferFunction(profile, &fTransferFn);
|
||||
skcms_SetXYZD50 (profile, &fToXYZD50);
|
||||
skcms_SetTransferFunction(profile, &tf);
|
||||
skcms_SetXYZD50 (profile, &toXYZD50);
|
||||
}
|
||||
|
||||
sk_sp<SkColorSpace> SkColorSpace::Make(const skcms_ICCProfile& profile) {
|
||||
@ -257,10 +289,10 @@ size_t SkColorSpace::writeToMemory(void* memory) const {
|
||||
*((ColorSpaceHeader*) memory) = ColorSpaceHeader();
|
||||
memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader));
|
||||
|
||||
memcpy(memory, &fTransferFn, 7 * sizeof(float));
|
||||
memcpy(memory, fTransferFn, 7 * sizeof(float));
|
||||
memory = SkTAddOffset<void>(memory, 7 * sizeof(float));
|
||||
|
||||
memcpy(memory, &fToXYZD50, 9 * sizeof(float));
|
||||
memcpy(memory, fToXYZD50_3x3, 9 * sizeof(float));
|
||||
}
|
||||
|
||||
return sizeof(ColorSpaceHeader) + 16 * sizeof(float);
|
||||
@ -376,12 +408,10 @@ bool SkColorSpace::Equals(const SkColorSpace* x, const SkColorSpace* y) {
|
||||
|
||||
if (x->hash() == y->hash()) {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
SkASSERT((&x->fTransferFn.g)[i] == (&y->fTransferFn.g)[i] && "Hash collsion");
|
||||
SkASSERT(x-> fTransferFn[i] == y-> fTransferFn[i] && "Hash collsion");
|
||||
}
|
||||
for (int r = 0; r < 3; r++) {
|
||||
for (int c = 0; c < 3; ++c) {
|
||||
SkASSERT(x->fToXYZD50.vals[r][c] == y->fToXYZD50.vals[r][c] && "Hash collsion");
|
||||
}
|
||||
for (int i = 0; i < 9; i++) {
|
||||
SkASSERT(x->fToXYZD50_3x3[i] == y->fToXYZD50_3x3[i] && "Hash collsion");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -45,20 +45,20 @@ SkColorSpaceXformSteps::SkColorSpaceXformSteps(SkColorSpace* src, SkAlphaType sr
|
||||
this->flags.premul = srcAT != kOpaque_SkAlphaType && dstAT == kPremul_SkAlphaType;
|
||||
|
||||
if (this->flags.gamut_transform) {
|
||||
skcms_Matrix3x3 src_to_dst; // TODO: switch src_to_dst_matrix to row-major
|
||||
src->gamutTransformTo(dst, &src_to_dst);
|
||||
float row_major[9]; // TODO: switch src_to_dst_matrix to row-major
|
||||
src->gamutTransformTo(dst, row_major);
|
||||
|
||||
this->src_to_dst_matrix[0] = src_to_dst.vals[0][0];
|
||||
this->src_to_dst_matrix[1] = src_to_dst.vals[1][0];
|
||||
this->src_to_dst_matrix[2] = src_to_dst.vals[2][0];
|
||||
this->src_to_dst_matrix[0] = row_major[0];
|
||||
this->src_to_dst_matrix[1] = row_major[3];
|
||||
this->src_to_dst_matrix[2] = row_major[6];
|
||||
|
||||
this->src_to_dst_matrix[3] = src_to_dst.vals[0][1];
|
||||
this->src_to_dst_matrix[4] = src_to_dst.vals[1][1];
|
||||
this->src_to_dst_matrix[5] = src_to_dst.vals[2][1];
|
||||
this->src_to_dst_matrix[3] = row_major[1];
|
||||
this->src_to_dst_matrix[4] = row_major[4];
|
||||
this->src_to_dst_matrix[5] = row_major[7];
|
||||
|
||||
this->src_to_dst_matrix[6] = src_to_dst.vals[0][2];
|
||||
this->src_to_dst_matrix[7] = src_to_dst.vals[1][2];
|
||||
this->src_to_dst_matrix[8] = src_to_dst.vals[2][2];
|
||||
this->src_to_dst_matrix[6] = row_major[2];
|
||||
this->src_to_dst_matrix[7] = row_major[5];
|
||||
this->src_to_dst_matrix[8] = row_major[8];
|
||||
} else {
|
||||
#ifdef SK_DEBUG
|
||||
skcms_Matrix3x3 srcM, dstM;
|
||||
@ -69,8 +69,8 @@ SkColorSpaceXformSteps::SkColorSpaceXformSteps(SkColorSpace* src, SkAlphaType sr
|
||||
}
|
||||
|
||||
// Fill out all the transfer functions we'll use.
|
||||
src-> transferFn(&this->srcTF );
|
||||
dst->invTransferFn(&this->dstTFInv);
|
||||
src-> transferFn(&this->srcTF .g);
|
||||
dst->invTransferFn(&this->dstTFInv.g);
|
||||
|
||||
this->srcTF_is_sRGB = src->gammaCloseToSRGB();
|
||||
this->dstTF_is_sRGB = dst->gammaCloseToSRGB();
|
||||
@ -82,10 +82,10 @@ SkColorSpaceXformSteps::SkColorSpaceXformSteps(SkColorSpace* src, SkAlphaType sr
|
||||
src->transferFnHash() == dst->transferFnHash())
|
||||
{
|
||||
#ifdef SK_DEBUG
|
||||
skcms_TransferFunction dstTF;
|
||||
dst->transferFn(&dstTF);
|
||||
float dstTF[7];
|
||||
dst->transferFn(dstTF);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
SkASSERT( (&srcTF.g)[i] == (&dstTF.g)[i] && "Hash collision" );
|
||||
SkASSERT( (&srcTF.g)[i] == dstTF[i] && "Hash collision" );
|
||||
}
|
||||
#endif
|
||||
this->flags.linearize = false;
|
||||
|
@ -66,7 +66,7 @@ bool SkHighContrast_Filter::onAppendStages(const SkStageRec& rec, bool shaderIsO
|
||||
// Linearize before applying high-contrast filter.
|
||||
auto tf = alloc->make<skcms_TransferFunction>();
|
||||
if (rec.fDstCS) {
|
||||
rec.fDstCS->transferFn(tf);
|
||||
rec.fDstCS->transferFn(&tf->g);
|
||||
} else {
|
||||
// Historically we approximate untagged destinations as gamma 2.
|
||||
// TODO: sRGB?
|
||||
@ -115,7 +115,7 @@ bool SkHighContrast_Filter::onAppendStages(const SkStageRec& rec, bool shaderIsO
|
||||
// Re-encode back from linear.
|
||||
auto invTF = alloc->make<skcms_TransferFunction>();
|
||||
if (rec.fDstCS) {
|
||||
rec.fDstCS->invTransferFn(invTF);
|
||||
rec.fDstCS->invTransferFn(&invTF->g);
|
||||
} else {
|
||||
// See above... historically untagged == gamma 2 in this filter.
|
||||
*invTF ={0.5f,1, 0,0,0,0,0};
|
||||
|
Loading…
Reference in New Issue
Block a user