aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/gradients/SkGradientShader.cpp
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2016-10-13 16:08:36 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-10-13 20:30:20 +0000
commit466ad9986851d48cd594efb9a2a5de27c620cdea (patch)
treea8eb4e3a72e23c9c2e9e3342817f60edd003329f /src/effects/gradients/SkGradientShader.cpp
parent22f939e849013b7fc51374c289b5bf37e63dfdb1 (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>
Diffstat (limited to 'src/effects/gradients/SkGradientShader.cpp')
-rw-r--r--src/effects/gradients/SkGradientShader.cpp90
1 files changed, 49 insertions, 41 deletions
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 {