From 3b79aa3a5ad0c6cff8495e14fca0c5e6f4ff9b9b Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Fri, 26 Oct 2018 14:57:35 -0400 Subject: [PATCH] On second thought, remove GrColor4s We're going to use half-floats, which are far more future-proof. Bug: skia: Change-Id: I6e098017381256d6e750ac546c353072802282cb Reviewed-on: https://skia-review.googlesource.com/c/165522 Reviewed-by: Brian Salomon Commit-Queue: Brian Osman --- bench/VertexColorSpaceBench.cpp | 25 +-------------- include/private/GrColor.h | 57 --------------------------------- tests/ColorTest.cpp | 50 ----------------------------- 3 files changed, 1 insertion(+), 131 deletions(-) diff --git a/bench/VertexColorSpaceBench.cpp b/bench/VertexColorSpaceBench.cpp index d4a4215688..ce826e11f4 100644 --- a/bench/VertexColorSpaceBench.cpp +++ b/bench/VertexColorSpaceBench.cpp @@ -31,7 +31,6 @@ enum Mode { kFloat_Mode, // Transform colors on CPU, use float4 attributes. kHalf_Mode, // Transform colors on CPU, use half4 attributes. kShader_Mode, // Use ubyte4 attributes, transform colors on GPU (vertex shader). - kShort_Mode, // Transform on CPU, use short4 (4.12) attributes with a bit of shader math. }; class GP : public GrGeometryProcessor { @@ -52,9 +51,6 @@ public: case kHalf_Mode: fInColor = {"inColor", kHalf4_GrVertexAttribType, kHalf4_GrSLType}; break; - case kShort_Mode: - fInColor = {"inColor", kShort4_GrVertexAttribType, kFloat4_GrSLType}; - break; } this->setVertexAttributeCnt(2); } @@ -84,8 +80,6 @@ public: vertBuilder->appendColorGamutXform(&xformedColor, "color", &fColorSpaceHelper); vertBuilder->codeAppendf("color = %s;", xformedColor.c_str()); vertBuilder->codeAppend("color = half4(color.rgb * color.a, color.a);"); - } else if (kShort_Mode == gp.fMode) { - vertBuilder->codeAppend("color = color * (1 / 4095.0);"); } vertBuilder->codeAppendf("%s = color;", varying.vsOut()); @@ -145,7 +139,7 @@ public: : INHERITED(ClassID()) , fMode(mode) , fColor4f(color4f) { - SkASSERT(kFloat_Mode == fMode || kHalf_Mode == mode || kShort_Mode == mode); + SkASSERT(kFloat_Mode == fMode || kHalf_Mode == mode); this->setBounds(SkRect::MakeWH(100.f, 100.f), HasAABloat::kNo, IsZeroArea::kNo); } @@ -177,7 +171,6 @@ private: vertexStride += sizeof(SkColor4f); break; case kHalf_Mode: - case kShort_Mode: vertexStride += sizeof(uint64_t); break; default: @@ -227,20 +220,6 @@ private: v[i + 1].fPos.set(dx * i, 100.0f); v[i + 1].fColor = color; } - } else if (kShort_Mode == fMode) { - struct V { - SkPoint fPos; - GrColor4s fColor; - }; - SkASSERT(sizeof(V) == vertexStride); - GrColor4s color = GrColor4s::FromFloat4(fColor4f.vec()); - V* v = (V*)verts; - for (int i = 0; i < kVertexCount; i += 2) { - v[i + 0].fPos.set(dx * i, 0.0f); - v[i + 0].fColor = color; - v[i + 1].fPos.set(dx * i, 100.0f); - v[i + 1].fColor = color; - } } else { struct V { SkPoint fPos; @@ -320,7 +299,6 @@ public: op = pool->allocate(SkColorToUnpremulGrColor(c), xform); break; case kHalf_Mode: - case kShort_Mode: case kFloat_Mode: { SkColor4f c4f = SkColor4f::FromColor(c); c4f = xform->apply(c4f); @@ -344,5 +322,4 @@ private: DEF_BENCH(return new VertexColorSpaceBench(kBaseline_Mode, "baseline")); DEF_BENCH(return new VertexColorSpaceBench(kFloat_Mode, "float")); DEF_BENCH(return new VertexColorSpaceBench(kHalf_Mode, "half")); -DEF_BENCH(return new VertexColorSpaceBench(kShort_Mode, "short")); DEF_BENCH(return new VertexColorSpaceBench(kShader_Mode, "shader")); diff --git a/include/private/GrColor.h b/include/private/GrColor.h index be11d7d767..23c432a942 100644 --- a/include/private/GrColor.h +++ b/include/private/GrColor.h @@ -152,61 +152,4 @@ static inline GrColor GrUnpremulColor(GrColor color) { return GrColorPackRGBA(r, g, b, a); } -/** - * GrColor4s is 8 bytes (4 shorts) for for R, G, B, A, in that order. This is intended for storing - * wide-gamut (non-normalized) colors in vertex attributes. The shorts are fixed point (1.3.12), - * giving us a range of ~[-8,8], and plenty of precision. - */ -struct GrColor4s { - static constexpr float kScale = 4095.0f; - - static GrColor4s FromFloat4(const float* c4f) { - auto convert = [](float x) { - return static_cast(SkTPin(sk_float_round2int(x * kScale), -32768, 32767)); - }; - return { convert(c4f[0]), convert(c4f[1]), convert(c4f[2]), convert(c4f[3]) }; - } - - static GrColor4s FromGrColor(GrColor color) { - unsigned r = GrColorUnpackR(color); - unsigned g = GrColorUnpackG(color); - unsigned b = GrColorUnpackB(color); - unsigned a = GrColorUnpackA(color); - // GrColor4s has 12 fractional bits, so to map a [0-1] byte value, we need to shift up, - // and then replicate the top nibble into the bottom nibble. - return { static_cast(r << 4 | r >> 4), - static_cast(g << 4 | g >> 4), - static_cast(b << 4 | b >> 4), - static_cast(a << 4 | a >> 4) }; - } - - bool isNormalized() const { - // The smallest normalized value is 0x0000 == 0.0. Negative values set the top sign bit. - // The largest normalized value is 0x0fff == 1.0. Larger values set some of the next 3 bits. - // So a [0, 1] check is easy: Are the top four bits clear? - return !((fR | fG | fB | fA) & 0xF000); - } - - SkColor4f toSkColor4f() const { - const float invScale = 1 / kScale; - return { static_cast(fR) * invScale, - static_cast(fG) * invScale, - static_cast(fB) * invScale, - static_cast(fA) * invScale }; - } - - GrColor toGrColor() const { - SkASSERT(isNormalized()); - return GrColorPackRGBA(fR >> 4, fG >> 4, fB >> 4, fA >> 4); - } - - // These values are actually signed shorts (as seen by the GPU), but we store them here as - // unsigned, so that we can safely/easily use bitwise operations to go to/from 8-bit, and to - // check for normalized values. - uint16_t fR; - uint16_t fG; - uint16_t fB; - uint16_t fA; -}; - #endif diff --git a/tests/ColorTest.cpp b/tests/ColorTest.cpp index 1b55d6523b..e8bc9ecd85 100644 --- a/tests/ColorTest.cpp +++ b/tests/ColorTest.cpp @@ -84,53 +84,3 @@ DEF_TEST(Color, reporter) { test_fast_interp(reporter); //test_565blend(); } - -#include "GrColor.h" - -DEF_GPUTEST(GrColor4s, reporter, /* options */) { - // Test that GrColor -> GrColor4s -> GrColor round-trips perfectly - for (unsigned i = 0; i <= 255; ++i) { - GrColor r = GrColorPackRGBA(i, 0, 0, 0); - GrColor g = GrColorPackRGBA(0, i, 0, 0); - GrColor b = GrColorPackRGBA(0, 0, i, 0); - GrColor a = GrColorPackRGBA(0, 0, 0, i); - REPORTER_ASSERT(reporter, r == GrColor4s::FromGrColor(r).toGrColor()); - REPORTER_ASSERT(reporter, g == GrColor4s::FromGrColor(g).toGrColor()); - REPORTER_ASSERT(reporter, b == GrColor4s::FromGrColor(b).toGrColor()); - REPORTER_ASSERT(reporter, a == GrColor4s::FromGrColor(a).toGrColor()); - REPORTER_ASSERT(reporter, GrColor4s::FromGrColor(r).isNormalized()); - REPORTER_ASSERT(reporter, GrColor4s::FromGrColor(g).isNormalized()); - REPORTER_ASSERT(reporter, GrColor4s::FromGrColor(b).isNormalized()); - REPORTER_ASSERT(reporter, GrColor4s::FromGrColor(a).isNormalized()); - } - - // Test that floating point values are correctly detected as in/out of range, and that they - // round-trip to within the limits of the fixed point precision - float maxErr = 0, worstX = 0, worstRT = 0; - { - for (int i = -32768; i <= 32767; ++i) { - float x = i / 4095.0f; - float frgba[4] = { x, 0, 0, 0 }; - GrColor4s c4s = GrColor4s::FromFloat4(frgba); - REPORTER_ASSERT(reporter, c4s.isNormalized() == (x >= 0.0f && x <= 1.0f)); - SkColor4f c4f = c4s.toSkColor4f(); - if (fabsf(c4f.fR - x) > maxErr) { - maxErr = fabsf(c4f.fR - x); - worstX = x; - worstRT = c4f.fR; - } - } - } - - REPORTER_ASSERT(reporter, maxErr < 0.0001f, "maxErr: %f, %f != %f", maxErr, worstX, worstRT); - - // Test clamping of unrepresentable values - { - float frgba[4] = { -8.5f, 9.0f, 0, 0 }; - GrColor4s c4s = GrColor4s::FromFloat4(frgba); - REPORTER_ASSERT(reporter, !c4s.isNormalized()); - SkColor4f c4f = c4s.toSkColor4f(); - REPORTER_ASSERT(reporter, c4f.fR < -8.0f); - REPORTER_ASSERT(reporter, c4f.fG > 8.0f); - } -}