OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 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 "SkRadialGradient.h" | 9 #include "SkRadialGradient.h" |
10 #include "SkRadialGradient_Table.h" | 10 #include "SkRadialGradient_Table.h" |
(...skipping 28 matching lines...) Expand all Loading... | |
39 } | 39 } |
40 } | 40 } |
41 ::fprintf(file, "};\n"); | 41 ::fprintf(file, "};\n"); |
42 ::fclose(file); | 42 ::fclose(file); |
43 } | 43 } |
44 | 44 |
45 #endif | 45 #endif |
46 | 46 |
47 namespace { | 47 namespace { |
48 | 48 |
49 // GCC doesn't like using static functions as template arguments. So force thes e to be non-static. | |
reed1
2013/10/16 15:24:05
that is some kind of crazy
| |
50 inline SkFixed mirror_tileproc_nonstatic(SkFixed x) { | |
51 return mirror_tileproc(x); | |
52 } | |
53 | |
54 inline SkFixed repeat_tileproc_nonstatic(SkFixed x) { | |
55 return repeat_tileproc(x); | |
56 } | |
57 | |
49 void rad_to_unit_matrix(const SkPoint& center, SkScalar radius, | 58 void rad_to_unit_matrix(const SkPoint& center, SkScalar radius, |
50 SkMatrix* matrix) { | 59 SkMatrix* matrix) { |
51 SkScalar inv = SkScalarInvert(radius); | 60 SkScalar inv = SkScalarInvert(radius); |
52 | 61 |
53 matrix->setTranslate(-center.fX, -center.fY); | 62 matrix->setTranslate(-center.fX, -center.fY); |
54 matrix->postScale(inv, inv); | 63 matrix->postScale(inv, inv); |
55 } | 64 } |
56 | 65 |
57 typedef void (* RadialShade16Proc)(SkScalar sfx, SkScalar sdx, | 66 typedef void (* RadialShade16Proc)(SkScalar sfx, SkScalar sdx, |
58 SkScalar sfy, SkScalar sdy, | 67 SkScalar sfy, SkScalar sdy, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
98 fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS)); | 107 fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS)); |
99 fx += dx; | 108 fx += dx; |
100 fy += dy; | 109 fy += dy; |
101 *dstC++ = cache[toggle + | 110 *dstC++ = cache[toggle + |
102 (sqrt_table[fi] >> SkGradientShaderBase::kSqrt16Shif t)]; | 111 (sqrt_table[fi] >> SkGradientShaderBase::kSqrt16Shif t)]; |
103 toggle = next_dither_toggle16(toggle); | 112 toggle = next_dither_toggle16(toggle); |
104 } while (--count != 0); | 113 } while (--count != 0); |
105 } | 114 } |
106 } | 115 } |
107 | 116 |
108 void shadeSpan16_radial_mirror(SkScalar sfx, SkScalar sdx, | 117 template <SkFixed (*TileProc)(SkFixed)> |
109 SkScalar sfy, SkScalar sdy, | 118 void shadeSpan16_radial(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy, |
110 uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RESTRICT cache, | 119 uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RESTRICT cache, |
111 int toggle, int count) { | 120 int toggle, int count) { |
112 do { | 121 do { |
113 #ifdef SK_SCALAR_IS_FLOAT | 122 const SkFixed dist = SkFloatToFixed(sk_float_sqrt(fx*fx + fy*fy)); |
114 float fdist = sk_float_sqrt(sfx*sfx + sfy*sfy); | 123 const unsigned fi = TileProc(dist); |
115 SkFixed dist = SkFloatToFixed(fdist); | |
116 #else | |
117 SkFixed magnitudeSquared = SkFixedSquare(sfx) + | |
118 SkFixedSquare(sfy); | |
119 if (magnitudeSquared < 0) // Overflow. | |
120 magnitudeSquared = SK_FixedMax; | |
121 SkFixed dist = SkFixedSqrt(magnitudeSquared); | |
122 #endif | |
123 unsigned fi = mirror_tileproc(dist); | |
124 SkASSERT(fi <= 0xFFFF); | 124 SkASSERT(fi <= 0xFFFF); |
125 *dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache16Shift)]; | 125 *dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache16Shift)]; |
126 toggle = next_dither_toggle16(toggle); | 126 toggle = next_dither_toggle16(toggle); |
127 sfx += sdx; | 127 fx += dx; |
128 sfy += sdy; | 128 fy += dy; |
129 } while (--count != 0); | 129 } while (--count != 0); |
130 } | 130 } |
131 | 131 |
132 void shadeSpan16_radial_repeat(SkScalar sfx, SkScalar sdx, | 132 void shadeSpan16_radial_mirror(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar d y, |
133 SkScalar sfy, SkScalar sdy, | 133 uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RE STRICT cache, |
134 uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RESTRICT cache, | 134 int toggle, int count) { |
135 int toggle, int count) { | 135 shadeSpan16_radial<mirror_tileproc_nonstatic>(fx, dx, fy, dy, dstC, cache, t oggle, count); |
136 SkFixed fx = SkScalarToFixed(sfx); | |
137 SkFixed dx = SkScalarToFixed(sdx); | |
138 SkFixed fy = SkScalarToFixed(sfy); | |
139 SkFixed dy = SkScalarToFixed(sdy); | |
140 do { | |
141 SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy)); | |
142 unsigned fi = repeat_tileproc(dist); | |
143 SkASSERT(fi <= 0xFFFF); | |
144 fx += dx; | |
145 fy += dy; | |
146 *dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache16Shift)]; | |
147 toggle = next_dither_toggle16(toggle); | |
148 } while (--count != 0); | |
149 } | 136 } |
150 | 137 |
138 void shadeSpan16_radial_repeat(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar d y, | |
139 uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RE STRICT cache, | |
140 int toggle, int count) { | |
141 shadeSpan16_radial<repeat_tileproc_nonstatic>(fx, dx, fy, dy, dstC, cache, t oggle, count); | |
151 } | 142 } |
152 | 143 |
144 } // namespace | |
145 | |
153 ///////////////////////////////////////////////////////////////////// | 146 ///////////////////////////////////////////////////////////////////// |
154 | 147 |
155 SkRadialGradient::SkRadialGradient(const SkPoint& center, SkScalar radius, | 148 SkRadialGradient::SkRadialGradient(const SkPoint& center, SkScalar radius, |
156 const Descriptor& desc) | 149 const Descriptor& desc) |
157 : SkGradientShaderBase(desc), | 150 : SkGradientShaderBase(desc), |
158 fCenter(center), | 151 fCenter(center), |
159 fRadius(radius) | 152 fRadius(radius) |
160 { | 153 { |
161 // make sure our table is insync with our current #define for kSQRT_TABLE_SI ZE | 154 // make sure our table is insync with our current #define for kSQRT_TABLE_SI ZE |
162 SkASSERT(sizeof(gSqrt8Table) == kSQRT_TABLE_SIZE); | 155 SkASSERT(sizeof(gSqrt8Table) == kSQRT_TABLE_SIZE); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
360 fx += dx; | 353 fx += dx; |
361 fy += dy; | 354 fy += dy; |
362 } while (--count != 0); | 355 } while (--count != 0); |
363 } | 356 } |
364 } | 357 } |
365 } | 358 } |
366 | 359 |
367 // Unrolling this loop doesn't seem to help (when float); we're stalling to | 360 // Unrolling this loop doesn't seem to help (when float); we're stalling to |
368 // get the results of the sqrt (?), and don't have enough extra registers to | 361 // get the results of the sqrt (?), and don't have enough extra registers to |
369 // have many in flight. | 362 // have many in flight. |
370 void shadeSpan_radial_mirror(SkScalar sfx, SkScalar sdx, | 363 template <SkFixed (*TileProc)(SkFixed)> |
371 SkScalar sfy, SkScalar sdy, | 364 void shadeSpan_radial(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy, |
372 SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, | 365 SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, |
373 int count, int toggle) { | 366 int count, int toggle) { |
374 do { | 367 do { |
375 #ifdef SK_SCALAR_IS_FLOAT | 368 const SkFixed dist = SkFloatToFixed(sk_float_sqrt(fx*fx + fy*fy)); |
376 float fdist = sk_float_sqrt(sfx*sfx + sfy*sfy); | 369 const unsigned fi = TileProc(dist); |
377 SkFixed dist = SkFloatToFixed(fdist); | |
378 #else | |
379 SkFixed magnitudeSquared = SkFixedSquare(sfx) + | |
380 SkFixedSquare(sfy); | |
381 if (magnitudeSquared < 0) // Overflow. | |
382 magnitudeSquared = SK_FixedMax; | |
383 SkFixed dist = SkFixedSqrt(magnitudeSquared); | |
384 #endif | |
385 unsigned fi = mirror_tileproc(dist); | |
386 SkASSERT(fi <= 0xFFFF); | 370 SkASSERT(fi <= 0xFFFF); |
387 *dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache32Shift)]; | 371 *dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache32Shift)]; |
388 toggle = next_dither_toggle(toggle); | 372 toggle = next_dither_toggle(toggle); |
389 sfx += sdx; | |
390 sfy += sdy; | |
391 } while (--count != 0); | |
392 } | |
393 | |
394 void shadeSpan_radial_repeat(SkScalar sfx, SkScalar sdx, | |
395 SkScalar sfy, SkScalar sdy, | |
396 SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, | |
397 int count, int toggle) { | |
398 SkFixed fx = SkScalarToFixed(sfx); | |
399 SkFixed dx = SkScalarToFixed(sdx); | |
400 SkFixed fy = SkScalarToFixed(sfy); | |
401 SkFixed dy = SkScalarToFixed(sdy); | |
402 do { | |
403 SkFixed magnitudeSquared = SkFixedSquare(fx) + | |
404 SkFixedSquare(fy); | |
405 if (magnitudeSquared < 0) // Overflow. | |
406 magnitudeSquared = SK_FixedMax; | |
407 SkFixed dist = SkFixedSqrt(magnitudeSquared); | |
408 unsigned fi = repeat_tileproc(dist); | |
409 SkASSERT(fi <= 0xFFFF); | |
410 *dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache32Shift)]; | |
411 toggle = next_dither_toggle(toggle); | |
412 fx += dx; | 373 fx += dx; |
413 fy += dy; | 374 fy += dy; |
414 } while (--count != 0); | 375 } while (--count != 0); |
415 } | 376 } |
377 | |
378 void shadeSpan_radial_mirror(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy, | |
379 SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RE STRICT cache, | |
380 int count, int toggle) { | |
381 shadeSpan_radial<mirror_tileproc_nonstatic>(fx, dx, fy, dy, dstC, cache, cou nt, toggle); | |
416 } | 382 } |
417 | 383 |
384 void shadeSpan_radial_repeat(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy, | |
385 SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RE STRICT cache, | |
386 int count, int toggle) { | |
387 shadeSpan_radial<repeat_tileproc_nonstatic>(fx, dx, fy, dy, dstC, cache, cou nt, toggle); | |
388 } | |
389 | |
390 } // namespace | |
391 | |
418 void SkRadialGradient::shadeSpan(int x, int y, | 392 void SkRadialGradient::shadeSpan(int x, int y, |
419 SkPMColor* SK_RESTRICT dstC, int count) { | 393 SkPMColor* SK_RESTRICT dstC, int count) { |
420 SkASSERT(count > 0); | 394 SkASSERT(count > 0); |
421 | 395 |
422 SkPoint srcPt; | 396 SkPoint srcPt; |
423 SkMatrix::MapXYProc dstProc = fDstToIndexProc; | 397 SkMatrix::MapXYProc dstProc = fDstToIndexProc; |
424 TileProc proc = fTileProc; | 398 TileProc proc = fTileProc; |
425 const SkPMColor* SK_RESTRICT cache = this->getCache32(); | 399 const SkPMColor* SK_RESTRICT cache = this->getCache32(); |
426 int toggle = init_dither_toggle(x, y); | 400 int toggle = init_dither_toggle(x, y); |
427 | 401 |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
599 str->appendScalar(fCenter.fY); | 573 str->appendScalar(fCenter.fY); |
600 str->append(") radius: "); | 574 str->append(") radius: "); |
601 str->appendScalar(fRadius); | 575 str->appendScalar(fRadius); |
602 str->append(" "); | 576 str->append(" "); |
603 | 577 |
604 this->INHERITED::toString(str); | 578 this->INHERITED::toString(str); |
605 | 579 |
606 str->append(")"); | 580 str->append(")"); |
607 } | 581 } |
608 #endif | 582 #endif |
OLD | NEW |