aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/shaders/gradients
diff options
context:
space:
mode:
authorGravatar Yuqian Li <liyuqian@google.com>2018-01-02 11:11:42 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-02 16:35:40 +0000
commite2d4e8f276ba8aee57f071e87e85f04a6a07addf (patch)
tree53a76ccd760cd1b65e31a64224c9913be1d6f113 /src/shaders/gradients
parent2e1d7e234241328154a93b6ddb19f573abc29c15 (diff)
Stronger fix for swapping r0, r1 in 2pt conical gradients
Bug: chromium:798173 Change-Id: I2ac0ee94ecc6230fd450c17b6a0de9065f5b3f16 Reviewed-on: https://skia-review.googlesource.com/90202 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.cpp20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp b/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp
index a2721b464f..320778b552 100644
--- a/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp
+++ b/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp
@@ -455,23 +455,33 @@ TwoPointConicalEffect::Data::Data(const SkTwoPointConicalGradient& shader, SkMat
fType = kStrip_Type;
} else { // focal case
fType = kFocal_Type;
- // We want to check if the end radius is zero and if so we swap it with the start
- // radius. Because of numerical precision, we check if r0 + (r1-r0) is zero
- if (SkScalarNearlyZero(fRadius0 + fDiffRadius)) {
+ SkScalar focalX = - fRadius0 / fDiffRadius;
+
+ // We want to check if the end radius is zero. If so, dr = -r0 and focalX will be 1.
+ // That makes our mapping from {focal_point, (1, 0)} to {(0, 0), {1, 0)} invalid. Hence
+ // we have to swap r0 and r1 to make sure focalX != 1. Due to precision limit, checking
+ // focalX == 1 is better than checking r1 == 0 or r0 + (r1 - r0) for large r0 (e.g., r0
+ // = 1e6, r1 = 1).
+ if (SkScalarNearlyZero(focalX - 1)) {
// swap r0, r1
matrix.postTranslate(-1, 0);
matrix.postScale(-1, 1);
fRadius0 = 0;
fDiffRadius = -fDiffRadius;
fIsSwapped = true;
+ focalX = 0; // - fRadius0 / fDiffRadius;
}
// Map {focal point, (1, 0)} to {(0, 0), (1, 0)}
- SkScalar focalX = - fRadius0 / fDiffRadius;
const SkPoint from[2] = { {focalX, 0}, {1, 0} };
const SkPoint to[2] = { {0, 0}, {1, 0} };
SkMatrix focalMatrix;
- focalMatrix.setPolyToPoly(from, to, 2);
+ if (!focalMatrix.setPolyToPoly(from, to, 2)) {
+ SkDEBUGFAILF("Mapping focal point failed unexpectedly for focalX = %f.\n", focalX);
+ // We won't be able to draw the gradient; at least make sure that we initialize the
+ // memory to prevent security issues.
+ focalMatrix = SkMatrix::MakeScale(1, 1);
+ }
matrix.postConcat(focalMatrix);
fRadius0 /= SkScalarAbs(1 - focalX);
fDiffRadius /= SkScalarAbs(1 - focalX);