aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2017-09-12 11:20:56 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-12 15:39:00 +0000
commit2ab4b2b871c01aa3dd6d2e43883461c722f01680 (patch)
tree8e3c242983ed75b99a7c419c5cce946acf6e8341 /src
parenta6b646986bf554e9f537494cfe1d7d577fdac796 (diff)
Remove symmetric three stop special case
Just let the general three-stop shader handle all three-stop gradients. Also, pre-compute values derived from the middle stop to remove all division (and actually convert computation to FMA form). Bug: skia: Change-Id: I1aae069d929d1a942c38aa2e2f3fd5fb7d9b2f10 Reviewed-on: https://skia-review.googlesource.com/45800 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/shaders/gradients/SkGradientShader.cpp55
-rw-r--r--src/shaders/gradients/SkGradientShaderPriv.h8
2 files changed, 26 insertions, 37 deletions
diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp
index 45f25cd7f0..9d95f997f0 100644
--- a/src/shaders/gradients/SkGradientShader.cpp
+++ b/src/shaders/gradients/SkGradientShader.cpp
@@ -1298,10 +1298,6 @@ SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
#include "glsl/GrGLSLUniformHandler.h"
#include "SkGr.h"
-static inline bool close_to_one_half(const SkFixed& val) {
- return SkScalarNearlyEqual(SkFixedToScalar(val), SK_ScalarHalf);
-}
-
static inline int color_type_to_color_count(GrGradientEffect::ColorType colorType) {
switch (colorType) {
case GrGradientEffect::kSingleHardStop_ColorType:
@@ -1312,7 +1308,6 @@ 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;
@@ -1350,8 +1345,7 @@ GrGradientEffect::ColorType GrGradientEffect::determineColorType(
if (2 == shader.fColorCount) {
return kTwo_ColorType;
} else if (3 == shader.fColorCount) {
- return close_to_one_half(shader.getRecs()[1].fPos) ? kSymmetricThree_ColorType
- : kThree_ColorType;
+ return kThree_ColorType;
}
return kTexture_ColorType;
@@ -1366,8 +1360,8 @@ void GrGradientEffect::GLSLProcessor::emitUniforms(GrGLSLUniformHandler* uniform
"Colors",
colorCount);
if (kSingleHardStop_ColorType == ge.fColorType || kThree_ColorType == ge.fColorType) {
- fExtraStopT = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType,
- kDefault_GrSLPrecision, "ExtraStopT");
+ fExtraStopT = uniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType,
+ kHigh_GrSLPrecision, "ExtraStopT");
}
} else {
fFSYUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
@@ -1470,12 +1464,16 @@ void GrGradientEffect::GLSLProcessor::onSetData(const GrGLSLProgramDataManager&
switch (e.getColorType()) {
case GrGradientEffect::kSingleHardStop_ColorType:
case GrGradientEffect::kThree_ColorType:
- pdman.set1f(fExtraStopT, e.fPositions[1]);
+ // ( t, 1/t, 1/(1-t), t/(1-t) )
+ // This lets us compute relative t on either side of the stop with at most a single FMA
+ pdman.set4f(fExtraStopT, e.fPositions[1],
+ 1.0f / e.fPositions[1],
+ 1.0f / (1.0f - e.fPositions[1]),
+ e.fPositions[1] / (1.0f - e.fPositions[1]));
// fall through
case GrGradientEffect::kHardStopLeftEdged_ColorType:
case GrGradientEffect::kHardStopRightEdged_ColorType:
- case GrGradientEffect::kTwo_ColorType:
- case GrGradientEffect::kSymmetricThree_ColorType: {
+ case GrGradientEffect::kTwo_ColorType: {
if (e.fColors4f.count() > 0) {
// Gamma-correct / color-space aware
if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
@@ -1524,8 +1522,6 @@ 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()) {
@@ -1576,18 +1572,20 @@ void GrGradientEffect::GLSLProcessor::emitAnalyticalColor(GrGLSLFPFragmentBuilde
const char* colors = uniformHandler->getUniformCStr(fColorsUni);
switch (ge.getColorType()) {
case kSingleHardStop_ColorType: {
+ // (t, 1/t, 1/(1-t), t/(1-t))
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("if (clamp_t < %s.x) {", stopT);
fragBuilder->codeAppendf(" start = %s[0];", colors);
fragBuilder->codeAppendf(" end = %s[1];", colors);
- fragBuilder->codeAppendf(" relative_t = clamp_t / %s;", stopT);
+ fragBuilder->codeAppendf(" relative_t = clamp_t * %s.y;", stopT);
fragBuilder->codeAppend ("} else {");
fragBuilder->codeAppendf(" start = %s[2];", colors);
fragBuilder->codeAppendf(" end = %s[3];", colors);
- fragBuilder->codeAppendf(" relative_t = (clamp_t - %s) / (1 - %s);", stopT, stopT);
+ // Want: (t-s)/(1-s), but arrange it as: t/(1-s) - s/(1-s), for FMA form
+ fragBuilder->codeAppendf(" relative_t = (clamp_t * %s.z) - %s.w;", stopT, stopT);
fragBuilder->codeAppend ("}");
fragBuilder->codeAppend ("float4 colorTemp = mix(start, end, relative_t);");
@@ -1626,35 +1624,26 @@ void GrGradientEffect::GLSLProcessor::emitAnalyticalColor(GrGLSLFPFragmentBuilde
}
case kThree_ColorType: {
+ // (t, 1/t, 1/(1-t), t/(1-t))
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("if (clamp_t < %s.x) {", stopT);
fragBuilder->codeAppendf(" start = %s[0];", colors);
fragBuilder->codeAppendf(" end = %s[1];", colors);
- fragBuilder->codeAppendf(" relative_t = clamp_t / %s;", stopT);
+ fragBuilder->codeAppendf(" relative_t = clamp_t * %s.y;", 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);
+ // Want: (t-s)/(1-s), but arrange it as: t/(1-s) - s/(1-s), for FMA form
+ fragBuilder->codeAppendf(" relative_t = (clamp_t * %s.z) - %s.w;", 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);
- 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);
-
- break;
- }
-
default:
SkASSERT(false);
break;
@@ -1729,6 +1718,9 @@ GrGradientEffect::GrGradientEffect(const CreateArgs& args, bool isOpaque)
if (shader.fOrigPos) {
fPositions = SkTDArray<SkScalar>(shader.fOrigPos, shader.fColorCount);
+ } else if (kThree_ColorType == fColorType) {
+ const SkScalar symmetricStops[] = { 0.0f, 0.5f, 1.0f };
+ fPositions = SkTDArray<SkScalar>(symmetricStops, 3);
}
}
@@ -1738,7 +1730,6 @@ 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:
diff --git a/src/shaders/gradients/SkGradientShaderPriv.h b/src/shaders/gradients/SkGradientShaderPriv.h
index fb1447ed05..59c9541b28 100644
--- a/src/shaders/gradients/SkGradientShaderPriv.h
+++ b/src/shaders/gradients/SkGradientShaderPriv.h
@@ -389,7 +389,6 @@ public:
enum ColorType {
kTwo_ColorType,
kThree_ColorType, // 0, t, 1
- kSymmetricThree_ColorType,
kTexture_ColorType,
kSingleHardStop_ColorType, // 0, t, t, 1
kHardStopLeftEdged_ColorType, // 0, 0, 1
@@ -542,11 +541,10 @@ private:
// hard stop cases (neither means using texture atlas)
kTwoColorKey = 2,
kThreeColorKey = 4,
- kSymmetricThreeColorKey = 6,
- kHardStopCenteredKey = 8,
- kHardStopZeroZeroOneKey = 10,
- kHardStopZeroOneOneKey = 12,
+ kHardStopCenteredKey = 6,
+ kHardStopZeroZeroOneKey = 8,
+ kHardStopZeroOneOneKey = 10,
// Next two bits for tile mode
kClampTileMode = 16,