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

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

Issue 227623004: Add flipped gradient branch to two point conical gradient (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Cpu flip fix Created 6 years, 8 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
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkTwoPointConicalGradient.h" 8 #include "SkTwoPointConicalGradient.h"
9 9
10 #include "SkTwoPointConicalGradient_gpu.h" 10 #include "SkTwoPointConicalGradient_gpu.h"
(...skipping 14 matching lines...) Expand all
25 SkASSERT(ratio); 25 SkASSERT(ratio);
26 if (0 == denom) { 26 if (0 == denom) {
27 return 0; 27 return 0;
28 } 28 }
29 *ratio = numer / denom; 29 *ratio = numer / denom;
30 return 1; 30 return 1;
31 } 31 }
32 32
33 // Return the number of distinct real roots, and write them into roots[] in 33 // Return the number of distinct real roots, and write them into roots[] in
34 // ascending order 34 // ascending order
35 static int find_quad_roots(float A, float B, float C, float roots[2]) { 35 static int find_quad_roots(float A, float B, float C, float roots[2], bool desce ndingOrder = false) {
36 SkASSERT(roots); 36 SkASSERT(roots);
37 37
38 if (A == 0) { 38 if (A == 0) {
39 return valid_divide(-C, B, roots); 39 return valid_divide(-C, B, roots);
40 } 40 }
41 41
42 float R = B*B - 4*A*C; 42 float R = B*B - 4*A*C;
43 if (R < 0) { 43 if (R < 0) {
44 return 0; 44 return 0;
45 } 45 }
(...skipping 13 matching lines...) Expand all
59 Q *= -0.5f; 59 Q *= -0.5f;
60 if (0 == Q) { 60 if (0 == Q) {
61 roots[0] = 0; 61 roots[0] = 0;
62 return 1; 62 return 1;
63 } 63 }
64 64
65 float r0 = Q / A; 65 float r0 = Q / A;
66 float r1 = C / Q; 66 float r1 = C / Q;
67 roots[0] = r0 < r1 ? r0 : r1; 67 roots[0] = r0 < r1 ? r0 : r1;
68 roots[1] = r0 > r1 ? r0 : r1; 68 roots[1] = r0 > r1 ? r0 : r1;
69 if (descendingOrder) {
70 SkTSwap(roots[0], roots[1]);
71 }
69 return 2; 72 return 2;
70 } 73 }
71 74
72 static float lerp(float x, float dx, float t) { 75 static float lerp(float x, float dx, float t) {
73 return x + t * dx; 76 return x + t * dx;
74 } 77 }
75 78
76 static float sqr(float x) { return x * x; } 79 static float sqr(float x) { return x * x; }
77 80
78 void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0, 81 void TwoPtRadial::init(const SkPoint& center0, SkScalar rad0,
79 const SkPoint& center1, SkScalar rad1) { 82 const SkPoint& center1, SkScalar rad1,
83 bool flipped) {
80 fCenterX = SkScalarToFloat(center0.fX); 84 fCenterX = SkScalarToFloat(center0.fX);
81 fCenterY = SkScalarToFloat(center0.fY); 85 fCenterY = SkScalarToFloat(center0.fY);
82 fDCenterX = SkScalarToFloat(center1.fX) - fCenterX; 86 fDCenterX = SkScalarToFloat(center1.fX) - fCenterX;
83 fDCenterY = SkScalarToFloat(center1.fY) - fCenterY; 87 fDCenterY = SkScalarToFloat(center1.fY) - fCenterY;
84 fRadius = SkScalarToFloat(rad0); 88 fRadius = SkScalarToFloat(rad0);
85 fDRadius = SkScalarToFloat(rad1) - fRadius; 89 fDRadius = SkScalarToFloat(rad1) - fRadius;
86 90
87 fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius); 91 fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius);
88 fRadius2 = sqr(fRadius); 92 fRadius2 = sqr(fRadius);
89 fRDR = fRadius * fDRadius; 93 fRDR = fRadius * fDRadius;
94
95 fFlipped = flipped;
90 } 96 }
91 97
92 TwoPtRadialContext::TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkSc alar fy, 98 TwoPtRadialContext::TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkSc alar fy,
93 SkScalar dfx, SkScalar dfy) 99 SkScalar dfx, SkScalar dfy)
94 : fRec(rec) 100 : fRec(rec)
95 , fRelX(SkScalarToFloat(fx) - rec.fCenterX) 101 , fRelX(SkScalarToFloat(fx) - rec.fCenterX)
96 , fRelY(SkScalarToFloat(fy) - rec.fCenterY) 102 , fRelY(SkScalarToFloat(fy) - rec.fCenterY)
97 , fIncX(SkScalarToFloat(dfx)) 103 , fIncX(SkScalarToFloat(dfx))
98 , fIncY(SkScalarToFloat(dfy)) 104 , fIncY(SkScalarToFloat(dfy))
99 , fB(-2 * (rec.fDCenterX * fRelX + rec.fDCenterY * fRelY + rec.fRDR)) 105 , fB(-2 * (rec.fDCenterX * fRelX + rec.fDCenterY * fRelY + rec.fRDR))
100 , fDB(-2 * (rec.fDCenterX * fIncX + rec.fDCenterY * fIncY)) {} 106 , fDB(-2 * (rec.fDCenterX * fIncX + rec.fDCenterY * fIncY)) {}
101 107
102 SkFixed TwoPtRadialContext::nextT() { 108 SkFixed TwoPtRadialContext::nextT() {
103 float roots[2]; 109 float roots[2];
104 110
105 float C = sqr(fRelX) + sqr(fRelY) - fRec.fRadius2; 111 float C = sqr(fRelX) + sqr(fRelY) - fRec.fRadius2;
106 int countRoots = find_quad_roots(fRec.fA, fB, C, roots); 112 int countRoots = find_quad_roots(fRec.fA, fB, C, roots, fRec.fFlipped);
107 113
108 fRelX += fIncX; 114 fRelX += fIncX;
109 fRelY += fIncY; 115 fRelY += fIncY;
110 fB += fDB; 116 fB += fDB;
111 117
112 if (0 == countRoots) { 118 if (0 == countRoots) {
113 return TwoPtRadial::kDontDrawT; 119 return TwoPtRadial::kDontDrawT;
114 } 120 }
115 121
116 // Prefer the bigger t value if both give a radius(t) > 0 122 // Prefer the bigger t value if both give a radius(t) > 0
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 SkFixed index = mirror_tileproc(t); 181 SkFixed index = mirror_tileproc(t);
176 SkASSERT(index <= 0xFFFF); 182 SkASSERT(index <= 0xFFFF);
177 *dstC++ = cache[toggle + 183 *dstC++ = cache[toggle +
178 (index >> SkGradientShaderBase::kCache32Shift)]; 184 (index >> SkGradientShaderBase::kCache32Shift)];
179 } 185 }
180 toggle = next_dither_toggle(toggle); 186 toggle = next_dither_toggle(toggle);
181 } 187 }
182 } 188 }
183 189
184 void SkTwoPointConicalGradient::init() { 190 void SkTwoPointConicalGradient::init() {
185 fRec.init(fCenter1, fRadius1, fCenter2, fRadius2); 191 fRec.init(fCenter1, fRadius1, fCenter2, fRadius2, fFlippedGrad);
186 fPtsToUnit.reset(); 192 fPtsToUnit.reset();
187 } 193 }
188 194
189 ///////////////////////////////////////////////////////////////////// 195 /////////////////////////////////////////////////////////////////////
190 196
191 SkTwoPointConicalGradient::SkTwoPointConicalGradient( 197 SkTwoPointConicalGradient::SkTwoPointConicalGradient(
192 const SkPoint& start, SkScalar startRadius, 198 const SkPoint& start, SkScalar startRadius,
193 const SkPoint& end, SkScalar endRadius, 199 const SkPoint& end, SkScalar endRadius,
194 const Descriptor& desc) 200 bool flippedGrad, const Descriptor& desc)
195 : SkGradientShaderBase(desc), 201 : SkGradientShaderBase(desc),
196 fCenter1(start), 202 fCenter1(start),
197 fCenter2(end), 203 fCenter2(end),
198 fRadius1(startRadius), 204 fRadius1(startRadius),
199 fRadius2(endRadius) { 205 fRadius2(endRadius),
206 fFlippedGrad(flippedGrad) {
200 // this is degenerate, and should be caught by our caller 207 // this is degenerate, and should be caught by our caller
201 SkASSERT(fCenter1 != fCenter2 || fRadius1 != fRadius2); 208 SkASSERT(fCenter1 != fCenter2 || fRadius1 != fRadius2);
202 this->init(); 209 this->init();
203 } 210 }
204 211
205 bool SkTwoPointConicalGradient::isOpaque() const { 212 bool SkTwoPointConicalGradient::isOpaque() const {
206 // Because areas outside the cone are left untouched, we cannot treat the 213 // Because areas outside the cone are left untouched, we cannot treat the
207 // shader as opaque even if the gradient itself is opaque. 214 // shader as opaque even if the gradient itself is opaque.
208 // TODO(junov): Compute whether the cone fills the plane crbug.com/222380 215 // TODO(junov): Compute whether the cone fills the plane crbug.com/222380
209 return false; 216 return false;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 return kConical_GradientType; 345 return kConical_GradientType;
339 } 346 }
340 347
341 SkTwoPointConicalGradient::SkTwoPointConicalGradient( 348 SkTwoPointConicalGradient::SkTwoPointConicalGradient(
342 SkReadBuffer& buffer) 349 SkReadBuffer& buffer)
343 : INHERITED(buffer), 350 : INHERITED(buffer),
344 fCenter1(buffer.readPoint()), 351 fCenter1(buffer.readPoint()),
345 fCenter2(buffer.readPoint()), 352 fCenter2(buffer.readPoint()),
346 fRadius1(buffer.readScalar()), 353 fRadius1(buffer.readScalar()),
347 fRadius2(buffer.readScalar()) { 354 fRadius2(buffer.readScalar()) {
355 if (buffer.pictureVersion() >= 24 || 0 == buffer.pictureVersion()) {
356 fFlippedGrad = buffer.readBool();
357 } else {
358 // V23_COMPATIBILITY_CODE
359 // Sort gradient by radius size for old pictures
360 if (fRadius2 < fRadius1) {
361 SkTSwap(fCenter1, fCenter2);
362 SkTSwap(fRadius1, fRadius2);
363 this->flipGradientColors();
364 fFlippedGrad = true;
365 } else {
366 fFlippedGrad = false;
367 }
368 }
348 this->init(); 369 this->init();
349 }; 370 };
350 371
351 void SkTwoPointConicalGradient::flatten( 372 void SkTwoPointConicalGradient::flatten(
352 SkWriteBuffer& buffer) const { 373 SkWriteBuffer& buffer) const {
353 this->INHERITED::flatten(buffer); 374 this->INHERITED::flatten(buffer);
354 buffer.writePoint(fCenter1); 375 buffer.writePoint(fCenter1);
355 buffer.writePoint(fCenter2); 376 buffer.writePoint(fCenter2);
356 buffer.writeScalar(fRadius1); 377 buffer.writeScalar(fRadius1);
357 buffer.writeScalar(fRadius2); 378 buffer.writeScalar(fRadius2);
379 buffer.writeBool(fFlippedGrad);
358 } 380 }
359 381
360 #if SK_SUPPORT_GPU 382 #if SK_SUPPORT_GPU
361 383
362 GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const Sk Paint&) const { 384 GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const Sk Paint&) const {
363 SkASSERT(NULL != context); 385 SkASSERT(NULL != context);
364 SkASSERT(fPtsToUnit.isIdentity()); 386 SkASSERT(fPtsToUnit.isIdentity());
365 387
366 return Gr2PtConicalGradientEffect::Create(context, *this, fTileMode); 388 return Gr2PtConicalGradientEffect::Create(context, *this, fTileMode);
367 } 389 }
(...skipping 25 matching lines...) Expand all
393 str->appendScalar(fCenter2.fY); 415 str->appendScalar(fCenter2.fY);
394 str->append(") radius2: "); 416 str->append(") radius2: ");
395 str->appendScalar(fRadius2); 417 str->appendScalar(fRadius2);
396 str->append(" "); 418 str->append(" ");
397 419
398 this->INHERITED::toString(str); 420 this->INHERITED::toString(str);
399 421
400 str->append(")"); 422 str->append(")");
401 } 423 }
402 #endif 424 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698