Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp

Issue 311373003: Fix Assert for gpu ConicalTwoPointGradient edgecase to be correct bounds. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix assert to check if zero start rad Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gm/gradients_2pt_conical.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2014 Google Inc. 3 * Copyright 2014 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkTwoPointConicalGradient_gpu.h" 9 #include "SkTwoPointConicalGradient_gpu.h"
10 10
11 #include "SkTwoPointConicalGradient.h" 11 #include "SkTwoPointConicalGradient.h"
12 12
13 #if SK_SUPPORT_GPU 13 #if SK_SUPPORT_GPU
14 #include "GrTBackendEffectFactory.h" 14 #include "GrTBackendEffectFactory.h"
15 // For brevity 15 // For brevity
16 typedef GrGLUniformManager::UniformHandle UniformHandle; 16 typedef GrGLUniformManager::UniformHandle UniformHandle;
17 17
18 static const SkScalar kErrorTol = 0.00001f; 18 static const SkScalar kErrorTol = 0.00001f;
19 static const SkScalar kEdgeErrorTol = 5.f * kErrorTol;
19 20
20 /** 21 /**
21 * We have three general cases for 2pt conical gradients. First we always assume that 22 * We have three general cases for 2pt conical gradients. First we always assume that
22 * the start radius <= end radius. Our first case (kInside_) is when the start c ircle 23 * the start radius <= end radius. Our first case (kInside_) is when the start c ircle
23 * is completely enclosed by the end circle. The second case (kOutside_) is the case 24 * is completely enclosed by the end circle. The second case (kOutside_) is the case
24 * when the start circle is either completely outside the end circle or the circ les 25 * when the start circle is either completely outside the end circle or the circ les
25 * overlap. The final case (kEdge_) is when the start circle is inside the end o ne, 26 * overlap. The final case (kEdge_) is when the start circle is inside the end o ne,
26 * but the two are just barely touching at 1 point along their edges. 27 * but the two are just barely touching at 1 point along their edges.
27 */ 28 */
28 enum ConicalType { 29 enum ConicalType {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 90
90 Edge2PtConicalEffect(GrContext* ctx, 91 Edge2PtConicalEffect(GrContext* ctx,
91 const SkTwoPointConicalGradient& shader, 92 const SkTwoPointConicalGradient& shader,
92 const SkMatrix& matrix, 93 const SkMatrix& matrix,
93 SkShader::TileMode tm) 94 SkShader::TileMode tm)
94 : INHERITED(ctx, shader, matrix, tm), 95 : INHERITED(ctx, shader, matrix, tm),
95 fCenterX1(shader.getCenterX1()), 96 fCenterX1(shader.getCenterX1()),
96 fRadius0(shader.getStartRadius()), 97 fRadius0(shader.getStartRadius()),
97 fDiffRadius(shader.getDiffRadius()){ 98 fDiffRadius(shader.getDiffRadius()){
98 // We should only be calling this shader if we are degenerate case with touching circles 99 // We should only be calling this shader if we are degenerate case with touching circles
99 SkASSERT(SkScalarAbs(fDiffRadius) - SkScalarAbs(fCenterX1) < kErrorTol) ; 100 // When deciding if we are in edge case, we scaled by the end radius for cases when the
101 // start radius was close to zero, otherwise we scaled by the start radi us
102 SkASSERT(SkScalarAbs(SkScalarAbs(fDiffRadius) - SkScalarAbs(fCenterX1)) <
103 kEdgeErrorTol * (fRadius0 < kErrorTol ? shader.getEndRadius() : fRadius0));
100 104
101 // We pass the linear part of the quadratic as a varying. 105 // We pass the linear part of the quadratic as a varying.
102 // float b = -2.0 * (fCenterX1 * x + fRadius0 * fDiffRadius * z) 106 // float b = -2.0 * (fCenterX1 * x + fRadius0 * fDiffRadius * z)
103 fBTransform = this->getCoordTransform(); 107 fBTransform = this->getCoordTransform();
104 SkMatrix& bMatrix = *fBTransform.accessMatrix(); 108 SkMatrix& bMatrix = *fBTransform.accessMatrix();
105 SkScalar r0dr = SkScalarMul(fRadius0, fDiffRadius); 109 SkScalar r0dr = SkScalarMul(fRadius0, fDiffRadius);
106 bMatrix[SkMatrix::kMScaleX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMat rix::kMScaleX]) + 110 bMatrix[SkMatrix::kMScaleX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMat rix::kMScaleX]) +
107 SkScalarMul(r0dr, bMatrix[SkMatrix:: kMPersp0])); 111 SkScalarMul(r0dr, bMatrix[SkMatrix:: kMPersp0]));
108 bMatrix[SkMatrix::kMSkewX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatr ix::kMSkewX]) + 112 bMatrix[SkMatrix::kMSkewX] = -2 * (SkScalarMul(fCenterX1, bMatrix[SkMatr ix::kMSkewX]) +
109 SkScalarMul(r0dr, bMatrix[SkMatrix::k MPersp1])); 113 SkScalarMul(r0dr, bMatrix[SkMatrix::k MPersp1]));
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 SkMatrix rot; 325 SkMatrix rot;
322 rot.setSinCos(-SkScalarMul(invFocalX, focalTrans.fY), 326 rot.setSinCos(-SkScalarMul(invFocalX, focalTrans.fY),
323 SkScalarMul(invFocalX, focalTrans.fX)); 327 SkScalarMul(invFocalX, focalTrans.fX));
324 matrix.postConcat(rot); 328 matrix.postConcat(rot);
325 } 329 }
326 330
327 matrix.postTranslate(-(*focalX), 0.f); 331 matrix.postTranslate(-(*focalX), 0.f);
328 332
329 // If the focal point is touching the edge of the circle it will 333 // If the focal point is touching the edge of the circle it will
330 // cause a degenerate case that must be handled separately 334 // cause a degenerate case that must be handled separately
331 // 5 * kErrorTol was picked after manual testing the stability trade off 335 // kEdgeErrorTol = 5 * kErrorTol was picked after manual testing the
332 // versus the linear approx used in the Edge Shader 336 // stability trade off versus the linear approx used in the Edge Shader
333 if (SkScalarAbs(1.f - (*focalX)) < 5 * kErrorTol) { 337 if (SkScalarAbs(1.f - (*focalX)) < kEdgeErrorTol) {
334 return kEdge_ConicalType; 338 return kEdge_ConicalType;
335 } 339 }
336 340
337 // Scale factor 1 / (1 - focalX * focalX) 341 // Scale factor 1 / (1 - focalX * focalX)
338 SkScalar oneMinusF2 = 1.f - SkScalarMul(*focalX, *focalX); 342 SkScalar oneMinusF2 = 1.f - SkScalarMul(*focalX, *focalX);
339 SkScalar s = SkScalarDiv(1.f, oneMinusF2); 343 SkScalar s = SkScalarDiv(1.f, oneMinusF2);
340 344
341 345
342 if (s >= 0.f) { 346 if (s >= 0.f) {
343 conicalType = kInside_ConicalType; 347 conicalType = kInside_ConicalType;
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 radiusEnd /= radiusStart; 768 radiusEnd /= radiusStart;
765 769
766 SkPoint centerEndTrans; 770 SkPoint centerEndTrans;
767 matrix.mapPoints(&centerEndTrans, &centerEnd, 1); 771 matrix.mapPoints(&centerEndTrans, &centerEnd, 1);
768 772
769 SkScalar A = centerEndTrans.fX * centerEndTrans.fX + centerEndTrans.fY * cen terEndTrans.fY 773 SkScalar A = centerEndTrans.fX * centerEndTrans.fX + centerEndTrans.fY * cen terEndTrans.fY
770 - radiusEnd * radiusEnd + 2 * radiusEnd - 1; 774 - radiusEnd * radiusEnd + 2 * radiusEnd - 1;
771 775
772 // Check to see if start circle is inside end circle with edges touching. 776 // Check to see if start circle is inside end circle with edges touching.
773 // If touching we return that it is of kEdge_ConicalType, and leave the matr ix setting 777 // If touching we return that it is of kEdge_ConicalType, and leave the matr ix setting
774 // to the edge shader. 5 * kErrorTol was picked after manual testing so that C = 1 / A 778 // to the edge shader. kEdgeErrorTol = 5 * kErrorTol was picked after manual testing
775 // is stable, and the linear approximation used in the Edge shader is still accurate. 779 // so that C = 1 / A is stable, and the linear approximation used in the Edg e shader is
776 if (SkScalarAbs(A) < 5 * kErrorTol) { 780 // still accurate.
781 if (SkScalarAbs(A) < kEdgeErrorTol) {
777 return kEdge_ConicalType; 782 return kEdge_ConicalType;
778 } 783 }
779 784
780 SkScalar C = 1.f / A; 785 SkScalar C = 1.f / A;
781 SkScalar B = (radiusEnd - 1.f) * C; 786 SkScalar B = (radiusEnd - 1.f) * C;
782 787
783 matrix.postScale(C, C); 788 matrix.postScale(C, C);
784 789
785 invLMatrix->postConcat(matrix); 790 invLMatrix->postConcat(matrix);
786 791
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
1301 return CircleInside2PtConicalEffect::Create(ctx, shader, matrix, tm, inf o); 1306 return CircleInside2PtConicalEffect::Create(ctx, shader, matrix, tm, inf o);
1302 } else if (type == kEdge_ConicalType) { 1307 } else if (type == kEdge_ConicalType) {
1303 set_matrix_edge_conical(shader, &matrix); 1308 set_matrix_edge_conical(shader, &matrix);
1304 return Edge2PtConicalEffect::Create(ctx, shader, matrix, tm); 1309 return Edge2PtConicalEffect::Create(ctx, shader, matrix, tm);
1305 } else { 1310 } else {
1306 return CircleOutside2PtConicalEffect::Create(ctx, shader, matrix, tm, in fo); 1311 return CircleOutside2PtConicalEffect::Create(ctx, shader, matrix, tm, in fo);
1307 } 1312 }
1308 } 1313 }
1309 1314
1310 #endif 1315 #endif
OLDNEW
« no previous file with comments | « gm/gradients_2pt_conical.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698