Added kSRGBLinear_Named color space, along with tests
Gradients (and other shaders) are going to end up serializing this particular color space very frequently, so we want a shorthand way of writing it out. I think it's also helpful to have a clearer way of creating it (vs. NewNamed(kSRGB_Named)->makeLinearGamma()). BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2377763002 Review-Url: https://codereview.chromium.org/2377763002
This commit is contained in:
parent
b3a3b58c4e
commit
eec8304714
@ -60,8 +60,7 @@ protected:
|
||||
|
||||
canvas->save();
|
||||
for (int i = 0; i < kNumColors; i++) {
|
||||
sk_sp<SkColorSpace> space =
|
||||
SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named)->makeLinearGamma();
|
||||
sk_sp<SkColorSpace> space = SkColorSpace::NewNamed(SkColorSpace::kSRGBLinear_Named);
|
||||
sk_sp<SkShader> s = SkShader::MakeColorShader(colors[i], space);
|
||||
SkPaint paint;
|
||||
paint.setShader(s);
|
||||
|
@ -31,6 +31,12 @@ public:
|
||||
* Often used by images and monitors.
|
||||
*/
|
||||
kAdobeRGB_Named,
|
||||
|
||||
/**
|
||||
* Colorspace with the sRGB primaries, but a linear (1.0) gamma. Commonly used for
|
||||
* half-float surfaces, and high precision individual colors (gradient stops, etc...)
|
||||
*/
|
||||
kSRGBLinear_Named,
|
||||
};
|
||||
|
||||
enum RenderTargetGamma : uint8_t {
|
||||
|
@ -113,6 +113,11 @@ sk_sp<SkColorSpace> SkColorSpace_Base::NewRGB(SkGammaNamed gammaNamed, const SkM
|
||||
return SkColorSpace::NewNamed(kAdobeRGB_Named);
|
||||
}
|
||||
break;
|
||||
case kLinear_SkGammaNamed:
|
||||
if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) {
|
||||
return SkColorSpace::NewNamed(kSRGBLinear_Named);
|
||||
}
|
||||
break;
|
||||
case kNonStandard_SkGammaNamed:
|
||||
// This is not allowed.
|
||||
return nullptr;
|
||||
@ -136,10 +141,12 @@ sk_sp<SkColorSpace> SkColorSpace::NewRGB(RenderTargetGamma gamma, const SkMatrix
|
||||
|
||||
static SkColorSpace* gAdobeRGB;
|
||||
static SkColorSpace* gSRGB;
|
||||
static SkColorSpace* gSRGBLinear;
|
||||
|
||||
sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
|
||||
static SkOnce sRGBOnce;
|
||||
static SkOnce adobeRGBOnce;
|
||||
static SkOnce sRGBLinearOnce;
|
||||
|
||||
switch (named) {
|
||||
case kSRGB_Named: {
|
||||
@ -164,6 +171,17 @@ sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
|
||||
});
|
||||
return sk_ref_sp<SkColorSpace>(gAdobeRGB);
|
||||
}
|
||||
case kSRGBLinear_Named: {
|
||||
sRGBLinearOnce([] {
|
||||
SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor);
|
||||
srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50);
|
||||
|
||||
// Force the mutable type mask to be computed. This avoids races.
|
||||
(void)srgbToxyzD50.getType();
|
||||
gSRGBLinear = new SkColorSpace_Base(kLinear_SkGammaNamed, srgbToxyzD50);
|
||||
});
|
||||
return sk_ref_sp<SkColorSpace>(gSRGBLinear);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -238,7 +256,7 @@ struct ColorSpaceHeader {
|
||||
SkASSERT(k0_Version == version);
|
||||
header.fVersion = (uint8_t) version;
|
||||
|
||||
SkASSERT(named <= SkColorSpace::kAdobeRGB_Named);
|
||||
SkASSERT(named <= SkColorSpace::kSRGBLinear_Named);
|
||||
header.fNamed = (uint8_t) named;
|
||||
|
||||
SkASSERT(gammaNamed <= kNonStandard_SkGammaNamed);
|
||||
@ -273,6 +291,14 @@ size_t SkColorSpace::writeToMemory(void* memory) const {
|
||||
ColorSpaceHeader::Pack(k0_Version, kAdobeRGB_Named,
|
||||
as_CSB(this)->fGammaNamed, 0);
|
||||
}
|
||||
return sizeof(ColorSpaceHeader);
|
||||
} else if (this == gSRGBLinear) {
|
||||
if (memory) {
|
||||
*((ColorSpaceHeader*)memory) =
|
||||
ColorSpaceHeader::Pack(k0_Version, kSRGBLinear_Named,
|
||||
as_CSB(this)->fGammaNamed, 0);
|
||||
}
|
||||
return sizeof(ColorSpaceHeader);
|
||||
}
|
||||
|
||||
// If we have a named gamma, write the enum and the matrix.
|
||||
|
@ -141,7 +141,7 @@ SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc, const SkMatri
|
||||
}
|
||||
|
||||
// Color space refers to fColors4f, so it's always linear gamma
|
||||
fColorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named)->makeLinearGamma();
|
||||
fColorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGBLinear_Named);
|
||||
} else {
|
||||
SkASSERT(desc.fColors4f && desc.fColorSpace && desc.fColorSpace->gammaIsLinear());
|
||||
|
||||
@ -683,10 +683,9 @@ void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap,
|
||||
SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named));
|
||||
break;
|
||||
case GradientBitmapType::kHalfFloat:
|
||||
info = SkImageInfo::Make(kCache32Count, 1, kRGBA_F16_SkColorType,
|
||||
kPremul_SkAlphaType,
|
||||
SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named)
|
||||
->makeLinearGamma());
|
||||
info = SkImageInfo::Make(
|
||||
kCache32Count, 1, kRGBA_F16_SkColorType, kPremul_SkAlphaType,
|
||||
SkColorSpace::NewNamed(SkColorSpace::kSRGBLinear_Named));
|
||||
break;
|
||||
default:
|
||||
SkFAIL("Unexpected bitmap type");
|
||||
|
@ -115,6 +115,29 @@ DEF_TEST(ColorSpaceSRGBCompare, r) {
|
||||
REPORTER_ASSERT(r, strangeColorSpace != namedColorSpace);
|
||||
}
|
||||
|
||||
DEF_TEST(ColorSpaceSRGBLinearCompare, r) {
|
||||
// Create the linear sRGB color space by name
|
||||
sk_sp<SkColorSpace> namedColorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGBLinear_Named);
|
||||
|
||||
// Create the linear sRGB color space via the sRGB color space's makeLinearGamma()
|
||||
sk_sp<SkColorSpace> viaSrgbColorSpace =
|
||||
SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named)->makeLinearGamma();
|
||||
REPORTER_ASSERT(r, namedColorSpace == viaSrgbColorSpace);
|
||||
|
||||
// Create a linear sRGB color space by value
|
||||
SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor);
|
||||
srgbToxyzD50.set3x3RowMajorf(g_sRGB_XYZ);
|
||||
sk_sp<SkColorSpace> rgbColorSpace =
|
||||
SkColorSpace::NewRGB(SkColorSpace::kLinear_RenderTargetGamma, srgbToxyzD50);
|
||||
REPORTER_ASSERT(r, rgbColorSpace == namedColorSpace);
|
||||
|
||||
// Change a single value from the sRGB matrix
|
||||
srgbToxyzD50.set(2, 2, 0.5f);
|
||||
sk_sp<SkColorSpace> strangeColorSpace =
|
||||
SkColorSpace::NewRGB(SkColorSpace::kLinear_RenderTargetGamma, srgbToxyzD50);
|
||||
REPORTER_ASSERT(r, strangeColorSpace != namedColorSpace);
|
||||
}
|
||||
|
||||
class ColorSpaceTest {
|
||||
public:
|
||||
static sk_sp<SkData> WriteToICC(SkColorSpace* space) {
|
||||
@ -150,21 +173,18 @@ DEF_TEST(ColorSpaceWriteICC, r) {
|
||||
DEF_TEST(ColorSpace_Named, r) {
|
||||
const struct {
|
||||
SkColorSpace::Named fNamed;
|
||||
bool fIsSRGB;
|
||||
SkGammaNamed fExpectedGamma;
|
||||
} recs[] {
|
||||
{ SkColorSpace::kSRGB_Named, true },
|
||||
{ SkColorSpace::kAdobeRGB_Named, false },
|
||||
{ SkColorSpace::kSRGB_Named, kSRGB_SkGammaNamed },
|
||||
{ SkColorSpace::kAdobeRGB_Named, k2Dot2Curve_SkGammaNamed },
|
||||
{ SkColorSpace::kSRGBLinear_Named, kLinear_SkGammaNamed },
|
||||
};
|
||||
|
||||
for (auto rec : recs) {
|
||||
auto cs = SkColorSpace::NewNamed(rec.fNamed);
|
||||
REPORTER_ASSERT(r, cs);
|
||||
if (cs) {
|
||||
if (rec.fIsSRGB) {
|
||||
REPORTER_ASSERT(r, kSRGB_SkGammaNamed == as_CSB(cs)->gammaNamed());
|
||||
} else {
|
||||
REPORTER_ASSERT(r, k2Dot2Curve_SkGammaNamed == as_CSB(cs)->gammaNamed());
|
||||
}
|
||||
REPORTER_ASSERT(r, rec.fExpectedGamma == as_CSB(cs)->gammaNamed());
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,6 +214,7 @@ static void test_serialize(skiatest::Reporter* r, SkColorSpace* space, bool isNa
|
||||
DEF_TEST(ColorSpace_Serialize, r) {
|
||||
test_serialize(r, SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named).get(), true);
|
||||
test_serialize(r, SkColorSpace::NewNamed(SkColorSpace::kAdobeRGB_Named).get(), true);
|
||||
test_serialize(r, SkColorSpace::NewNamed(SkColorSpace::kSRGBLinear_Named).get(), true);
|
||||
|
||||
sk_sp<SkData> monitorData = SkData::MakeFromFileName(
|
||||
GetResourcePath("icc_profiles/HP_ZR30w.icc").c_str());
|
||||
|
@ -924,7 +924,7 @@ static void test_surface_creation_and_snapshot_with_color_space(
|
||||
SkMatrix44 srgbMatrix = srgbColorSpace->toXYZD50();
|
||||
const float oddGamma[] = { 2.4f, 2.4f, 2.4f };
|
||||
auto oddColorSpace = SkColorSpace_Base::NewRGB(oddGamma, srgbMatrix);
|
||||
auto linearColorSpace = srgbColorSpace->makeLinearGamma();
|
||||
auto linearColorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGBLinear_Named);
|
||||
|
||||
const struct {
|
||||
SkColorType fColorType;
|
||||
|
Loading…
Reference in New Issue
Block a user