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

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

Issue 249643002: Revert of Extract most of the mutable state of SkShader into a separate Context object. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 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"
11 11
12 struct TwoPtRadialContext {
13 const TwoPtRadial& fRec;
14 float fRelX, fRelY;
15 const float fIncX, fIncY;
16 float fB;
17 const float fDB;
18
19 TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkScalar fy,
20 SkScalar dfx, SkScalar dfy);
21 SkFixed nextT();
22 };
23
24 static int valid_divide(float numer, float denom, float* ratio) { 12 static int valid_divide(float numer, float denom, float* ratio) {
25 SkASSERT(ratio); 13 SkASSERT(ratio);
26 if (0 == denom) { 14 if (0 == denom) {
27 return 0; 15 return 0;
28 } 16 }
29 *ratio = numer / denom; 17 *ratio = numer / denom;
30 return 1; 18 return 1;
31 } 19 }
32 20
33 // Return the number of distinct real roots, and write them into roots[] in 21 // Return the number of distinct real roots, and write them into roots[] in
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 fRadius = SkScalarToFloat(rad0); 76 fRadius = SkScalarToFloat(rad0);
89 fDRadius = SkScalarToFloat(rad1) - fRadius; 77 fDRadius = SkScalarToFloat(rad1) - fRadius;
90 78
91 fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius); 79 fA = sqr(fDCenterX) + sqr(fDCenterY) - sqr(fDRadius);
92 fRadius2 = sqr(fRadius); 80 fRadius2 = sqr(fRadius);
93 fRDR = fRadius * fDRadius; 81 fRDR = fRadius * fDRadius;
94 82
95 fFlipped = flipped; 83 fFlipped = flipped;
96 } 84 }
97 85
98 TwoPtRadialContext::TwoPtRadialContext(const TwoPtRadial& rec, SkScalar fx, SkSc alar fy, 86 void TwoPtRadial::setup(SkScalar fx, SkScalar fy, SkScalar dfx, SkScalar dfy) {
99 SkScalar dfx, SkScalar dfy) 87 fRelX = SkScalarToFloat(fx) - fCenterX;
100 : fRec(rec) 88 fRelY = SkScalarToFloat(fy) - fCenterY;
101 , fRelX(SkScalarToFloat(fx) - rec.fCenterX) 89 fIncX = SkScalarToFloat(dfx);
102 , fRelY(SkScalarToFloat(fy) - rec.fCenterY) 90 fIncY = SkScalarToFloat(dfy);
103 , fIncX(SkScalarToFloat(dfx)) 91 fB = -2 * (fDCenterX * fRelX + fDCenterY * fRelY + fRDR);
104 , fIncY(SkScalarToFloat(dfy)) 92 fDB = -2 * (fDCenterX * fIncX + fDCenterY * fIncY);
105 , fB(-2 * (rec.fDCenterX * fRelX + rec.fDCenterY * fRelY + rec.fRDR)) 93 }
106 , fDB(-2 * (rec.fDCenterX * fIncX + rec.fDCenterY * fIncY)) {}
107 94
108 SkFixed TwoPtRadialContext::nextT() { 95 SkFixed TwoPtRadial::nextT() {
109 float roots[2]; 96 float roots[2];
110 97
111 float C = sqr(fRelX) + sqr(fRelY) - fRec.fRadius2; 98 float C = sqr(fRelX) + sqr(fRelY) - fRadius2;
112 int countRoots = find_quad_roots(fRec.fA, fB, C, roots, fRec.fFlipped); 99 int countRoots = find_quad_roots(fA, fB, C, roots, fFlipped);
113 100
114 fRelX += fIncX; 101 fRelX += fIncX;
115 fRelY += fIncY; 102 fRelY += fIncY;
116 fB += fDB; 103 fB += fDB;
117 104
118 if (0 == countRoots) { 105 if (0 == countRoots) {
119 return TwoPtRadial::kDontDrawT; 106 return kDontDrawT;
120 } 107 }
121 108
122 // Prefer the bigger t value if both give a radius(t) > 0 109 // Prefer the bigger t value if both give a radius(t) > 0
123 // find_quad_roots returns the values sorted, so we start with the last 110 // find_quad_roots returns the values sorted, so we start with the last
124 float t = roots[countRoots - 1]; 111 float t = roots[countRoots - 1];
125 float r = lerp(fRec.fRadius, fRec.fDRadius, t); 112 float r = lerp(fRadius, fDRadius, t);
126 if (r <= 0) { 113 if (r <= 0) {
127 t = roots[0]; // might be the same as roots[countRoots-1] 114 t = roots[0]; // might be the same as roots[countRoots-1]
128 r = lerp(fRec.fRadius, fRec.fDRadius, t); 115 r = lerp(fRadius, fDRadius, t);
129 if (r <= 0) { 116 if (r <= 0) {
130 return TwoPtRadial::kDontDrawT; 117 return kDontDrawT;
131 } 118 }
132 } 119 }
133 return SkFloatToFixed(t); 120 return SkFloatToFixed(t);
134 } 121 }
135 122
136 typedef void (*TwoPointConicalProc)(TwoPtRadialContext* rec, SkPMColor* dstC, 123 typedef void (*TwoPointConicalProc)(TwoPtRadial* rec, SkPMColor* dstC,
137 const SkPMColor* cache, int toggle, int coun t); 124 const SkPMColor* cache, int toggle, int coun t);
138 125
139 static void twopoint_clamp(TwoPtRadialContext* rec, SkPMColor* SK_RESTRICT dstC, 126 static void twopoint_clamp(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
140 const SkPMColor* SK_RESTRICT cache, int toggle, 127 const SkPMColor* SK_RESTRICT cache, int toggle,
141 int count) { 128 int count) {
142 for (; count > 0; --count) { 129 for (; count > 0; --count) {
143 SkFixed t = rec->nextT(); 130 SkFixed t = rec->nextT();
144 if (TwoPtRadial::DontDrawT(t)) { 131 if (TwoPtRadial::DontDrawT(t)) {
145 *dstC++ = 0; 132 *dstC++ = 0;
146 } else { 133 } else {
147 SkFixed index = SkClampMax(t, 0xFFFF); 134 SkFixed index = SkClampMax(t, 0xFFFF);
148 SkASSERT(index <= 0xFFFF); 135 SkASSERT(index <= 0xFFFF);
149 *dstC++ = cache[toggle + 136 *dstC++ = cache[toggle +
150 (index >> SkGradientShaderBase::kCache32Shift)]; 137 (index >> SkGradientShaderBase::kCache32Shift)];
151 } 138 }
152 toggle = next_dither_toggle(toggle); 139 toggle = next_dither_toggle(toggle);
153 } 140 }
154 } 141 }
155 142
156 static void twopoint_repeat(TwoPtRadialContext* rec, SkPMColor* SK_RESTRICT dstC , 143 static void twopoint_repeat(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
157 const SkPMColor* SK_RESTRICT cache, int toggle, 144 const SkPMColor* SK_RESTRICT cache, int toggle,
158 int count) { 145 int count) {
159 for (; count > 0; --count) { 146 for (; count > 0; --count) {
160 SkFixed t = rec->nextT(); 147 SkFixed t = rec->nextT();
161 if (TwoPtRadial::DontDrawT(t)) { 148 if (TwoPtRadial::DontDrawT(t)) {
162 *dstC++ = 0; 149 *dstC++ = 0;
163 } else { 150 } else {
164 SkFixed index = repeat_tileproc(t); 151 SkFixed index = repeat_tileproc(t);
165 SkASSERT(index <= 0xFFFF); 152 SkASSERT(index <= 0xFFFF);
166 *dstC++ = cache[toggle + 153 *dstC++ = cache[toggle +
167 (index >> SkGradientShaderBase::kCache32Shift)]; 154 (index >> SkGradientShaderBase::kCache32Shift)];
168 } 155 }
169 toggle = next_dither_toggle(toggle); 156 toggle = next_dither_toggle(toggle);
170 } 157 }
171 } 158 }
172 159
173 static void twopoint_mirror(TwoPtRadialContext* rec, SkPMColor* SK_RESTRICT dstC , 160 static void twopoint_mirror(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
174 const SkPMColor* SK_RESTRICT cache, int toggle, 161 const SkPMColor* SK_RESTRICT cache, int toggle,
175 int count) { 162 int count) {
176 for (; count > 0; --count) { 163 for (; count > 0; --count) {
177 SkFixed t = rec->nextT(); 164 SkFixed t = rec->nextT();
178 if (TwoPtRadial::DontDrawT(t)) { 165 if (TwoPtRadial::DontDrawT(t)) {
179 *dstC++ = 0; 166 *dstC++ = 0;
180 } else { 167 } else {
181 SkFixed index = mirror_tileproc(t); 168 SkFixed index = mirror_tileproc(t);
182 SkASSERT(index <= 0xFFFF); 169 SkASSERT(index <= 0xFFFF);
183 *dstC++ = cache[toggle + 170 *dstC++ = cache[toggle +
(...skipping 25 matching lines...) Expand all
209 this->init(); 196 this->init();
210 } 197 }
211 198
212 bool SkTwoPointConicalGradient::isOpaque() const { 199 bool SkTwoPointConicalGradient::isOpaque() const {
213 // Because areas outside the cone are left untouched, we cannot treat the 200 // Because areas outside the cone are left untouched, we cannot treat the
214 // shader as opaque even if the gradient itself is opaque. 201 // shader as opaque even if the gradient itself is opaque.
215 // TODO(junov): Compute whether the cone fills the plane crbug.com/222380 202 // TODO(junov): Compute whether the cone fills the plane crbug.com/222380
216 return false; 203 return false;
217 } 204 }
218 205
219 size_t SkTwoPointConicalGradient::contextSize() const { 206 void SkTwoPointConicalGradient::shadeSpan(int x, int y, SkPMColor* dstCParam,
220 return sizeof(TwoPointConicalGradientContext); 207 int count) {
221 }
222
223 SkShader::Context* SkTwoPointConicalGradient::createContext(
224 const SkBitmap& device, const SkPaint& paint,
225 const SkMatrix& matrix, void* storage) const {
226 if (!this->validContext(device, paint, matrix)) {
227 return NULL;
228 }
229
230 return SkNEW_PLACEMENT_ARGS(storage, TwoPointConicalGradientContext,
231 (*this, device, paint, matrix));
232 }
233
234 SkTwoPointConicalGradient::TwoPointConicalGradientContext::TwoPointConicalGradie ntContext(
235 const SkTwoPointConicalGradient& shader, const SkBitmap& device,
236 const SkPaint& paint, const SkMatrix& matrix)
237 : INHERITED(shader, device, paint, matrix)
238 {
239 // we don't have a span16 proc
240 fFlags &= ~kHasSpan16_Flag;
241
242 // in general, we might discard based on computed-radius, so clear
243 // this flag (todo: sometimes we can detect that we never discard...)
244 fFlags &= ~kOpaqueAlpha_Flag;
245 }
246
247 void SkTwoPointConicalGradient::TwoPointConicalGradientContext::shadeSpan(
248 int x, int y, SkPMColor* dstCParam, int count) {
249 const SkTwoPointConicalGradient& twoPointConicalGradient =
250 static_cast<const SkTwoPointConicalGradient&>(fShader);
251
252 int toggle = init_dither_toggle(x, y); 208 int toggle = init_dither_toggle(x, y);
253 209
254 SkASSERT(count > 0); 210 SkASSERT(count > 0);
255 211
256 SkPMColor* SK_RESTRICT dstC = dstCParam; 212 SkPMColor* SK_RESTRICT dstC = dstCParam;
257 213
258 SkMatrix::MapXYProc dstProc = fDstToIndexProc; 214 SkMatrix::MapXYProc dstProc = fDstToIndexProc;
259 215
260 const SkPMColor* SK_RESTRICT cache = fCache->getCache32(); 216 const SkPMColor* SK_RESTRICT cache = this->getCache32();
261 217
262 TwoPointConicalProc shadeProc = twopoint_repeat; 218 TwoPointConicalProc shadeProc = twopoint_repeat;
263 if (SkShader::kClamp_TileMode == twoPointConicalGradient.fTileMode) { 219 if (SkShader::kClamp_TileMode == fTileMode) {
264 shadeProc = twopoint_clamp; 220 shadeProc = twopoint_clamp;
265 } else if (SkShader::kMirror_TileMode == twoPointConicalGradient.fTileMode) { 221 } else if (SkShader::kMirror_TileMode == fTileMode) {
266 shadeProc = twopoint_mirror; 222 shadeProc = twopoint_mirror;
267 } else { 223 } else {
268 SkASSERT(SkShader::kRepeat_TileMode == twoPointConicalGradient.fTileMode ); 224 SkASSERT(SkShader::kRepeat_TileMode == fTileMode);
269 } 225 }
270 226
271 if (fDstToIndexClass != kPerspective_MatrixClass) { 227 if (fDstToIndexClass != kPerspective_MatrixClass) {
272 SkPoint srcPt; 228 SkPoint srcPt;
273 dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf, 229 dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
274 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); 230 SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
275 SkScalar dx, fx = srcPt.fX; 231 SkScalar dx, fx = srcPt.fX;
276 SkScalar dy, fy = srcPt.fY; 232 SkScalar dy, fy = srcPt.fY;
277 233
278 if (fDstToIndexClass == kFixedStepInX_MatrixClass) { 234 if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
279 SkFixed fixedX, fixedY; 235 SkFixed fixedX, fixedY;
280 (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY); 236 (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY);
281 dx = SkFixedToScalar(fixedX); 237 dx = SkFixedToScalar(fixedX);
282 dy = SkFixedToScalar(fixedY); 238 dy = SkFixedToScalar(fixedY);
283 } else { 239 } else {
284 SkASSERT(fDstToIndexClass == kLinear_MatrixClass); 240 SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
285 dx = fDstToIndex.getScaleX(); 241 dx = fDstToIndex.getScaleX();
286 dy = fDstToIndex.getSkewY(); 242 dy = fDstToIndex.getSkewY();
287 } 243 }
288 244
289 TwoPtRadialContext rec(twoPointConicalGradient.fRec, fx, fy, dx, dy); 245 fRec.setup(fx, fy, dx, dy);
290 (*shadeProc)(&rec, dstC, cache, toggle, count); 246 (*shadeProc)(&fRec, dstC, cache, toggle, count);
291 } else { // perspective case 247 } else { // perspective case
292 SkScalar dstX = SkIntToScalar(x) + SK_ScalarHalf; 248 SkScalar dstX = SkIntToScalar(x) + SK_ScalarHalf;
293 SkScalar dstY = SkIntToScalar(y) + SK_ScalarHalf; 249 SkScalar dstY = SkIntToScalar(y) + SK_ScalarHalf;
294 for (; count > 0; --count) { 250 for (; count > 0; --count) {
295 SkPoint srcPt; 251 SkPoint srcPt;
296 dstProc(fDstToIndex, dstX, dstY, &srcPt); 252 dstProc(fDstToIndex, dstX, dstY, &srcPt);
297 TwoPtRadialContext rec(twoPointConicalGradient.fRec, srcPt.fX, srcPt .fY, 0, 0); 253 fRec.setup(srcPt.fX, srcPt.fY, 0, 0);
298 (*shadeProc)(&rec, dstC, cache, toggle, 1); 254 (*shadeProc)(&fRec, dstC, cache, toggle, 1);
299 255
300 dstX += SK_Scalar1; 256 dstX += SK_Scalar1;
301 toggle = next_dither_toggle(toggle); 257 toggle = next_dither_toggle(toggle);
302 dstC += 1; 258 dstC += 1;
303 } 259 }
304 } 260 }
305 } 261 }
306 262
263 bool SkTwoPointConicalGradient::setContext(const SkBitmap& device,
264 const SkPaint& paint,
265 const SkMatrix& matrix) {
266 if (!this->INHERITED::setContext(device, paint, matrix)) {
267 return false;
268 }
269
270 // we don't have a span16 proc
271 fFlags &= ~kHasSpan16_Flag;
272
273 // in general, we might discard based on computed-radius, so clear
274 // this flag (todo: sometimes we can detect that we never discard...)
275 fFlags &= ~kOpaqueAlpha_Flag;
276
277 return true;
278 }
279
307 SkShader::BitmapType SkTwoPointConicalGradient::asABitmap( 280 SkShader::BitmapType SkTwoPointConicalGradient::asABitmap(
308 SkBitmap* bitmap, SkMatrix* matrix, SkShader::TileMode* xy) const { 281 SkBitmap* bitmap, SkMatrix* matrix, SkShader::TileMode* xy) const {
309 SkPoint diff = fCenter2 - fCenter1; 282 SkPoint diff = fCenter2 - fCenter1;
310 SkScalar diffLen = 0; 283 SkScalar diffLen = 0;
311 284
312 if (bitmap) { 285 if (bitmap) {
313 this->getGradientTableBitmap(bitmap); 286 this->getGradientTableBitmap(bitmap);
314 } 287 }
315 if (matrix) { 288 if (matrix) {
316 diffLen = diff.length(); 289 diffLen = diff.length();
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 str->appendScalar(fCenter2.fY); 393 str->appendScalar(fCenter2.fY);
421 str->append(") radius2: "); 394 str->append(") radius2: ");
422 str->appendScalar(fRadius2); 395 str->appendScalar(fRadius2);
423 str->append(" "); 396 str->append(" ");
424 397
425 this->INHERITED::toString(str); 398 this->INHERITED::toString(str);
426 399
427 str->append(")"); 400 str->append(")");
428 } 401 }
429 #endif 402 #endif
OLDNEW
« no previous file with comments | « src/effects/gradients/SkTwoPointConicalGradient.h ('k') | src/effects/gradients/SkTwoPointRadialGradient.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698