aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/gradients/SkGradientShader.cpp
diff options
context:
space:
mode:
authorGravatar fmenozzi <fmenozzi@google.com>2016-08-10 13:01:35 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-08-10 13:01:35 -0700
commit568de46cb1ac9d5a996fb52c6cf85568415a14ea (patch)
tree6e53918ffc79d7f502f4bc5eedbdcd7beff756b1 /src/effects/gradients/SkGradientShader.cpp
parent80e38ac117371129df2eb27fe674c7ca84256971 (diff)
Revert "Remove generalized gradient code"
Diffstat (limited to 'src/effects/gradients/SkGradientShader.cpp')
-rw-r--r--src/effects/gradients/SkGradientShader.cpp598
1 files changed, 190 insertions, 408 deletions
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index 2c686ece28..820c5b225d 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -228,52 +228,22 @@ void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const {
desc.flatten(buffer);
}
-#if SK_SUPPORT_GPU
-
-static inline bool close_to_one_half(const SkFixed& val) {
- return SkScalarNearlyEqual(SkFixedToScalar(val), SK_ScalarHalf);
-}
-
-GrGradientEffect::ColorType GrGradientEffect::determineColorTypeAndNumHardStops(
- 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;
- }
- }
+SkGradientShaderBase::GpuColorType SkGradientShaderBase::getGpuColorType(SkColor colors[3]) const {
+ if (fColorCount <= 3) {
+ memcpy(colors, fOrigColors, fColorCount * sizeof(SkColor));
}
-#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;
+ 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_ColorType;
+ return kTexture_GpuColorType;
}
-#endif
void SkGradientShaderBase::FlipGradientColors(SkColor* colorDst, Rec* recDst,
SkColor* colorSrc, Rec* recSrc,
@@ -941,146 +911,113 @@ SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
#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::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_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_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_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;
+ 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));
}
- case GrGradientEffect::kTexture_ColorType: {
- SkScalar yCoord = e.getYCoord();
- if (yCoord != fCachedYCoord) {
- pdman.set1f(fFSYUni, yCoord);
- fCachedYCoord = yCoord;
- }
- break;
+ } 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 (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
- key |= kPremulBeforeInterpKey;
- }
-
- if (GrGradientEffect::kTwo_ColorType == e.getColorType()) {
+ if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()) {
key |= kTwoColorKey;
- } else if (GrGradientEffect::kThree_ColorType == e.getColorType()) {
+ } else if (SkGradientShaderBase::kThree_GpuColorType == 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;
+
+ if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
+ key |= kPremulBeforeInterpKey;
}
-#endif
return key;
}
@@ -1093,183 +1030,56 @@ void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui
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;
+ 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");
}
- 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;
+ 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());
}
-
- 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;
+ 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");
}
- 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;
- }
+ 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");
}
}
@@ -1282,87 +1092,56 @@ GrGradientEffect::GrGradientEffect(GrContext* ctx,
fIsOpaque = shader.isOpaque();
- fColorType = this->determineColorTypeAndNumHardStops(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]);
- fCoordTransform.reset(kCoordSet, matrix);
+ // The two and three color specializations do not currently support tiling.
+ if (SkGradientShaderBase::kTwo_GpuColorType == fColorType ||
+ SkGradientShaderBase::kThree_GpuColorType == fColorType) {
+ fRow = -1;
- break;
- case kTexture_ColorType:
- // doesn't matter how this is set, just be consistent because it is part of the
- // effect key.
+ if (SkGradientShader::kInterpolateColorsInPremul_Flag & shader.getGradFlags()) {
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;
+ } 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;
}
-
- this->addTextureAccess(&fTextureAccess);
-
- break;
+ fCoordTransform.reset(kCoordSet, matrix, texture, params.filterMode());
+ fTextureAccess.reset(texture, params);
+ fYCoord = SK_ScalarHalf;
+ }
+ this->addTextureAccess(&fTextureAccess);
}
-
this->addCoordTransform(&fCoordTransform);
}
@@ -1373,27 +1152,30 @@ GrGradientEffect::~GrGradientEffect() {
}
bool GrGradientEffect::onIsEqual(const GrFragmentProcessor& processor) const {
- const GrGradientEffect& ge = processor.cast<GrGradientEffect>();
+ const GrGradientEffect& s = processor.cast<GrGradientEffect>();
+
+ if (this->fColorType == s.getColorType()){
- if (this->fColorType == ge.getColorType()) {
- if (kTexture_ColorType == fColorType) {
- if (fYCoord != ge.getYCoord()) {
+ 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 (this->getPremulType() != ge.getPremulType() ||
- this->fColors.count() != ge.fColors.count()) {
+ } 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;
}
-
- for (int i = 0; i < this->fColors.count(); i++) {
- if (*this->getColors(i) != *ge.getColors(i)) {
- return false;
- }
+ } else {
+ if (fYCoord != s.getYCoord()) {
+ return false;
}
}
- SkASSERT(this->useAtlas() == ge.useAtlas());
+ SkASSERT(this->useAtlas() == s.useAtlas());
return true;
}