diff options
-rw-r--r-- | gm/gradients.cpp | 12 | ||||
-rw-r--r-- | src/shaders/gradients/SkGradientShader.cpp | 44 | ||||
-rw-r--r-- | src/shaders/gradients/SkGradientShaderPriv.h | 12 |
3 files changed, 48 insertions, 20 deletions
diff --git a/gm/gradients.cpp b/gm/gradients.cpp index 2a1f9031bb..08d65f7d12 100644 --- a/gm/gradients.cpp +++ b/gm/gradients.cpp @@ -1074,14 +1074,15 @@ DEF_SIMPLE_GM(sweep_tiling, canvas, 690, 512) { } // Exercises the special-case Ganesh gradient effects. -DEF_SIMPLE_GM(gradients_interesting, canvas, 640, 1080) { +DEF_SIMPLE_GM(gradients_interesting, canvas, 640, 1300) { static const SkColor colors2[] = { SK_ColorRED, SK_ColorBLUE }; static const SkColor colors3[] = { SK_ColorRED, SK_ColorYELLOW, SK_ColorBLUE }; static const SkColor colors4[] = { SK_ColorRED, SK_ColorYELLOW, SK_ColorYELLOW, SK_ColorBLUE }; - static const SkScalar hardLeft[] = { 0, 0, 1 }; - static const SkScalar hardRight[] = { 0, 1, 1 }; - static const SkScalar hardCenter[] = { 0, .5f, .5f, 1 }; + static const SkScalar softRight[] = { 0, .999f, 1 }; // Based on Android launcher "clipping" + static const SkScalar hardLeft[] = { 0, 0, 1 }; + static const SkScalar hardRight[] = { 0, 1, 1 }; + static const SkScalar hardCenter[] = { 0, .5f, .5f, 1 }; static const struct { const SkColor* colors; @@ -1089,7 +1090,8 @@ DEF_SIMPLE_GM(gradients_interesting, canvas, 640, 1080) { int count; } configs[] = { { colors2, nullptr, 2 }, // kTwo_ColorType - { colors3, nullptr, 3 }, // kThree_ColorType + { colors3, nullptr, 3 }, // kSymmetricThree_ColorType + { colors3, softRight, 3 }, // kThree_ColorType { colors3, hardLeft, 3 }, // kHardStopLeftEdged_ColorType { colors3, hardRight, 3 }, // kHardStopRightEdged_ColorType { colors4, hardCenter, 4 }, // kSingleHardStop_ColorType diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp index 64d3b4820a..45f25cd7f0 100644 --- a/src/shaders/gradients/SkGradientShader.cpp +++ b/src/shaders/gradients/SkGradientShader.cpp @@ -1312,6 +1312,7 @@ static inline int color_type_to_color_count(GrGradientEffect::ColorType colorTyp case GrGradientEffect::kTwo_ColorType: return 2; case GrGradientEffect::kThree_ColorType: + case GrGradientEffect::kSymmetricThree_ColorType: return 3; case GrGradientEffect::kTexture_ColorType: return 0; @@ -1348,9 +1349,9 @@ GrGradientEffect::ColorType GrGradientEffect::determineColorType( if (2 == shader.fColorCount) { return kTwo_ColorType; - } else if (3 == shader.fColorCount && - close_to_one_half(shader.getRecs()[1].fPos)) { - return kThree_ColorType; + } else if (3 == shader.fColorCount) { + return close_to_one_half(shader.getRecs()[1].fPos) ? kSymmetricThree_ColorType + : kThree_ColorType; } return kTexture_ColorType; @@ -1364,9 +1365,9 @@ void GrGradientEffect::GLSLProcessor::emitUniforms(GrGLSLUniformHandler* uniform kDefault_GrSLPrecision, "Colors", colorCount); - if (ge.fColorType == kSingleHardStop_ColorType) { - fHardStopT = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, - kDefault_GrSLPrecision, "HardStopT"); + if (kSingleHardStop_ColorType == ge.fColorType || kThree_ColorType == ge.fColorType) { + fExtraStopT = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, + kDefault_GrSLPrecision, "ExtraStopT"); } } else { fFSYUni = uniformHandler->addUniform(kFragment_GrShaderFlag, @@ -1468,12 +1469,13 @@ void GrGradientEffect::GLSLProcessor::onSetData(const GrGLSLProgramDataManager& switch (e.getColorType()) { case GrGradientEffect::kSingleHardStop_ColorType: - pdman.set1f(fHardStopT, e.fPositions[1]); + case GrGradientEffect::kThree_ColorType: + pdman.set1f(fExtraStopT, e.fPositions[1]); // fall through case GrGradientEffect::kHardStopLeftEdged_ColorType: case GrGradientEffect::kHardStopRightEdged_ColorType: case GrGradientEffect::kTwo_ColorType: - case GrGradientEffect::kThree_ColorType: { + case GrGradientEffect::kSymmetricThree_ColorType: { if (e.fColors4f.count() > 0) { // Gamma-correct / color-space aware if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { @@ -1522,6 +1524,8 @@ uint32_t GrGradientEffect::GLSLProcessor::GenBaseGradientKey(const GrProcessor& key |= kTwoColorKey; } else if (GrGradientEffect::kThree_ColorType == e.getColorType()) { key |= kThreeColorKey; + } else if (GrGradientEffect::kSymmetricThree_ColorType == e.getColorType()) { + key |= kSymmetricThreeColorKey; } else if (GrGradientEffect::kSingleHardStop_ColorType == e.getColorType()) { key |= kHardStopCenteredKey; } else if (GrGradientEffect::kHardStopLeftEdged_ColorType == e.getColorType()) { @@ -1572,7 +1576,7 @@ void GrGradientEffect::GLSLProcessor::emitAnalyticalColor(GrGLSLFPFragmentBuilde const char* colors = uniformHandler->getUniformCStr(fColorsUni); switch (ge.getColorType()) { case kSingleHardStop_ColorType: { - const char* stopT = uniformHandler->getUniformCStr(fHardStopT); + const char* stopT = uniformHandler->getUniformCStr(fExtraStopT); fragBuilder->codeAppend ("float4 start, end;"); fragBuilder->codeAppend ("float relative_t;"); @@ -1622,6 +1626,25 @@ void GrGradientEffect::GLSLProcessor::emitAnalyticalColor(GrGLSLFPFragmentBuilde } case kThree_ColorType: { + const char* stopT = uniformHandler->getUniformCStr(fExtraStopT); + + fragBuilder->codeAppend("float4 start, end;"); + fragBuilder->codeAppend("float relative_t;"); + fragBuilder->codeAppendf("if (clamp_t < %s) {", stopT); + fragBuilder->codeAppendf(" start = %s[0];", colors); + fragBuilder->codeAppendf(" end = %s[1];", colors); + fragBuilder->codeAppendf(" relative_t = clamp_t / %s;", stopT); + fragBuilder->codeAppend("} else {"); + fragBuilder->codeAppendf(" start = %s[1];", colors); + fragBuilder->codeAppendf(" end = %s[2];", colors); + fragBuilder->codeAppendf(" relative_t = (clamp_t - %s) / (1 - %s);", stopT, stopT); + fragBuilder->codeAppend("}"); + fragBuilder->codeAppend("float4 colorTemp = mix(start, end, relative_t);"); + + break; + } + + case kSymmetricThree_ColorType: { fragBuilder->codeAppendf("float oneMinus2t = 1.0 - (2.0 * clamp_t);"); fragBuilder->codeAppendf("float4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s[0];", colors); @@ -1715,6 +1738,7 @@ GrGradientEffect::GrGradientEffect(const CreateArgs& args, bool isOpaque) // The two and three color specializations do not currently support tiling. case kTwo_ColorType: case kThree_ColorType: + case kSymmetricThree_ColorType: case kHardStopLeftEdged_ColorType: case kHardStopRightEdged_ColorType: case kSingleHardStop_ColorType: @@ -1843,7 +1867,7 @@ bool GrGradientEffect::onIsEqual(const GrFragmentProcessor& processor) const { return false; } } else { - if (kSingleHardStop_ColorType == fColorType) { + if (kSingleHardStop_ColorType == fColorType || kThree_ColorType == fColorType) { if (!SkScalarNearlyEqual(ge.fPositions[1], fPositions[1])) { return false; } diff --git a/src/shaders/gradients/SkGradientShaderPriv.h b/src/shaders/gradients/SkGradientShaderPriv.h index 97c1e842c4..fb1447ed05 100644 --- a/src/shaders/gradients/SkGradientShaderPriv.h +++ b/src/shaders/gradients/SkGradientShaderPriv.h @@ -388,7 +388,8 @@ public: enum ColorType { kTwo_ColorType, - kThree_ColorType, // Symmetric three color + kThree_ColorType, // 0, t, 1 + kSymmetricThree_ColorType, kTexture_ColorType, kSingleHardStop_ColorType, // 0, t, t, 1 kHardStopLeftEdged_ColorType, // 0, 0, 1 @@ -541,10 +542,11 @@ private: // hard stop cases (neither means using texture atlas) kTwoColorKey = 2, kThreeColorKey = 4, + kSymmetricThreeColorKey = 6, - kHardStopCenteredKey = 6, - kHardStopZeroZeroOneKey = 8, - kHardStopZeroOneOneKey = 10, + kHardStopCenteredKey = 8, + kHardStopZeroZeroOneKey = 10, + kHardStopZeroOneOneKey = 12, // Next two bits for tile mode kClampTileMode = 16, @@ -557,7 +559,7 @@ private: SkScalar fCachedYCoord; GrGLSLProgramDataManager::UniformHandle fColorsUni; - GrGLSLProgramDataManager::UniformHandle fHardStopT; + GrGLSLProgramDataManager::UniformHandle fExtraStopT; GrGLSLProgramDataManager::UniformHandle fFSYUni; GrGLSLColorSpaceXformHelper fColorSpaceHelper; |