diff options
author | 2016-08-10 13:01:35 -0700 | |
---|---|---|
committer | 2016-08-10 13:01:35 -0700 | |
commit | 568de46cb1ac9d5a996fb52c6cf85568415a14ea (patch) | |
tree | 6e53918ffc79d7f502f4bc5eedbdcd7beff756b1 /src/effects/gradients/SkGradientShader.cpp | |
parent | 80e38ac117371129df2eb27fe674c7ca84256971 (diff) |
Revert "Remove generalized gradient code"
This reverts commit 0c63006b88a16e3418d92852a62771615799839d.
BUG=skia:
NOTREECHECKS=true
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2235953003
Review-Url: https://codereview.chromium.org/2235953003
Diffstat (limited to 'src/effects/gradients/SkGradientShader.cpp')
-rw-r--r-- | src/effects/gradients/SkGradientShader.cpp | 598 |
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; } |