Chromium Code Reviews| 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 |