Index: src/effects/gradients/SkGradientShader.cpp |
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp |
index 5585944e55b77369cfca9c7150a0051a0cc126f1..820c5b225d1d4187c1cf6a9e4d85d5fe5fca126b 100644 |
--- a/src/effects/gradients/SkGradientShader.cpp |
+++ b/src/effects/gradients/SkGradientShader.cpp |
@@ -228,8 +228,21 @@ |
desc.flatten(buffer); |
} |
-static inline bool close_to_one_half(const SkFixed& val) { |
- return SkScalarNearlyEqual(SkFixedToScalar(val), SK_ScalarHalf); |
+SkGradientShaderBase::GpuColorType SkGradientShaderBase::getGpuColorType(SkColor colors[3]) const { |
+ if (fColorCount <= 3) { |
+ memcpy(colors, fOrigColors, fColorCount * sizeof(SkColor)); |
+ } |
+ |
+ if (SkShader::kClamp_TileMode == fTileMode) { |
+ if (2 == fColorCount) { |
+ return kTwo_GpuColorType; |
+ } else if (3 == fColorCount && |
+ (SkScalarAbs( |
+ SkFixedToScalar(fRecs[1].fPos) - SK_ScalarHalf) < SK_Scalar1 / 1000)) { |
+ return kThree_GpuColorType; |
+ } |
+ } |
+ return kTexture_GpuColorType; |
} |
void SkGradientShaderBase::FlipGradientColors(SkColor* colorDst, Rec* recDst, |
@@ -898,186 +911,113 @@ |
#include "glsl/GrGLSLUniformHandler.h" |
#include "SkGr.h" |
-static inline int color_type_to_color_count(GrGradientEffect::ColorType colorType) { |
- switch (colorType) { |
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
- case GrGradientEffect::kHardStopCentered_ColorType: |
- return 4; |
- case GrGradientEffect::kHardStopLeftEdged_ColorType: |
- case GrGradientEffect::kHardStopRightEdged_ColorType: |
- return 3; |
-#endif |
- case GrGradientEffect::kTwo_ColorType: |
- return 2; |
- case GrGradientEffect::kThree_ColorType: |
- return 3; |
- case GrGradientEffect::kTexture_ColorType: |
- return 0; |
- } |
- |
- SkDEBUGFAIL("Unhandled ColorType in color_type_to_color_count()"); |
- return -1; |
-} |
- |
-GrGradientEffect::ColorType GrGradientEffect::determineColorType( |
- const SkGradientShaderBase& shader) { |
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
- if (shader.fOrigPos) { |
- if (4 == shader.fColorCount) { |
- if (SkScalarNearlyEqual(shader.fOrigPos[0], 0.0f) && |
- SkScalarNearlyEqual(shader.fOrigPos[1], 0.5f) && |
- SkScalarNearlyEqual(shader.fOrigPos[2], 0.5f) && |
- SkScalarNearlyEqual(shader.fOrigPos[3], 1.0f)) { |
- |
- return kHardStopCentered_ColorType; |
- } |
- } else if (3 == shader.fColorCount) { |
- if (SkScalarNearlyEqual(shader.fOrigPos[0], 0.0f) && |
- SkScalarNearlyEqual(shader.fOrigPos[1], 0.0f) && |
- SkScalarNearlyEqual(shader.fOrigPos[2], 1.0f)) { |
- |
- return kHardStopLeftEdged_ColorType; |
- } else if (SkScalarNearlyEqual(shader.fOrigPos[0], 0.0f) && |
- SkScalarNearlyEqual(shader.fOrigPos[1], 1.0f) && |
- SkScalarNearlyEqual(shader.fOrigPos[2], 1.0f)) { |
- |
- return kHardStopRightEdged_ColorType; |
- } |
- } |
- } |
-#endif |
- |
- if (SkShader::kClamp_TileMode == shader.getTileMode()) { |
- if (2 == shader.fColorCount) { |
- return kTwo_ColorType; |
- } else if (3 == shader.fColorCount && |
- close_to_one_half(shader.getRecs()[1].fPos)) { |
- return kThree_ColorType; |
- } |
- } |
- |
- return kTexture_ColorType; |
+GrGradientEffect::GLSLProcessor::GLSLProcessor() |
+ : fCachedYCoord(SK_ScalarMax) { |
} |
void GrGradientEffect::GLSLProcessor::emitUniforms(GrGLSLUniformHandler* uniformHandler, |
const GrGradientEffect& ge) { |
- if (int colorCount = color_type_to_color_count(ge.getColorType())) { |
- fColorsUni = uniformHandler->addUniformArray(kFragment_GrShaderFlag, |
- kVec4f_GrSLType, |
- kDefault_GrSLPrecision, |
- "Colors", |
- colorCount); |
- } else { |
+ |
+ if (SkGradientShaderBase::kTwo_GpuColorType == ge.getColorType()) { // 2 Color case |
+ fColorStartUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
+ kVec4f_GrSLType, kDefault_GrSLPrecision, |
+ "GradientStartColor"); |
+ fColorEndUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
+ kVec4f_GrSLType, kDefault_GrSLPrecision, |
+ "GradientEndColor"); |
+ |
+ } else if (SkGradientShaderBase::kThree_GpuColorType == ge.getColorType()) { // 3 Color Case |
+ fColorStartUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
+ kVec4f_GrSLType, kDefault_GrSLPrecision, |
+ "GradientStartColor"); |
+ fColorMidUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
+ kVec4f_GrSLType, kDefault_GrSLPrecision, |
+ "GradientMidColor"); |
+ fColorEndUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
+ kVec4f_GrSLType, kDefault_GrSLPrecision, |
+ "GradientEndColor"); |
+ |
+ } else { // if not a fast case |
fFSYUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
kFloat_GrSLType, kDefault_GrSLPrecision, |
"GradientYCoordFS"); |
} |
} |
-static inline void set_after_interp_color_uni_array(const GrGLSLProgramDataManager& pdman, |
- const GrGLSLProgramDataManager::UniformHandle uni, |
- const SkTDArray<SkColor>& colors) { |
- int count = colors.count(); |
- constexpr int kSmallCount = 10; |
- |
- SkAutoSTArray<4*kSmallCount, float> vals(4*count); |
- |
- for (int i = 0; i < colors.count(); i++) { |
- // RGBA |
- vals[4*i + 0] = SkColorGetR(colors[i]) / 255.f; |
- vals[4*i + 1] = SkColorGetG(colors[i]) / 255.f; |
- vals[4*i + 2] = SkColorGetB(colors[i]) / 255.f; |
- vals[4*i + 3] = SkColorGetA(colors[i]) / 255.f; |
- } |
- |
- pdman.set4fv(uni, colors.count(), vals.get()); |
-} |
- |
-static inline void set_before_interp_color_uni_array(const GrGLSLProgramDataManager& pdman, |
- const GrGLSLProgramDataManager::UniformHandle uni, |
- const SkTDArray<SkColor>& colors) { |
- int count = colors.count(); |
- constexpr int kSmallCount = 10; |
- |
- SkAutoSTArray<4*kSmallCount, float> vals(4*count); |
- |
- for (int i = 0; i < count; i++) { |
- float a = SkColorGetA(colors[i]) / 255.f; |
- float aDiv255 = a / 255.f; |
- |
- // RGBA |
- vals[4*i + 0] = SkColorGetR(colors[i]) * aDiv255; |
- vals[4*i + 1] = SkColorGetG(colors[i]) * aDiv255; |
- vals[4*i + 2] = SkColorGetB(colors[i]) * aDiv255; |
- vals[4*i + 3] = a; |
- } |
- |
- pdman.set4fv(uni, count, vals.get()); |
+static inline void set_color_uni(const GrGLSLProgramDataManager& pdman, |
+ const GrGLSLProgramDataManager::UniformHandle uni, |
+ const SkColor* color) { |
+ pdman.set4f(uni, |
+ SkColorGetR(*color) / 255.f, |
+ SkColorGetG(*color) / 255.f, |
+ SkColorGetB(*color) / 255.f, |
+ SkColorGetA(*color) / 255.f); |
+} |
+ |
+static inline void set_mul_color_uni(const GrGLSLProgramDataManager& pdman, |
+ const GrGLSLProgramDataManager::UniformHandle uni, |
+ const SkColor* color){ |
+ float a = SkColorGetA(*color) / 255.f; |
+ float aDiv255 = a / 255.f; |
+ pdman.set4f(uni, |
+ SkColorGetR(*color) * aDiv255, |
+ SkColorGetG(*color) * aDiv255, |
+ SkColorGetB(*color) * aDiv255, |
+ a); |
} |
void GrGradientEffect::GLSLProcessor::onSetData(const GrGLSLProgramDataManager& pdman, |
const GrProcessor& processor) { |
+ |
const GrGradientEffect& e = processor.cast<GrGradientEffect>(); |
- switch (e.getColorType()) { |
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
- case GrGradientEffect::kHardStopCentered_ColorType: |
- case GrGradientEffect::kHardStopLeftEdged_ColorType: |
- case GrGradientEffect::kHardStopRightEdged_ColorType: |
-#endif |
- case GrGradientEffect::kTwo_ColorType: |
- case GrGradientEffect::kThree_ColorType: { |
- if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { |
- set_before_interp_color_uni_array(pdman, fColorsUni, e.fColors); |
- } else { |
- set_after_interp_color_uni_array(pdman, fColorsUni, e.fColors); |
- } |
- |
- break; |
- } |
- |
- case GrGradientEffect::kTexture_ColorType: { |
- SkScalar yCoord = e.getYCoord(); |
- if (yCoord != fCachedYCoord) { |
- pdman.set1f(fFSYUni, yCoord); |
- fCachedYCoord = yCoord; |
- } |
- break; |
- } |
- } |
-} |
+ |
+ if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()){ |
+ |
+ if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { |
+ set_mul_color_uni(pdman, fColorStartUni, e.getColors(0)); |
+ set_mul_color_uni(pdman, fColorEndUni, e.getColors(1)); |
+ } else { |
+ set_color_uni(pdman, fColorStartUni, e.getColors(0)); |
+ set_color_uni(pdman, fColorEndUni, e.getColors(1)); |
+ } |
+ |
+ } else if (SkGradientShaderBase::kThree_GpuColorType == e.getColorType()){ |
+ |
+ if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { |
+ set_mul_color_uni(pdman, fColorStartUni, e.getColors(0)); |
+ set_mul_color_uni(pdman, fColorMidUni, e.getColors(1)); |
+ set_mul_color_uni(pdman, fColorEndUni, e.getColors(2)); |
+ } else { |
+ set_color_uni(pdman, fColorStartUni, e.getColors(0)); |
+ set_color_uni(pdman, fColorMidUni, e.getColors(1)); |
+ set_color_uni(pdman, fColorEndUni, e.getColors(2)); |
+ } |
+ } else { |
+ |
+ SkScalar yCoord = e.getYCoord(); |
+ if (yCoord != fCachedYCoord) { |
+ pdman.set1f(fFSYUni, yCoord); |
+ fCachedYCoord = yCoord; |
+ } |
+ } |
+} |
+ |
uint32_t GrGradientEffect::GLSLProcessor::GenBaseGradientKey(const GrProcessor& processor) { |
const GrGradientEffect& e = processor.cast<GrGradientEffect>(); |
uint32_t key = 0; |
+ if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()) { |
+ key |= kTwoColorKey; |
+ } else if (SkGradientShaderBase::kThree_GpuColorType == e.getColorType()) { |
+ key |= kThreeColorKey; |
+ } |
+ |
if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { |
key |= kPremulBeforeInterpKey; |
} |
- |
- if (GrGradientEffect::kTwo_ColorType == e.getColorType()) { |
- key |= kTwoColorKey; |
- } else if (GrGradientEffect::kThree_ColorType == e.getColorType()) { |
- key |= kThreeColorKey; |
- } |
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
- else if (GrGradientEffect::kHardStopCentered_ColorType == e.getColorType()) { |
- key |= kHardStopCenteredKey; |
- } else if (GrGradientEffect::kHardStopLeftEdged_ColorType == e.getColorType()) { |
- key |= kHardStopZeroZeroOneKey; |
- } else if (GrGradientEffect::kHardStopRightEdged_ColorType == e.getColorType()) { |
- key |= kHardStopZeroOneOneKey; |
- } |
- |
- if (SkShader::TileMode::kClamp_TileMode == e.fTileMode) { |
- key |= kClampTileMode; |
- } else if (SkShader::TileMode::kRepeat_TileMode == e.fTileMode) { |
- key |= kRepeatTileMode; |
- } else { |
- key |= kMirrorTileMode; |
- } |
-#endif |
return key; |
} |
@@ -1090,183 +1030,56 @@ |
const char* outputColor, |
const char* inputColor, |
const SamplerHandle* texSamplers) { |
- switch (ge.getColorType()) { |
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
- case kHardStopCentered_ColorType: { |
- const char* t = gradientTValue; |
- const char* colors = uniformHandler->getUniformCStr(fColorsUni); |
- |
- fragBuilder->codeAppendf("float clamp_t = clamp(%s, 0.0, 1.0);", t); |
- |
- // Account for tile mode |
- if (SkShader::kRepeat_TileMode == ge.fTileMode) { |
- fragBuilder->codeAppendf("clamp_t = fract(%s);", t); |
- } else if (SkShader::kMirror_TileMode == ge.fTileMode) { |
- fragBuilder->codeAppendf("if (%s < 0.0 || %s > 1.0) {", t, t); |
- fragBuilder->codeAppendf(" if (mod(floor(%s), 2.0) == 0.0) {", t); |
- fragBuilder->codeAppendf(" clamp_t = fract(%s);", t); |
- fragBuilder->codeAppendf(" } else {"); |
- fragBuilder->codeAppendf(" clamp_t = 1.0 - fract(%s);", t); |
- fragBuilder->codeAppendf(" }"); |
- fragBuilder->codeAppendf("}"); |
- } |
- |
- // Calculate color |
- fragBuilder->codeAppendf("float relative_t = fract(2.0 * clamp_t);"); |
- if (SkShader::kClamp_TileMode == ge.fTileMode) { |
- fragBuilder->codeAppendf("relative_t += step(1.0, %s);", t); |
- } |
- fragBuilder->codeAppendf("vec4 colorTemp = mix(%s[0], %s[1], relative_t);", colors, |
- colors); |
- fragBuilder->codeAppendf("if (clamp_t >= 0.5) {"); |
- fragBuilder->codeAppendf(" colorTemp = mix(%s[2], %s[3], relative_t);", colors, |
- colors); |
- fragBuilder->codeAppendf("}"); |
- |
- if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) { |
- fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;"); |
- } |
- fragBuilder->codeAppendf("%s = %s;", outputColor, |
- (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str()); |
- |
- break; |
- } |
- |
- case kHardStopLeftEdged_ColorType: { |
- const char* t = gradientTValue; |
- const char* colors = uniformHandler->getUniformCStr(fColorsUni); |
- |
- fragBuilder->codeAppendf("float clamp_t = clamp(%s, 0.0, 1.0);", t); |
- |
- // Account for tile mode |
- if (SkShader::kRepeat_TileMode == ge.fTileMode) { |
- fragBuilder->codeAppendf("clamp_t = fract(%s);", t); |
- } else if (SkShader::kMirror_TileMode == ge.fTileMode) { |
- fragBuilder->codeAppendf("if (%s < 0.0 || %s > 1.0) {", t, t); |
- fragBuilder->codeAppendf(" if (mod(floor(%s), 2.0) == 0.0) {", t); |
- fragBuilder->codeAppendf(" clamp_t = fract(%s);", t); |
- fragBuilder->codeAppendf(" } else {"); |
- fragBuilder->codeAppendf(" clamp_t = 1.0 - fract(%s);", t); |
- fragBuilder->codeAppendf(" }"); |
- fragBuilder->codeAppendf("}"); |
- } |
- |
- fragBuilder->codeAppendf("vec4 colorTemp = mix(%s[1], %s[2], clamp_t);", colors, |
- colors); |
- if (SkShader::kClamp_TileMode == ge.fTileMode) { |
- fragBuilder->codeAppendf("if (%s < 0.0) {", t); |
- fragBuilder->codeAppendf(" colorTemp = %s[0];", colors); |
- fragBuilder->codeAppendf("}"); |
- } |
- |
- if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) { |
- fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;"); |
- } |
- fragBuilder->codeAppendf("%s = %s;", outputColor, |
- (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str()); |
- |
- break; |
- } |
- |
- case kHardStopRightEdged_ColorType: { |
- const char* t = gradientTValue; |
- const char* colors = uniformHandler->getUniformCStr(fColorsUni); |
- |
- fragBuilder->codeAppendf("float clamp_t = clamp(%s, 0.0, 1.0);", t); |
- |
- // Account for tile mode |
- if (SkShader::kRepeat_TileMode == ge.fTileMode) { |
- fragBuilder->codeAppendf("clamp_t = fract(%s);", t); |
- } else if (SkShader::kMirror_TileMode == ge.fTileMode) { |
- fragBuilder->codeAppendf("if (%s < 0.0 || %s > 1.0) {", t, t); |
- fragBuilder->codeAppendf(" if (mod(floor(%s), 2.0) == 0.0) {", t); |
- fragBuilder->codeAppendf(" clamp_t = fract(%s);", t); |
- fragBuilder->codeAppendf(" } else {"); |
- fragBuilder->codeAppendf(" clamp_t = 1.0 - fract(%s);", t); |
- fragBuilder->codeAppendf(" }"); |
- fragBuilder->codeAppendf("}"); |
- } |
- |
- fragBuilder->codeAppendf("vec4 colorTemp = mix(%s[0], %s[1], clamp_t);", colors, |
- colors); |
- if (SkShader::kClamp_TileMode == ge.fTileMode) { |
- fragBuilder->codeAppendf("if (%s > 1.0) {", t); |
- fragBuilder->codeAppendf(" colorTemp = %s[2];", colors); |
- fragBuilder->codeAppendf("}"); |
- } |
- |
- if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) { |
- fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;"); |
- } |
- fragBuilder->codeAppendf("%s = %s;", outputColor, |
- (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str()); |
- |
- break; |
- } |
-#endif |
- |
- case kTwo_ColorType: { |
- const char* t = gradientTValue; |
- const char* colors = uniformHandler->getUniformCStr(fColorsUni); |
- |
- fragBuilder->codeAppendf("vec4 colorTemp = mix(%s[0], %s[1], clamp(%s, 0.0, 1.0));", |
- colors, colors, t); |
- |
- // 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;"); |
- } |
- |
- fragBuilder->codeAppendf("%s = %s;", outputColor, |
- (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str()); |
- |
- break; |
- } |
- |
- case kThree_ColorType: { |
- const char* t = gradientTValue; |
- const char* colors = uniformHandler->getUniformCStr(fColorsUni); |
- |
- fragBuilder->codeAppendf("float oneMinus2t = 1.0 - (2.0 * %s);", t); |
- fragBuilder->codeAppendf("vec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s[0];", |
- colors); |
- if (!glslCaps->canUseMinAndAbsTogether()) { |
- // The Tegra3 compiler will sometimes never return if we have |
- // min(abs(oneMinus2t), 1.0), or do the abs first in a separate expression. |
- fragBuilder->codeAppendf("float minAbs = abs(oneMinus2t);"); |
- fragBuilder->codeAppendf("minAbs = minAbs > 1.0 ? 1.0 : minAbs;"); |
- fragBuilder->codeAppendf("colorTemp += (1.0 - minAbs) * %s[1];", colors); |
- } else { |
- fragBuilder->codeAppendf("colorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s[1];", |
- colors); |
- } |
- fragBuilder->codeAppendf("colorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s[2];", colors); |
- |
- if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) { |
- fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;"); |
- } |
- |
- fragBuilder->codeAppendf("%s = %s;", outputColor, |
- (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str()); |
- |
- break; |
- } |
- |
- case kTexture_ColorType: { |
- const char* fsyuni = uniformHandler->getUniformCStr(fFSYUni); |
- |
- fragBuilder->codeAppendf("vec2 coord = vec2(%s, %s);", gradientTValue, fsyuni); |
- fragBuilder->codeAppendf("%s = ", outputColor); |
- fragBuilder->appendTextureLookupAndModulate(inputColor, texSamplers[0], "coord"); |
- fragBuilder->codeAppend(";"); |
- |
- break; |
- } |
+ if (SkGradientShaderBase::kTwo_GpuColorType == ge.getColorType()){ |
+ fragBuilder->codeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n", |
+ uniformHandler->getUniformVariable(fColorStartUni).c_str(), |
+ uniformHandler->getUniformVariable(fColorEndUni).c_str(), |
+ gradientTValue); |
+ // Note that 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("\tcolorTemp.rgb *= colorTemp.a;\n"); |
+ } |
+ |
+ fragBuilder->codeAppendf("\t%s = %s;\n", outputColor, |
+ (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str()); |
+ } else if (SkGradientShaderBase::kThree_GpuColorType == ge.getColorType()) { |
+ fragBuilder->codeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n", |
+ gradientTValue); |
+ fragBuilder->codeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n", |
+ uniformHandler->getUniformVariable(fColorStartUni).c_str()); |
+ if (!glslCaps->canUseMinAndAbsTogether()) { |
+ // The Tegra3 compiler will sometimes never return if we have |
+ // min(abs(oneMinus2t), 1.0), or do the abs first in a separate expression. |
+ fragBuilder->codeAppend("\tfloat minAbs = abs(oneMinus2t);\n"); |
+ fragBuilder->codeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n"); |
+ fragBuilder->codeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n", |
+ uniformHandler->getUniformVariable(fColorMidUni).c_str()); |
+ } else { |
+ fragBuilder->codeAppendf("\tcolorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s;\n", |
+ uniformHandler->getUniformVariable(fColorMidUni).c_str()); |
+ } |
+ fragBuilder->codeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s;\n", |
+ uniformHandler->getUniformVariable(fColorEndUni).c_str()); |
+ if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) { |
+ fragBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n"); |
+ } |
+ |
+ fragBuilder->codeAppendf("\t%s = %s;\n", outputColor, |
+ (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str()); |
+ } else { |
+ fragBuilder->codeAppendf("\tvec2 coord = vec2(%s, %s);\n", |
+ gradientTValue, |
+ uniformHandler->getUniformVariable(fFSYUni).c_str()); |
+ fragBuilder->codeAppendf("\t%s = ", outputColor); |
+ fragBuilder->appendTextureLookupAndModulate(inputColor, |
+ texSamplers[0], |
+ "coord"); |
+ fragBuilder->codeAppend(";\n"); |
} |
} |
@@ -1279,87 +1092,56 @@ |
fIsOpaque = shader.isOpaque(); |
- fColorType = this->determineColorType(shader); |
- |
- if (kTexture_ColorType != fColorType) { |
- if (shader.fOrigColors) { |
- fColors = SkTDArray<SkColor>(shader.fOrigColors, shader.fColorCount); |
- } |
- |
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
- if (shader.fOrigPos) { |
- fPositions = SkTDArray<SkScalar>(shader.fOrigPos, shader.fColorCount); |
- } |
- |
- fTileMode = tileMode; |
-#endif |
- } |
- |
- switch (fColorType) { |
- // The two and three color specializations do not currently support tiling. |
- case kTwo_ColorType: |
- case kThree_ColorType: |
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
- case kHardStopLeftEdged_ColorType: |
- case kHardStopRightEdged_ColorType: |
- case kHardStopCentered_ColorType: |
-#endif |
- fRow = -1; |
- |
- if (SkGradientShader::kInterpolateColorsInPremul_Flag & shader.getGradFlags()) { |
- fPremulType = kBeforeInterp_PremulType; |
- } else { |
- fPremulType = kAfterInterp_PremulType; |
+ fColorType = shader.getGpuColorType(&fColors[0]); |
+ |
+ // The two and three color specializations do not currently support tiling. |
+ if (SkGradientShaderBase::kTwo_GpuColorType == fColorType || |
+ SkGradientShaderBase::kThree_GpuColorType == fColorType) { |
+ fRow = -1; |
+ |
+ if (SkGradientShader::kInterpolateColorsInPremul_Flag & shader.getGradFlags()) { |
+ fPremulType = kBeforeInterp_PremulType; |
+ } else { |
+ fPremulType = kAfterInterp_PremulType; |
+ } |
+ fCoordTransform.reset(kCoordSet, matrix); |
+ } else { |
+ // doesn't matter how this is set, just be consistent because it is part of the effect key. |
+ fPremulType = kBeforeInterp_PremulType; |
+ SkBitmap bitmap; |
+ shader.getGradientTableBitmap(&bitmap); |
+ |
+ GrTextureStripAtlas::Desc desc; |
+ desc.fWidth = bitmap.width(); |
+ desc.fHeight = 32; |
+ desc.fRowHeight = bitmap.height(); |
+ desc.fContext = ctx; |
+ desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *ctx->caps()); |
+ fAtlas = GrTextureStripAtlas::GetAtlas(desc); |
+ SkASSERT(fAtlas); |
+ |
+ // We always filter the gradient table. Each table is one row of a texture, always y-clamp. |
+ GrTextureParams params; |
+ params.setFilterMode(GrTextureParams::kBilerp_FilterMode); |
+ params.setTileModeX(tileMode); |
+ |
+ fRow = fAtlas->lockRow(bitmap); |
+ if (-1 != fRow) { |
+ fYCoord = fAtlas->getYOffset(fRow) + SK_ScalarHalf * fAtlas->getNormalizedTexelHeight(); |
+ fCoordTransform.reset(kCoordSet, matrix, fAtlas->getTexture(), params.filterMode()); |
+ fTextureAccess.reset(fAtlas->getTexture(), params); |
+ } else { |
+ SkAutoTUnref<GrTexture> texture( |
+ GrRefCachedBitmapTexture(ctx, bitmap, params, SkSourceGammaTreatment::kRespect)); |
+ if (!texture) { |
+ return; |
} |
- |
- fCoordTransform.reset(kCoordSet, matrix); |
- |
- break; |
- case kTexture_ColorType: |
- // doesn't matter how this is set, just be consistent because it is part of the |
- // effect key. |
- fPremulType = kBeforeInterp_PremulType; |
- |
- SkBitmap bitmap; |
- shader.getGradientTableBitmap(&bitmap); |
- |
- GrTextureStripAtlas::Desc desc; |
- desc.fWidth = bitmap.width(); |
- desc.fHeight = 32; |
- desc.fRowHeight = bitmap.height(); |
- desc.fContext = ctx; |
- desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *ctx->caps()); |
- fAtlas = GrTextureStripAtlas::GetAtlas(desc); |
- SkASSERT(fAtlas); |
- |
- // We always filter the gradient table. Each table is one row of a texture, always |
- // y-clamp. |
- GrTextureParams params; |
- params.setFilterMode(GrTextureParams::kBilerp_FilterMode); |
- params.setTileModeX(tileMode); |
- |
- fRow = fAtlas->lockRow(bitmap); |
- if (-1 != fRow) { |
- fYCoord = fAtlas->getYOffset(fRow)+SK_ScalarHalf*fAtlas->getNormalizedTexelHeight(); |
- fCoordTransform.reset(kCoordSet, matrix, fAtlas->getTexture(), params.filterMode()); |
- fTextureAccess.reset(fAtlas->getTexture(), params); |
- } else { |
- SkAutoTUnref<GrTexture> texture( |
- GrRefCachedBitmapTexture(ctx, bitmap, params, |
- SkSourceGammaTreatment::kRespect)); |
- if (!texture) { |
- return; |
- } |
- fCoordTransform.reset(kCoordSet, matrix, texture, params.filterMode()); |
- fTextureAccess.reset(texture, params); |
- fYCoord = SK_ScalarHalf; |
- } |
- |
- this->addTextureAccess(&fTextureAccess); |
- |
- break; |
- } |
- |
+ fCoordTransform.reset(kCoordSet, matrix, texture, params.filterMode()); |
+ fTextureAccess.reset(texture, params); |
+ fYCoord = SK_ScalarHalf; |
+ } |
+ this->addTextureAccess(&fTextureAccess); |
+ } |
this->addCoordTransform(&fCoordTransform); |
} |
@@ -1370,27 +1152,30 @@ |
} |
bool GrGradientEffect::onIsEqual(const GrFragmentProcessor& processor) const { |
- const GrGradientEffect& ge = processor.cast<GrGradientEffect>(); |
- |
- if (this->fColorType == ge.getColorType()) { |
- if (kTexture_ColorType == fColorType) { |
- if (fYCoord != ge.getYCoord()) { |
+ const GrGradientEffect& s = processor.cast<GrGradientEffect>(); |
+ |
+ if (this->fColorType == s.getColorType()){ |
+ |
+ if (SkGradientShaderBase::kTwo_GpuColorType == fColorType) { |
+ if (this->getPremulType() != s.getPremulType() || |
+ *this->getColors(0) != *s.getColors(0) || |
+ *this->getColors(1) != *s.getColors(1)) { |
+ return false; |
+ } |
+ } else if (SkGradientShaderBase::kThree_GpuColorType == fColorType) { |
+ if (this->getPremulType() != s.getPremulType() || |
+ *this->getColors(0) != *s.getColors(0) || |
+ *this->getColors(1) != *s.getColors(1) || |
+ *this->getColors(2) != *s.getColors(2)) { |
return false; |
} |
} else { |
- if (this->getPremulType() != ge.getPremulType() || |
- this->fColors.count() != ge.fColors.count()) { |
+ if (fYCoord != s.getYCoord()) { |
return false; |
} |
- |
- for (int i = 0; i < this->fColors.count(); i++) { |
- if (*this->getColors(i) != *ge.getColors(i)) { |
- return false; |
- } |
- } |
- } |
- |
- SkASSERT(this->useAtlas() == ge.useAtlas()); |
+ } |
+ |
+ SkASSERT(this->useAtlas() == s.useAtlas()); |
return true; |
} |