Add clamped/unclamped xform to GrColorSpaceXform
Use that in analytic gradient setup for future-proofing. Also fixed
several out-of-date comments in gradient code.
Bug: skia:
Change-Id: I79726cad786c22f80e08cdc2b7a1e15ae27ecd5a
Reviewed-on: https://skia-review.googlesource.com/62320
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/GrColorSpaceXform.cpp b/src/gpu/GrColorSpaceXform.cpp
index 0e98a87..e43ccdc 100644
--- a/src/gpu/GrColorSpaceXform.cpp
+++ b/src/gpu/GrColorSpaceXform.cpp
@@ -121,11 +121,16 @@
return a->fSrcToDst == b->fSrcToDst;
}
-GrColor4f GrColorSpaceXform::apply(const GrColor4f& srcColor) {
+GrColor4f GrColorSpaceXform::unclampedXform(const GrColor4f& srcColor) {
GrColor4f result;
fSrcToDst.mapScalars(srcColor.fRGBA, result.fRGBA);
- // We always operate on unpremul colors, so clamp to [0,1].
+ return result;
+}
+
+GrColor4f GrColorSpaceXform::clampedXform(const GrColor4f& srcColor) {
+ GrColor4f result = this->unclampedXform(srcColor);
for (int i = 0; i < 4; ++i) {
+ // We always operate on unpremul colors, so clamp to [0,1].
result.fRGBA[i] = SkTPin(result.fRGBA[i], 0.0f, 1.0f);
}
return result;
diff --git a/src/gpu/GrColorSpaceXform.h b/src/gpu/GrColorSpaceXform.h
index b871563..3f03e56 100644
--- a/src/gpu/GrColorSpaceXform.h
+++ b/src/gpu/GrColorSpaceXform.h
@@ -37,7 +37,8 @@
static bool Equals(const GrColorSpaceXform* a, const GrColorSpaceXform* b);
- GrColor4f apply(const GrColor4f& srcColor);
+ GrColor4f unclampedXform(const GrColor4f& srcColor);
+ GrColor4f clampedXform(const GrColor4f& srcColor);
private:
SkMatrix44 fSrcToDst;
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 0c065f9..2d09f00 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -342,7 +342,7 @@
}
if (gamutXform) {
- color = gamutXform->apply(color);
+ color = gamutXform->clampedXform(color);
}
return color;
diff --git a/src/shaders/SkColorShader.cpp b/src/shaders/SkColorShader.cpp
index 53bc94e..33d3166 100644
--- a/src/shaders/SkColorShader.cpp
+++ b/src/shaders/SkColorShader.cpp
@@ -213,7 +213,7 @@
args.fDstColorSpace);
GrColor4f color = GrColor4f::FromSkColor4f(fColor4);
if (colorSpaceXform) {
- color = colorSpaceXform->apply(color);
+ color = colorSpaceXform->clampedXform(color);
}
return GrConstColorProcessor::Make(color.premul(), GrConstColorProcessor::kModulateA_InputMode);
}
diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp
index 6dcc0ae..339f7ee 100644
--- a/src/shaders/gradients/SkGradientShader.cpp
+++ b/src/shaders/gradients/SkGradientShader.cpp
@@ -809,8 +809,7 @@
* over and over, we'd like to return exactly the same "bitmap" if possible,
* allowing the client to utilize a cache of our bitmap (e.g. with a GPU).
* To do that, we maintain a private cache of built-bitmaps, based on our
- * colors and positions. Note: we don't try to flatten the fMapper, so if one
- * is present, we skip the cache for now.
+ * colors and positions.
*/
void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap,
GradientBitmapType bitmapType) const {
@@ -864,13 +863,11 @@
switch (bitmapType) {
case GradientBitmapType::kSRGB:
info = SkImageInfo::Make(kCache32Count, 1, kRGBA_8888_SkColorType,
- kPremul_SkAlphaType,
- SkColorSpace::MakeSRGB());
+ kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
break;
case GradientBitmapType::kHalfFloat:
- info = SkImageInfo::Make(
- kCache32Count, 1, kRGBA_F16_SkColorType, kPremul_SkAlphaType,
- SkColorSpace::MakeSRGBLinear());
+ info = SkImageInfo::Make(kCache32Count, 1, kRGBA_F16_SkColorType,
+ kPremul_SkAlphaType, SkColorSpace::MakeSRGBLinear());
break;
default:
SK_ABORT("Unexpected bitmap type");
@@ -1483,12 +1480,10 @@
break;
}
- // We could skip this step if both colors are known to be opaque. Two
- // considerations:
+ // We could skip this step if all colors are known to be opaque. Two considerations:
// The gradient SkShader reporting opaque is more restrictive than necessary in the two
// pt case. Make sure the key reflects this optimization (and note that it can use the
- // same shader as thekBeforeIterp case). This same optimization applies to the 3 color
- // case below.
+ // same shader as the kBeforeInterp case).
if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
}
@@ -1569,7 +1564,8 @@
}
if (fColorSpaceXform) {
- fColorSpaceXform->srcToDst().mapScalars(fColors4f[i].fRGBA, fColors4f[i].fRGBA);
+ // We defer clamping to after interpolation (see emitAnalyticalColor)
+ fColors4f[i] = fColorSpaceXform->unclampedXform(fColors4f[i]);
}
}
diff --git a/src/shaders/gradients/SkGradientShaderPriv.h b/src/shaders/gradients/SkGradientShaderPriv.h
index 23ff30f..1fd5ca9 100644
--- a/src/shaders/gradients/SkGradientShaderPriv.h
+++ b/src/shaders/gradients/SkGradientShaderPriv.h
@@ -516,11 +516,11 @@
const char* inputColor);
enum {
- // First bit for premul before/after interp
+ // First bit for premul before/after interpolation
kPremulBeforeInterpKey = 1,
// Next three bits for 2/3 color type or different special
- // hard stop cases (neither means using texture atlas)
+ // hard stop cases ('none' means using texture atlas)
kTwoColorKey = 2,
kThreeColorKey = 4,