diff options
author | 2017-08-08 12:14:17 -0400 | |
---|---|---|
committer | 2017-08-08 16:42:59 +0000 | |
commit | b81a8b9c74c69ebbe9eafa5100baf599aa22d9fd (patch) | |
tree | 0887b58f47c427429056f6af21feed43d4953b22 | |
parent | e9bf6dc100e2ce913ee000273e1879ebc1ffbafd (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.cpp | 148 | ||||
-rw-r--r-- | src/shaders/gradients/SkGradientShaderPriv.h | 8 |
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, |