diff options
author | Yuqian Li <liyuqian@google.com> | 2018-01-02 13:10:19 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-01-02 19:54:31 +0000 |
commit | ad8b489f9e822c33691d0219f4518f7b058e573d (patch) | |
tree | 242276fda72278be47a58f28565e9280bb9bcd64 /src/shaders/gradients | |
parent | df6290ce033e483ba442144f1be4ef2280244a22 (diff) |
Changes to make 2pt gradient source code better aligned with our future doc
See https://skia-review.googlesource.com/c/skia/+/89340 for the doc
Bug: skia:
Change-Id: I7a57eea317bbc424278c9eaa524a6b7e3b36178e
Reviewed-on: https://skia-review.googlesource.com/90203
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Yuqian Li <liyuqian@google.com>
Diffstat (limited to 'src/shaders/gradients')
-rw-r--r-- | src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp b/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp index 320778b552..6dc0675b24 100644 --- a/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp +++ b/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp @@ -17,6 +17,7 @@ // For brevity typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; +// Please see https://skia.org/dev/design/conical for how our shader works. class TwoPointConicalEffect : public GrGradientEffect { public: class DegeneratedGLSLProcessor; // radial (center0 == center1) or strip (r0 == r1) case @@ -300,6 +301,7 @@ private: // FocalGLSLProcessor ////////////////////////////////////////////////////////////////////////////// +// Please see https://skia.org/dev/design/conical for how our shader works. class TwoPointConicalEffect::FocalGLSLProcessor : public GrGradientEffect::GLSLProcessor { protected: void emitCode(EmitArgs& args) override { @@ -320,48 +322,44 @@ protected: const char* p = coords2D.c_str(); if (ge.isFocalOnCircle()) { - fragBuilder->codeAppendf("half %s_prime = dot(%s, %s) / %s.x;", tName, p, p, p); + fragBuilder->codeAppendf("half x_t = dot(%s, %s) / %s.x;", p, p, p); } else if (ge.isWellBehaved()) { - // empty sign is positive - char sign = ge.isRadiusIncreasing() ? ' ' : '-'; - fragBuilder->codeAppendf("half %s_prime = %clength(%s) - %s.x * %s;", - tName, sign, p, p, p0.c_str()); + fragBuilder->codeAppendf("half x_t = length(%s) - %s.x * %s;", p, p, p0.c_str()); } else { - char sign = ge.isSwapped() ? '-' : ' '; + char sign = (ge.isSwapped() || !ge.isRadiusIncreasing()) ? '-' : ' '; fragBuilder->codeAppendf("half temp = %s.x * %s.x - %s.y * %s.y;", p, p, p, p); - // Initialize t_prime to illegal state (where r(t) < 0) - fragBuilder->codeAppendf("half %s_prime = %s;", - tName, ge.isRadiusIncreasing() ? "-1" : "1"); + // Initialize x_t to illegal state + fragBuilder->codeAppendf("half x_t = -1;"); // Only do sqrt if temp >= 0; this is significantly slower than checking temp >= 0 in // the if statement that checks r(t) >= 0. But GPU may break if we sqrt a negative // float. (Although I havevn't observed that on any devices so far, and the old approach // also does sqrt negative value without a check.) If the performance is really - // critical, maybe we should just compute the area where temp and t_prime are always + // critical, maybe we should just compute the area where temp and x_t are always // valid and drop all these ifs. fragBuilder->codeAppendf("if (temp >= 0) {"); - fragBuilder->codeAppendf("%s_prime = (%csqrt(temp) - %s.x * %s);", - tName, sign, p, p0.c_str()); + fragBuilder->codeAppendf("x_t = (%csqrt(temp) - %s.x * %s);", sign, p, p0.c_str()); fragBuilder->codeAppendf("}"); } + + // empty sign is positive + char sign = ge.isRadiusIncreasing() ? ' ' : '-'; + // "- 0" is much faster than "- p1" so we specialize the natively focal case where p1 = 0. - fragBuilder->codeAppendf("half %s = %s_prime - %s;", tName, tName, + fragBuilder->codeAppendf("half %s = %cx_t - %s;", tName, sign, ge.isNativelyFocal() ? "0" : p1.c_str()); - if (ge.isSwapped()) { - fragBuilder->codeAppendf("%s = 1 - %s;", tName, tName); - } - if (!ge.isWellBehaved()) { // output will default to transparent black (we simply won't write anything // else to it if invalid, instead of discarding or returning prematurely) fragBuilder->codeAppendf("%s = half4(0.0,0.0,0.0,0.0);", args.fOutputColor); + fragBuilder->codeAppendf("if (x_t > 0.0) {"); + } - // r(t) must be nonnegative; we need to swap direction if r0 > r1 because we did a final - // scale of r1 / (r1 - r0) that's negative if r0 > r1. - char direction = ge.isRadiusIncreasing() ? '>' : '<'; - fragBuilder->codeAppendf("if (%s_prime %c= 0.0) {", tName, direction); + if (ge.isSwapped()) { + fragBuilder->codeAppendf("%s = 1 - %s;", tName, tName); } + this->emitColor(fragBuilder, uniformHandler, args.fShaderCaps, @@ -496,7 +494,8 @@ TwoPointConicalEffect::Data::Data(const SkTwoPointConicalGradient& shader, SkMat } else { matrix.postScale(r1 / (r1 * r1 - 1), 1 / sqrt(SkScalarAbs(r1 * r1 - 1))); } - matrix.postScale(r1 / (r1 - r0), r1 / (r1 - r0)); + SkScalar scale = SkScalarAbs(r1 / (r1 - r0)); // |1 - f| + matrix.postScale(scale, scale); } } } |