aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Florin Malita <fmalita@chromium.org>2017-08-08 12:14:17 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-08-08 16:42:59 +0000
commitb81a8b9c74c69ebbe9eafa5100baf599aa22d9fd (patch)
tree0887b58f47c427429056f6af21feed43d4953b22
parente9bf6dc100e2ce913ee000273e1879ebc1ffbafd (diff)
Consolidate GrGradientEffect analytical impls
There's a lot of commonality, we can share more code. Change-Id: I6528358763459c4e8af17fe5f6763752cfffdf39 Reviewed-on: https://skia-review.googlesource.com/31023 Commit-Queue: Florin Malita <fmalita@chromium.org> Reviewed-by: Brian Salomon <bsalomon@google.com>
-rw-r--r--src/shaders/gradients/SkGradientShader.cpp148
-rw-r--r--src/shaders/gradients/SkGradientShaderPriv.h8
2 files changed, 59 insertions, 97 deletions
diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp
index d34d4e0fd0..4fcfa36d85 100644
--- a/src/shaders/gradients/SkGradientShader.cpp
+++ b/src/shaders/gradients/SkGradientShader.cpp
@@ -1544,11 +1544,15 @@ uint32_t GrGradientEffect::GLSLProcessor::GenBaseGradientKey(const GrProcessor&
return key;
}
-static void emit_clamp_t(GrGLSLFPFragmentBuilder* fragBuilder,
- const GrShaderCaps* shaderCaps,
- const char* t,
- SkShader::TileMode tileMode) {
- switch (tileMode) {
+void GrGradientEffect::GLSLProcessor::emitAnalyticalColor(GrGLSLFPFragmentBuilder* fragBuilder,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderCaps* shaderCaps,
+ const GrGradientEffect& ge,
+ const char* t,
+ const char* outputColor,
+ const char* inputColor) {
+ // First, apply tiling rules.
+ switch (ge.fTileMode) {
case SkShader::kClamp_TileMode:
fragBuilder->codeAppendf("float clamp_t = clamp(%s, 0.0, 1.0);", t);
break;
@@ -1575,25 +1579,13 @@ static void emit_clamp_t(GrGLSLFPFragmentBuilder* fragBuilder,
fragBuilder->codeAppendf("}");
break;
}
-}
-void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBuilder,
- GrGLSLUniformHandler* uniformHandler,
- const GrShaderCaps* shaderCaps,
- const GrGradientEffect& ge,
- const char* gradientTValue,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplers& texSamplers) {
+ // Calculate the color.
+ const char* colors = uniformHandler->getUniformCStr(fColorsUni);
switch (ge.getColorType()) {
case kSingleHardStop_ColorType: {
- const char* t = gradientTValue;
- const char* colors = uniformHandler->getUniformCStr(fColorsUni);
const char* stopT = uniformHandler->getUniformCStr(fHardStopT);
- emit_clamp_t(fragBuilder, shaderCaps, t, ge.fTileMode);
-
- // Calculate color
fragBuilder->codeAppend ("float4 start, end;");
fragBuilder->codeAppend ("float relative_t;");
fragBuilder->codeAppendf("if (clamp_t < %s) {", stopT);
@@ -1607,23 +1599,10 @@ void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui
fragBuilder->codeAppend ("}");
fragBuilder->codeAppend ("float4 colorTemp = mix(start, end, relative_t);");
- if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
- fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
- }
- if (ge.fColorSpaceXform) {
- fragBuilder->codeAppend("colorTemp.rgb = clamp(colorTemp.rgb, 0, colorTemp.a);");
- }
- fragBuilder->codeAppendf("%s = %s * colorTemp;", outputColor, inputColor);
-
break;
}
case kHardStopLeftEdged_ColorType: {
- const char* t = gradientTValue;
- const char* colors = uniformHandler->getUniformCStr(fColorsUni);
-
- emit_clamp_t(fragBuilder, shaderCaps, t, ge.fTileMode);
-
fragBuilder->codeAppendf("float4 colorTemp = mix(%s[1], %s[2], clamp_t);", colors,
colors);
if (SkShader::kClamp_TileMode == ge.fTileMode) {
@@ -1632,23 +1611,10 @@ void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui
fragBuilder->codeAppendf("}");
}
- if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
- fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
- }
- if (ge.fColorSpaceXform) {
- fragBuilder->codeAppend("colorTemp.rgb = clamp(colorTemp.rgb, 0, colorTemp.a);");
- }
- fragBuilder->codeAppendf("%s = %s * colorTemp;", outputColor, inputColor);
-
break;
}
case kHardStopRightEdged_ColorType: {
- const char* t = gradientTValue;
- const char* colors = uniformHandler->getUniformCStr(fColorsUni);
-
- emit_clamp_t(fragBuilder, shaderCaps, t, ge.fTileMode);
-
fragBuilder->codeAppendf("float4 colorTemp = mix(%s[0], %s[1], clamp_t);", colors,
colors);
if (SkShader::kClamp_TileMode == ge.fTileMode) {
@@ -1657,50 +1623,17 @@ void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui
fragBuilder->codeAppendf("}");
}
- if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
- fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
- }
- if (ge.fColorSpaceXform) {
- fragBuilder->codeAppend("colorTemp.rgb = clamp(colorTemp.rgb, 0, colorTemp.a);");
- }
- fragBuilder->codeAppendf("%s = %s * colorTemp;", outputColor, inputColor);
-
break;
}
case kTwo_ColorType: {
- const char* t = gradientTValue;
- const char* colors = uniformHandler->getUniformCStr(fColorsUni);
-
- emit_clamp_t(fragBuilder, shaderCaps, t, ge.fTileMode);
-
fragBuilder->codeAppendf("float4 colorTemp = mix(%s[0], %s[1], clamp_t);",
colors, colors);
- // We could skip this step if both 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.
- if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
- fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
- }
- if (ge.fColorSpaceXform) {
- fragBuilder->codeAppend("colorTemp.rgb = clamp(colorTemp.rgb, 0, colorTemp.a);");
- }
-
- fragBuilder->codeAppendf("%s = %s * colorTemp;", outputColor, inputColor);
-
break;
}
case kThree_ColorType: {
- const char* t = gradientTValue;
- const char* colors = uniformHandler->getUniformCStr(fColorsUni);
-
- emit_clamp_t(fragBuilder, shaderCaps, t, ge.fTileMode);
-
fragBuilder->codeAppendf("float oneMinus2t = 1.0 - (2.0 * clamp_t);");
fragBuilder->codeAppendf("float4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s[0];",
colors);
@@ -1716,32 +1649,53 @@ void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui
}
fragBuilder->codeAppendf("colorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s[2];", colors);
- if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
- fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
- }
- if (ge.fColorSpaceXform) {
- fragBuilder->codeAppend("colorTemp.rgb = clamp(colorTemp.rgb, 0, colorTemp.a);");
- }
-
- fragBuilder->codeAppendf("%s = %s * colorTemp;", outputColor, inputColor);
-
break;
}
- case kTexture_ColorType: {
- fColorSpaceHelper.emitCode(uniformHandler, ge.fColorSpaceXform.get());
+ default:
+ SkASSERT(false);
+ break;
+ }
- const char* fsyuni = uniformHandler->getUniformCStr(fFSYUni);
+ // We could skip this step if both 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.
+ if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
+ fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
+ }
+ if (ge.fColorSpaceXform) {
+ fragBuilder->codeAppend("colorTemp.rgb = clamp(colorTemp.rgb, 0, colorTemp.a);");
+ }
- fragBuilder->codeAppendf("float2 coord = float2(%s, %s);", gradientTValue, fsyuni);
- fragBuilder->codeAppendf("%s = ", outputColor);
- fragBuilder->appendTextureLookupAndModulate(inputColor, texSamplers[0], "coord",
- kVec2f_GrSLType, &fColorSpaceHelper);
- fragBuilder->codeAppend(";");
+ fragBuilder->codeAppendf("%s = %s * colorTemp;", outputColor, inputColor);
+}
- break;
- }
+void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBuilder,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderCaps* shaderCaps,
+ const GrGradientEffect& ge,
+ const char* gradientTValue,
+ const char* outputColor,
+ const char* inputColor,
+ const TextureSamplers& texSamplers) {
+ if (ge.getColorType() != kTexture_ColorType) {
+ this->emitAnalyticalColor(fragBuilder, uniformHandler, shaderCaps, ge, gradientTValue,
+ outputColor, inputColor);
+ return;
}
+
+ fColorSpaceHelper.emitCode(uniformHandler, ge.fColorSpaceXform.get());
+
+ const char* fsyuni = uniformHandler->getUniformCStr(fFSYUni);
+
+ fragBuilder->codeAppendf("float2 coord = float2(%s, %s);", gradientTValue, fsyuni);
+ fragBuilder->codeAppendf("%s = ", outputColor);
+ fragBuilder->appendTextureLookupAndModulate(inputColor, texSamplers[0], "coord",
+ kVec2f_GrSLType, &fColorSpaceHelper);
+ fragBuilder->codeAppend(";");
}
/////////////////////////////////////////////////////////////////////
diff --git a/src/shaders/gradients/SkGradientShaderPriv.h b/src/shaders/gradients/SkGradientShaderPriv.h
index b6da7b9507..437e8308f5 100644
--- a/src/shaders/gradients/SkGradientShaderPriv.h
+++ b/src/shaders/gradients/SkGradientShaderPriv.h
@@ -503,6 +503,14 @@ protected:
const TextureSamplers&);
private:
+ void emitAnalyticalColor(GrGLSLFPFragmentBuilder* fragBuilder,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderCaps* shaderCaps,
+ const GrGradientEffect&,
+ const char* gradientTValue,
+ const char* outputColor,
+ const char* inputColor);
+
enum {
// First bit for premul before/after interp
kPremulBeforeInterpKey = 1,