diff options
author | Brian Salomon <bsalomon@google.com> | 2016-10-13 16:08:36 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-10-13 20:30:20 +0000 |
commit | 466ad9986851d48cd594efb9a2a5de27c620cdea (patch) | |
tree | a8eb4e3a72e23c9c2e9e3342817f60edd003329f | |
parent | 22f939e849013b7fc51374c289b5bf37e63dfdb1 (diff) |
Slightly generalize GPU hard stop gradient implementation.
With this CL we handle single off-center hardstop gradients.
BUG=chromium:543625
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3303
Change-Id: Ic754e87469475ce15865c54055b8ed492e1d826d
Reviewed-on: https://skia-review.googlesource.com/3303
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
-rw-r--r-- | gm/hardstop_gradients.cpp | 26 | ||||
-rw-r--r-- | src/effects/gradients/SkGradientShader.cpp | 90 | ||||
-rw-r--r-- | src/effects/gradients/SkGradientShaderPriv.h | 3 |
3 files changed, 66 insertions, 53 deletions
diff --git a/gm/hardstop_gradients.cpp b/gm/hardstop_gradients.cpp index 846465ec19..2ab2ed9c89 100644 --- a/gm/hardstop_gradients.cpp +++ b/gm/hardstop_gradients.cpp @@ -14,15 +14,16 @@ * order to highlight the differences between tile modes, the gradient * starts and ends at 30 pixel inset from either side of the rectangle. * - * | Clamp Repeat Mirror - * ___________________________|___________________________________________ - * 2-color | rect00 rect01 rect02 - * 3-color even | rect10 rect11 rect12 - * 3-color texture | rect20 rect21 rect22 - * 5-color hard stop | rect30 rect31 rect32 - * 4-color hard stop centered | rect40 rect41 rect42 - * 3-color hard stop 001 | rect50 rect51 rect52 - * 3-color hard stop 011 | rect60 rect61 rect62 + * | Clamp Repeat Mirror + * _____________________________|___________________________________________ + * 2-color | rect00 rect01 rect02 + * 3-color even | rect10 rect11 rect12 + * 3-color texture | rect20 rect21 rect22 + * 5-color hard stop | rect30 rect31 rect32 + * 4-color hard stop centered | rect40 rect41 rect42 + * 3-color hard stop 001 | rect50 rect51 rect52 + * 3-color hard stop 011 | rect60 rect61 rect62 + * 4-color hard stop off-center | rect70 rect71 rect72 * * The first three rows are cases covered by pre-hard-stop code; simple * 2-color gradients, 3-color gradients with the middle color centered, @@ -32,7 +33,7 @@ * is a generic hard stop gradient, while the three subsequent rows deal * with special cases of hard stop gradients; centered hard stop gradients * (with t-values 0, 0.5, 0.5, 1), and two edge cases (with t-values - * 0, 0, 1 and 0, 1, 1). + * 0, 0, 1 and 0, 1, 1). The final row has a single off-center hard stop. */ #include "gm.h" @@ -42,7 +43,7 @@ const int WIDTH = 500; const int HEIGHT = 500; -const int NUM_ROWS = 7; +const int NUM_ROWS = 8; const int NUM_COLS = 3; const int CELL_WIDTH = WIDTH / NUM_COLS; @@ -108,6 +109,7 @@ protected: SkScalar row5[] = {0.00f, 0.50f, 0.50f, 1.00f}; SkScalar row6[] = {0.00f, 0.00f, 1.00f}; SkScalar row7[] = {0.00f, 1.00f, 1.00f}; + SkScalar row8[] = {0.00f, 0.30f, 0.30f, 1.00f}; SkScalar* positions[NUM_ROWS] = { nullptr, @@ -117,6 +119,7 @@ protected: row5, row6, row7, + row8, }; int numGradientColors[NUM_ROWS] = { @@ -127,6 +130,7 @@ protected: 4, 3, 3, + 4, }; SkShader::TileMode tilemodes[NUM_COLS] = { diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp index bedc6e8868..eee2cbfadc 100644 --- a/src/effects/gradients/SkGradientShader.cpp +++ b/src/effects/gradients/SkGradientShader.cpp @@ -1125,7 +1125,7 @@ static inline bool close_to_one_half(const SkFixed& val) { 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: + case GrGradientEffect::kSingleHardStop_ColorType: return 4; case GrGradientEffect::kHardStopLeftEdged_ColorType: case GrGradientEffect::kHardStopRightEdged_ColorType: @@ -1149,11 +1149,10 @@ GrGradientEffect::ColorType GrGradientEffect::determineColorType( 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[1], shader.fOrigPos[2]) && SkScalarNearlyEqual(shader.fOrigPos[3], 1.0f)) { - return kHardStopCentered_ColorType; + return kSingleHardStop_ColorType; } } else if (3 == shader.fColorCount) { if (SkScalarNearlyEqual(shader.fOrigPos[0], 0.0f) && @@ -1191,6 +1190,10 @@ 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"); + } } else { fFSYUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, @@ -1291,7 +1294,9 @@ void GrGradientEffect::GLSLProcessor::onSetData(const GrGLSLProgramDataManager& switch (e.getColorType()) { #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS - case GrGradientEffect::kHardStopCentered_ColorType: + case GrGradientEffect::kSingleHardStop_ColorType: + pdman.set1f(fHardStopT, e.fPositions[1]); + // fall through case GrGradientEffect::kHardStopLeftEdged_ColorType: case GrGradientEffect::kHardStopRightEdged_ColorType: #endif @@ -1347,7 +1352,7 @@ uint32_t GrGradientEffect::GLSLProcessor::GenBaseGradientKey(const GrProcessor& key |= kThreeColorKey; } #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS - else if (GrGradientEffect::kHardStopCentered_ColorType == e.getColorType()) { + else if (GrGradientEffect::kSingleHardStop_ColorType == e.getColorType()) { key |= kHardStopCenteredKey; } else if (GrGradientEffect::kHardStopLeftEdged_ColorType == e.getColorType()) { key |= kHardStopZeroZeroOneKey; @@ -1379,9 +1384,10 @@ void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui const TextureSamplers& texSamplers) { switch (ge.getColorType()) { #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS - case kHardStopCentered_ColorType: { + case kSingleHardStop_ColorType: { const char* t = gradientTValue; const char* colors = uniformHandler->getUniformCStr(fColorsUni); + const char* stopT = uniformHandler->getUniformCStr(fHardStopT); fragBuilder->codeAppendf("float clamp_t = clamp(%s, 0.0, 1.0);", t); @@ -1399,18 +1405,18 @@ void GrGradientEffect::GLSLProcessor::emitColor(GrGLSLFPFragmentBuilder* fragBui } // 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 start = %s[0];", colors); - fragBuilder->codeAppendf("vec4 end = %s[1];", colors); - fragBuilder->codeAppendf("if (clamp_t >= 0.5) {"); + fragBuilder->codeAppend ("vec4 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[2];", colors); fragBuilder->codeAppendf(" end = %s[3];", colors); - fragBuilder->codeAppendf("}"); - fragBuilder->codeAppendf("vec4 colorTemp = mix(start, end, relative_t);"); + fragBuilder->codeAppendf(" relative_t = (clamp_t - %s) / (1 - %s);", stopT, stopT); + fragBuilder->codeAppend ("}"); + fragBuilder->codeAppend ("vec4 colorTemp = mix(start, end, relative_t);"); if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) { fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;"); @@ -1599,7 +1605,7 @@ GrGradientEffect::GrGradientEffect(const CreateArgs& args) { #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS case kHardStopLeftEdged_ColorType: case kHardStopRightEdged_ColorType: - case kHardStopCentered_ColorType: + case kSingleHardStop_ColorType: #endif fRow = -1; @@ -1683,36 +1689,38 @@ GrGradientEffect::~GrGradientEffect() { 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()) { - return false; - } - } else { - if (this->getPremulType() != ge.getPremulType() || - this->fColors.count() != ge.fColors.count() || - this->fColors4f.count() != ge.fColors4f.count()) { + if (this->fColorType != ge.getColorType()) { + return false; + } + SkASSERT(this->useAtlas() == ge.useAtlas()); + if (kTexture_ColorType == fColorType) { + if (fYCoord != ge.getYCoord()) { + return false; + } + } else { + if (kSingleHardStop_ColorType == fColorType) { + if (!SkScalarNearlyEqual(ge.fPositions[1], fPositions[1])) { return false; } + } + if (this->getPremulType() != ge.getPremulType() || + this->fColors.count() != ge.fColors.count() || + this->fColors4f.count() != ge.fColors4f.count()) { + return false; + } - for (int i = 0; i < this->fColors.count(); i++) { - if (*this->getColors(i) != *ge.getColors(i)) { - return false; - } + for (int i = 0; i < this->fColors.count(); i++) { + if (*this->getColors(i) != *ge.getColors(i)) { + return false; } - for (int i = 0; i < this->fColors4f.count(); i++) { - if (*this->getColors4f(i) != *ge.getColors4f(i)) { - return false; - } + } + for (int i = 0; i < this->fColors4f.count(); i++) { + if (*this->getColors4f(i) != *ge.getColors4f(i)) { + return false; } } - - - SkASSERT(this->useAtlas() == ge.useAtlas()); - return GrColorSpaceXform::Equals(this->fColorSpaceXform.get(), ge.fColorSpaceXform.get()); } - - return false; + return GrColorSpaceXform::Equals(this->fColorSpaceXform.get(), ge.fColorSpaceXform.get()); } void GrGradientEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h index d94363d466..36ccab04e1 100644 --- a/src/effects/gradients/SkGradientShaderPriv.h +++ b/src/effects/gradients/SkGradientShaderPriv.h @@ -363,7 +363,7 @@ public: kTexture_ColorType, #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS - kHardStopCentered_ColorType, // 0, 0.5, 0.5, 1 + kSingleHardStop_ColorType, // 0, t, t, 1 kHardStopLeftEdged_ColorType, // 0, 0, 1 kHardStopRightEdged_ColorType, // 0, 1, 1 #endif @@ -510,6 +510,7 @@ private: SkScalar fCachedYCoord; GrGLSLProgramDataManager::UniformHandle fColorsUni; + GrGLSLProgramDataManager::UniformHandle fHardStopT; GrGLSLProgramDataManager::UniformHandle fFSYUni; GrGLSLProgramDataManager::UniformHandle fColorSpaceXformUni; |