| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 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 "SkGradientShaderPriv.h" | 8 #include "SkGradientShaderPriv.h" |
| 9 #include "SkLinearGradient.h" | 9 #include "SkLinearGradient.h" |
| 10 #include "SkRadialGradient.h" | 10 #include "SkRadialGradient.h" |
| 11 #include "SkTwoPointRadialGradient.h" | 11 #include "SkTwoPointRadialGradient.h" |
| 12 #include "SkTwoPointConicalGradient.h" | 12 #include "SkTwoPointConicalGradient.h" |
| 13 #include "SkSweepGradient.h" | 13 #include "SkSweepGradient.h" |
| 14 | 14 |
| 15 SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc) { | 15 SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc) { |
| 16 SkASSERT(desc.fCount > 1); | 16 SkASSERT(desc.fCount > 1); |
| 17 | 17 |
| 18 fCacheAlpha = 256; // init to a value that paint.getAlpha() can't return | 18 fCacheAlpha = 256; // init to a value that paint.getAlpha() can't return |
| 19 | 19 |
| 20 fMapper = desc.fMapper; | 20 fMapper = desc.fMapper; |
| 21 SkSafeRef(fMapper); | 21 SkSafeRef(fMapper); |
| 22 fGradFlags = SkToU8(desc.fFlags); |
| 22 | 23 |
| 23 SkASSERT((unsigned)desc.fTileMode < SkShader::kTileModeCount); | 24 SkASSERT((unsigned)desc.fTileMode < SkShader::kTileModeCount); |
| 24 SkASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gTileProcs)); | 25 SkASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gTileProcs)); |
| 25 fTileMode = desc.fTileMode; | 26 fTileMode = desc.fTileMode; |
| 26 fTileProc = gTileProcs[desc.fTileMode]; | 27 fTileProc = gTileProcs[desc.fTileMode]; |
| 27 | 28 |
| 28 fCache16 = fCache16Storage = NULL; | 29 fCache16 = fCache16Storage = NULL; |
| 29 fCache32 = NULL; | 30 fCache32 = NULL; |
| 30 fCache32PixelRef = NULL; | 31 fCache32PixelRef = NULL; |
| 31 | 32 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 recs->fPos = p; | 122 recs->fPos = p; |
| 122 recs->fScale = scale; | 123 recs->fScale = scale; |
| 123 recs += 1; | 124 recs += 1; |
| 124 p += dp; | 125 p += dp; |
| 125 } | 126 } |
| 126 } | 127 } |
| 127 } | 128 } |
| 128 this->initCommon(); | 129 this->initCommon(); |
| 129 } | 130 } |
| 130 | 131 |
| 131 SkGradientShaderBase::SkGradientShaderBase(SkFlattenableReadBuffer& buffer) : | 132 static uint32_t pack_mode_flags(SkShader::TileMode mode, uint32_t flags) { |
| 132 INHERITED(buffer) { | 133 SkASSERT(0 == (flags >> 28)); |
| 134 SkASSERT(0 == ((uint32_t)mode >> 4)); |
| 135 return (flags << 4) | mode; |
| 136 } |
| 137 |
| 138 static SkShader::TileMode unpack_mode(uint32_t packed) { |
| 139 return (SkShader::TileMode)(packed & 0xF); |
| 140 } |
| 141 |
| 142 static uint32_t unpack_flags(uint32_t packed) { |
| 143 return packed >> 4; |
| 144 } |
| 145 |
| 146 SkGradientShaderBase::SkGradientShaderBase(SkFlattenableReadBuffer& buffer) : IN
HERITED(buffer) { |
| 133 fCacheAlpha = 256; | 147 fCacheAlpha = 256; |
| 134 | 148 |
| 135 fMapper = buffer.readFlattenableT<SkUnitMapper>(); | 149 fMapper = buffer.readFlattenableT<SkUnitMapper>(); |
| 136 | 150 |
| 137 fCache16 = fCache16Storage = NULL; | 151 fCache16 = fCache16Storage = NULL; |
| 138 fCache32 = NULL; | 152 fCache32 = NULL; |
| 139 fCache32PixelRef = NULL; | 153 fCache32PixelRef = NULL; |
| 140 | 154 |
| 141 int colorCount = fColorCount = buffer.getArrayCount(); | 155 int colorCount = fColorCount = buffer.getArrayCount(); |
| 142 if (colorCount > kColorStorageCount) { | 156 if (colorCount > kColorStorageCount) { |
| 143 size_t size = sizeof(SkColor) + sizeof(SkPMColor) + sizeof(Rec); | 157 size_t size = sizeof(SkColor) + sizeof(SkPMColor) + sizeof(Rec); |
| 144 fOrigColors = (SkColor*)sk_malloc_throw(size * colorCount); | 158 fOrigColors = (SkColor*)sk_malloc_throw(size * colorCount); |
| 145 } else { | 159 } else { |
| 146 fOrigColors = fStorage; | 160 fOrigColors = fStorage; |
| 147 } | 161 } |
| 148 buffer.readColorArray(fOrigColors); | 162 buffer.readColorArray(fOrigColors); |
| 149 | 163 |
| 150 fTileMode = (TileMode)buffer.readUInt(); | 164 { |
| 165 uint32_t packed = buffer.readUInt(); |
| 166 fGradFlags = SkToU8(unpack_flags(packed)); |
| 167 fTileMode = unpack_mode(packed); |
| 168 } |
| 151 fTileProc = gTileProcs[fTileMode]; | 169 fTileProc = gTileProcs[fTileMode]; |
| 152 fRecs = (Rec*)(fOrigColors + colorCount); | 170 fRecs = (Rec*)(fOrigColors + colorCount); |
| 153 if (colorCount > 2) { | 171 if (colorCount > 2) { |
| 154 Rec* recs = fRecs; | 172 Rec* recs = fRecs; |
| 155 recs[0].fPos = 0; | 173 recs[0].fPos = 0; |
| 156 for (int i = 1; i < colorCount; i++) { | 174 for (int i = 1; i < colorCount; i++) { |
| 157 recs[i].fPos = buffer.readInt(); | 175 recs[i].fPos = buffer.readInt(); |
| 158 recs[i].fScale = buffer.readUInt(); | 176 recs[i].fScale = buffer.readUInt(); |
| 159 } | 177 } |
| 160 } | 178 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 179 for (int i = 0; i < fColorCount; i++) { | 197 for (int i = 0; i < fColorCount; i++) { |
| 180 colorAlpha &= SkColorGetA(fOrigColors[i]); | 198 colorAlpha &= SkColorGetA(fOrigColors[i]); |
| 181 } | 199 } |
| 182 fColorsAreOpaque = colorAlpha == 0xFF; | 200 fColorsAreOpaque = colorAlpha == 0xFF; |
| 183 } | 201 } |
| 184 | 202 |
| 185 void SkGradientShaderBase::flatten(SkFlattenableWriteBuffer& buffer) const { | 203 void SkGradientShaderBase::flatten(SkFlattenableWriteBuffer& buffer) const { |
| 186 this->INHERITED::flatten(buffer); | 204 this->INHERITED::flatten(buffer); |
| 187 buffer.writeFlattenable(fMapper); | 205 buffer.writeFlattenable(fMapper); |
| 188 buffer.writeColorArray(fOrigColors, fColorCount); | 206 buffer.writeColorArray(fOrigColors, fColorCount); |
| 189 buffer.writeUInt(fTileMode); | 207 buffer.writeUInt(pack_mode_flags(fTileMode, fGradFlags)); |
| 190 if (fColorCount > 2) { | 208 if (fColorCount > 2) { |
| 191 Rec* recs = fRecs; | 209 Rec* recs = fRecs; |
| 192 for (int i = 1; i < fColorCount; i++) { | 210 for (int i = 1; i < fColorCount; i++) { |
| 193 buffer.writeInt(recs[i].fPos); | 211 buffer.writeInt(recs[i].fPos); |
| 194 buffer.writeUInt(recs[i].fScale); | 212 buffer.writeUInt(recs[i].fScale); |
| 195 } | 213 } |
| 196 } | 214 } |
| 197 buffer.writeMatrix(fPtsToUnit); | 215 buffer.writeMatrix(fPtsToUnit); |
| 198 } | 216 } |
| 199 | 217 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 unsigned bb = b >> 16; | 299 unsigned bb = b >> 16; |
| 282 cache[0] = SkPackRGB16(SkR32ToR16(rr), SkG32ToG16(gg), SkB32ToB16(bb)); | 300 cache[0] = SkPackRGB16(SkR32ToR16(rr), SkG32ToG16(gg), SkB32ToB16(bb)); |
| 283 cache[kCache16Count] = SkDitherPack888ToRGB16(rr, gg, bb); | 301 cache[kCache16Count] = SkDitherPack888ToRGB16(rr, gg, bb); |
| 284 cache += 1; | 302 cache += 1; |
| 285 r += dr; | 303 r += dr; |
| 286 g += dg; | 304 g += dg; |
| 287 b += db; | 305 b += db; |
| 288 } while (--count != 0); | 306 } while (--count != 0); |
| 289 } | 307 } |
| 290 | 308 |
| 309 /* |
| 310 * r,g,b used to be SkFixed, but on gcc (4.2.1 mac and 4.6.3 goobuntu) in |
| 311 * release builds, we saw a compiler error where the 0xFF parameter in |
| 312 * SkPackARGB32() was being totally ignored whenever it was called with |
| 313 * a non-zero add (e.g. 0x8000). |
| 314 * |
| 315 * We found two work-arounds: |
| 316 * 1. change r,g,b to unsigned (or just one of them) |
| 317 * 2. change SkPackARGB32 to + its (a << SK_A32_SHIFT) value instead |
| 318 * of using | |
| 319 * |
| 320 * We chose #1 just because it was more localized. |
| 321 * See http://code.google.com/p/skia/issues/detail?id=1113 |
| 322 * |
| 323 * The type SkUFixed encapsulate this need for unsigned, but logically Fixed. |
| 324 */ |
| 325 typedef uint32_t SkUFixed; |
| 326 |
| 291 void SkGradientShaderBase::Build32bitCache(SkPMColor cache[], SkColor c0, SkColo
r c1, | 327 void SkGradientShaderBase::Build32bitCache(SkPMColor cache[], SkColor c0, SkColo
r c1, |
| 292 int count, U8CPU paintAlpha) { | 328 int count, U8CPU paintAlpha, uint32_t grad
Flags) { |
| 293 SkASSERT(count > 1); | 329 SkASSERT(count > 1); |
| 294 | 330 |
| 295 // need to apply paintAlpha to our two endpoints | 331 // need to apply paintAlpha to our two endpoints |
| 296 SkFixed a = SkMulDiv255Round(SkColorGetA(c0), paintAlpha); | 332 uint32_t a0 = SkMulDiv255Round(SkColorGetA(c0), paintAlpha); |
| 297 SkFixed da; | 333 uint32_t a1 = SkMulDiv255Round(SkColorGetA(c1), paintAlpha); |
| 298 { | 334 |
| 299 int tmp = SkMulDiv255Round(SkColorGetA(c1), paintAlpha); | 335 |
| 300 da = SkIntToFixed(tmp - a) / (count - 1); | 336 const bool interpInPremul = SkToBool(gradFlags & |
| 337 SkGradientShader::kInterpolateColorsInPremul_Flag); |
| 338 |
| 339 uint32_t r0 = SkColorGetR(c0); |
| 340 uint32_t g0 = SkColorGetG(c0); |
| 341 uint32_t b0 = SkColorGetB(c0); |
| 342 |
| 343 uint32_t r1 = SkColorGetR(c1); |
| 344 uint32_t g1 = SkColorGetG(c1); |
| 345 uint32_t b1 = SkColorGetB(c1); |
| 346 |
| 347 if (interpInPremul) { |
| 348 r0 = SkMulDiv255Round(r0, a0); |
| 349 g0 = SkMulDiv255Round(g0, a0); |
| 350 b0 = SkMulDiv255Round(b0, a0); |
| 351 |
| 352 r1 = SkMulDiv255Round(r1, a1); |
| 353 g1 = SkMulDiv255Round(g1, a1); |
| 354 b1 = SkMulDiv255Round(b1, a1); |
| 301 } | 355 } |
| 302 | 356 |
| 303 /* | 357 SkFixed da = SkIntToFixed(a1 - a0) / (count - 1); |
| 304 * r,g,b used to be SkFixed, but on gcc (4.2.1 mac and 4.6.3 goobuntu) in | 358 SkFixed dr = SkIntToFixed(r1 - r0) / (count - 1); |
| 305 * release builds, we saw a compiler error where the 0xFF parameter in | 359 SkFixed dg = SkIntToFixed(g1 - g0) / (count - 1); |
| 306 * SkPackARGB32() was being totally ignored whenever it was called with | 360 SkFixed db = SkIntToFixed(b1 - b0) / (count - 1); |
| 307 * a non-zero add (e.g. 0x8000). | |
| 308 * | |
| 309 * We found two work-arounds: | |
| 310 * 1. change r,g,b to unsigned (or just one of them) | |
| 311 * 2. change SkPackARGB32 to + its (a << SK_A32_SHIFT) value instead | |
| 312 * of using | | |
| 313 * | |
| 314 * We chose #1 just because it was more localized. | |
| 315 * See http://code.google.com/p/skia/issues/detail?id=1113 | |
| 316 */ | |
| 317 uint32_t r = SkColorGetR(c0); | |
| 318 uint32_t g = SkColorGetG(c0); | |
| 319 uint32_t b = SkColorGetB(c0); | |
| 320 | |
| 321 SkFixed dr = SkIntToFixed(SkColorGetR(c1) - r) / (count - 1); | |
| 322 SkFixed dg = SkIntToFixed(SkColorGetG(c1) - g) / (count - 1); | |
| 323 SkFixed db = SkIntToFixed(SkColorGetB(c1) - b) / (count - 1); | |
| 324 | 361 |
| 325 /* We pre-add 1/8 to avoid having to add this to our [0] value each time | 362 /* We pre-add 1/8 to avoid having to add this to our [0] value each time |
| 326 in the loop. Without this, the bias for each would be | 363 in the loop. Without this, the bias for each would be |
| 327 0x2000 0xA000 0xE000 0x6000 | 364 0x2000 0xA000 0xE000 0x6000 |
| 328 With this trick, we can add 0 for the first (no-op) and just adjust the | 365 With this trick, we can add 0 for the first (no-op) and just adjust the |
| 329 others. | 366 others. |
| 330 */ | 367 */ |
| 331 r = SkIntToFixed(r) + 0x2000; | 368 SkUFixed a = SkIntToFixed(a0) + 0x2000; |
| 332 g = SkIntToFixed(g) + 0x2000; | 369 SkUFixed r = SkIntToFixed(r0) + 0x2000; |
| 333 b = SkIntToFixed(b) + 0x2000; | 370 SkUFixed g = SkIntToFixed(g0) + 0x2000; |
| 371 SkUFixed b = SkIntToFixed(b0) + 0x2000; |
| 334 | 372 |
| 335 /* | 373 /* |
| 336 * Our dither-cell (spatially) is | 374 * Our dither-cell (spatially) is |
| 337 * 0 2 | 375 * 0 2 |
| 338 * 3 1 | 376 * 3 1 |
| 339 * Where | 377 * Where |
| 340 * [0] -> [-1/8 ... 1/8 ) values near 0 | 378 * [0] -> [-1/8 ... 1/8 ) values near 0 |
| 341 * [1] -> [ 1/8 ... 3/8 ) values near 1/4 | 379 * [1] -> [ 1/8 ... 3/8 ) values near 1/4 |
| 342 * [2] -> [ 3/8 ... 5/8 ) values near 1/2 | 380 * [2] -> [ 3/8 ... 5/8 ) values near 1/2 |
| 343 * [3] -> [ 5/8 ... 7/8 ) values near 3/4 | 381 * [3] -> [ 5/8 ... 7/8 ) values near 3/4 |
| 344 */ | 382 */ |
| 345 | 383 |
| 346 if (0xFF == a && 0 == da) { | 384 if (0xFF == a0 && 0 == da) { |
| 347 do { | 385 do { |
| 348 cache[kCache32Count*0] = SkPackARGB32(0xFF, (r + 0 ) >> 16, | 386 cache[kCache32Count*0] = SkPackARGB32(0xFF, (r + 0 ) >> 16, |
| 349 (g + 0 ) >> 16, | 387 (g + 0 ) >> 16, |
| 350 (b + 0 ) >> 16); | 388 (b + 0 ) >> 16); |
| 351 cache[kCache32Count*1] = SkPackARGB32(0xFF, (r + 0x8000) >> 16, | 389 cache[kCache32Count*1] = SkPackARGB32(0xFF, (r + 0x8000) >> 16, |
| 352 (g + 0x8000) >> 16, | 390 (g + 0x8000) >> 16, |
| 353 (b + 0x8000) >> 16); | 391 (b + 0x8000) >> 16); |
| 354 cache[kCache32Count*2] = SkPackARGB32(0xFF, (r + 0xC000) >> 16, | 392 cache[kCache32Count*2] = SkPackARGB32(0xFF, (r + 0xC000) >> 16, |
| 355 (g + 0xC000) >> 16, | 393 (g + 0xC000) >> 16, |
| 356 (b + 0xC000) >> 16); | 394 (b + 0xC000) >> 16); |
| 357 cache[kCache32Count*3] = SkPackARGB32(0xFF, (r + 0x4000) >> 16, | 395 cache[kCache32Count*3] = SkPackARGB32(0xFF, (r + 0x4000) >> 16, |
| 358 (g + 0x4000) >> 16, | 396 (g + 0x4000) >> 16, |
| 359 (b + 0x4000) >> 16); | 397 (b + 0x4000) >> 16); |
| 360 cache += 1; | 398 cache += 1; |
| 361 r += dr; | 399 r += dr; |
| 362 g += dg; | 400 g += dg; |
| 363 b += db; | 401 b += db; |
| 364 } while (--count != 0); | 402 } while (--count != 0); |
| 365 } else { | 403 } else if (interpInPremul) { |
| 366 a = SkIntToFixed(a) + 0x2000; | 404 do { |
| 405 cache[kCache32Count*0] = SkPackARGB32((a + 0 ) >> 16, |
| 406 (r + 0 ) >> 16, |
| 407 (g + 0 ) >> 16, |
| 408 (b + 0 ) >> 16); |
| 409 cache[kCache32Count*1] = SkPackARGB32((a + 0x8000) >> 16, |
| 410 (r + 0x8000) >> 16, |
| 411 (g + 0x8000) >> 16, |
| 412 (b + 0x8000) >> 16); |
| 413 cache[kCache32Count*2] = SkPackARGB32((a + 0xC000) >> 16, |
| 414 (r + 0xC000) >> 16, |
| 415 (g + 0xC000) >> 16, |
| 416 (b + 0xC000) >> 16); |
| 417 cache[kCache32Count*3] = SkPackARGB32((a + 0x4000) >> 16, |
| 418 (r + 0x4000) >> 16, |
| 419 (g + 0x4000) >> 16, |
| 420 (b + 0x4000) >> 16); |
| 421 cache += 1; |
| 422 a += da; |
| 423 r += dr; |
| 424 g += dg; |
| 425 b += db; |
| 426 } while (--count != 0); |
| 427 } else { // interpolate in unpreml space |
| 367 do { | 428 do { |
| 368 cache[kCache32Count*0] = SkPremultiplyARGBInline((a + 0 ) >> 16, | 429 cache[kCache32Count*0] = SkPremultiplyARGBInline((a + 0 ) >> 16, |
| 369 (r + 0 ) >> 16, | 430 (r + 0 ) >> 16, |
| 370 (g + 0 ) >> 16, | 431 (g + 0 ) >> 16, |
| 371 (b + 0 ) >> 16)
; | 432 (b + 0 ) >> 16)
; |
| 372 cache[kCache32Count*1] = SkPremultiplyARGBInline((a + 0x8000) >> 16, | 433 cache[kCache32Count*1] = SkPremultiplyARGBInline((a + 0x8000) >> 16, |
| 373 (r + 0x8000) >> 16, | 434 (r + 0x8000) >> 16, |
| 374 (g + 0x8000) >> 16, | 435 (g + 0x8000) >> 16, |
| 375 (b + 0x8000) >> 16)
; | 436 (b + 0x8000) >> 16)
; |
| 376 cache[kCache32Count*2] = SkPremultiplyARGBInline((a + 0xC000) >> 16, | 437 cache[kCache32Count*2] = SkPremultiplyARGBInline((a + 0xC000) >> 16, |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 const int entryCount = kCache32Count * 4; | 517 const int entryCount = kCache32Count * 4; |
| 457 const size_t allocSize = sizeof(SkPMColor) * entryCount; | 518 const size_t allocSize = sizeof(SkPMColor) * entryCount; |
| 458 | 519 |
| 459 if (NULL == fCache32PixelRef) { | 520 if (NULL == fCache32PixelRef) { |
| 460 fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef, | 521 fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef, |
| 461 (NULL, allocSize, NULL)); | 522 (NULL, allocSize, NULL)); |
| 462 } | 523 } |
| 463 fCache32 = (SkPMColor*)fCache32PixelRef->getAddr(); | 524 fCache32 = (SkPMColor*)fCache32PixelRef->getAddr(); |
| 464 if (fColorCount == 2) { | 525 if (fColorCount == 2) { |
| 465 Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1], | 526 Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1], |
| 466 kCache32Count, fCacheAlpha); | 527 kCache32Count, fCacheAlpha, fGradFlags); |
| 467 } else { | 528 } else { |
| 468 Rec* rec = fRecs; | 529 Rec* rec = fRecs; |
| 469 int prevIndex = 0; | 530 int prevIndex = 0; |
| 470 for (int i = 1; i < fColorCount; i++) { | 531 for (int i = 1; i < fColorCount; i++) { |
| 471 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache32Shift; | 532 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache32Shift; |
| 472 SkASSERT(nextIndex < kCache32Count); | 533 SkASSERT(nextIndex < kCache32Count); |
| 473 | 534 |
| 474 if (nextIndex > prevIndex) | 535 if (nextIndex > prevIndex) |
| 475 Build32bitCache(fCache32 + prevIndex, fOrigColors[i-1], | 536 Build32bitCache(fCache32 + prevIndex, fOrigColors[i-1], |
| 476 fOrigColors[i], | 537 fOrigColors[i], nextIndex - prevIndex + 1, |
| 477 nextIndex - prevIndex + 1, fCacheAlpha); | 538 fCacheAlpha, fGradFlags); |
| 478 prevIndex = nextIndex; | 539 prevIndex = nextIndex; |
| 479 } | 540 } |
| 480 } | 541 } |
| 481 | 542 |
| 482 if (fMapper) { | 543 if (fMapper) { |
| 483 SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef, | 544 SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef, |
| 484 (NULL, allocSize, NULL)); | 545 (NULL, allocSize, NULL)); |
| 485 SkPMColor* linear = fCache32; // just computed linear data | 546 SkPMColor* linear = fCache32; // just computed linear data |
| 486 SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for
mapped data | 547 SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for
mapped data |
| 487 SkUnitMapper* map = fMapper; | 548 SkUnitMapper* map = fMapper; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 515 | 576 |
| 516 // don't have a way to put the mapper into our cache-key yet | 577 // don't have a way to put the mapper into our cache-key yet |
| 517 if (fMapper) { | 578 if (fMapper) { |
| 518 // force our cahce32pixelref to be built | 579 // force our cahce32pixelref to be built |
| 519 (void)this->getCache32(); | 580 (void)this->getCache32(); |
| 520 bitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1); | 581 bitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1); |
| 521 bitmap->setPixelRef(fCache32PixelRef); | 582 bitmap->setPixelRef(fCache32PixelRef); |
| 522 return; | 583 return; |
| 523 } | 584 } |
| 524 | 585 |
| 525 // build our key: [numColors + colors[] + {positions[]} ] | 586 // build our key: [numColors + colors[] + {positions[]} + flags ] |
| 526 int count = 1 + fColorCount; | 587 int count = 1 + fColorCount + 1; |
| 527 if (fColorCount > 2) { | 588 if (fColorCount > 2) { |
| 528 count += fColorCount - 1; // fRecs[].fPos | 589 count += fColorCount - 1; // fRecs[].fPos |
| 529 } | 590 } |
| 530 | 591 |
| 531 SkAutoSTMalloc<16, int32_t> storage(count); | 592 SkAutoSTMalloc<16, int32_t> storage(count); |
| 532 int32_t* buffer = storage.get(); | 593 int32_t* buffer = storage.get(); |
| 533 | 594 |
| 534 *buffer++ = fColorCount; | 595 *buffer++ = fColorCount; |
| 535 memcpy(buffer, fOrigColors, fColorCount * sizeof(SkColor)); | 596 memcpy(buffer, fOrigColors, fColorCount * sizeof(SkColor)); |
| 536 buffer += fColorCount; | 597 buffer += fColorCount; |
| 537 if (fColorCount > 2) { | 598 if (fColorCount > 2) { |
| 538 for (int i = 1; i < fColorCount; i++) { | 599 for (int i = 1; i < fColorCount; i++) { |
| 539 *buffer++ = fRecs[i].fPos; | 600 *buffer++ = fRecs[i].fPos; |
| 540 } | 601 } |
| 541 } | 602 } |
| 603 *buffer++ = fGradFlags; |
| 542 SkASSERT(buffer - storage.get() == count); | 604 SkASSERT(buffer - storage.get() == count); |
| 543 | 605 |
| 544 /////////////////////////////////// | 606 /////////////////////////////////// |
| 545 | 607 |
| 546 SK_DECLARE_STATIC_MUTEX(gMutex); | 608 SK_DECLARE_STATIC_MUTEX(gMutex); |
| 547 static SkBitmapCache* gCache; | 609 static SkBitmapCache* gCache; |
| 548 // each cache cost 1K of RAM, since each bitmap will be 1x256 at 32bpp | 610 // each cache cost 1K of RAM, since each bitmap will be 1x256 at 32bpp |
| 549 static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32; | 611 static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32; |
| 550 SkAutoMutexAcquire ama(gMutex); | 612 SkAutoMutexAcquire ama(gMutex); |
| 551 | 613 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 576 info->fColorOffsets[1] = SK_Scalar1; | 638 info->fColorOffsets[1] = SK_Scalar1; |
| 577 } else if (fColorCount > 2) { | 639 } else if (fColorCount > 2) { |
| 578 for (int i = 0; i < fColorCount; ++i) { | 640 for (int i = 0; i < fColorCount; ++i) { |
| 579 info->fColorOffsets[i] = SkFixedToScalar(fRecs[i].fPos); | 641 info->fColorOffsets[i] = SkFixedToScalar(fRecs[i].fPos); |
| 580 } | 642 } |
| 581 } | 643 } |
| 582 } | 644 } |
| 583 } | 645 } |
| 584 info->fColorCount = fColorCount; | 646 info->fColorCount = fColorCount; |
| 585 info->fTileMode = fTileMode; | 647 info->fTileMode = fTileMode; |
| 648 info->fGradientFlags = fGradFlags; |
| 586 } | 649 } |
| 587 } | 650 } |
| 588 | 651 |
| 589 #ifdef SK_DEVELOPER | 652 #ifdef SK_DEVELOPER |
| 590 void SkGradientShaderBase::toString(SkString* str) const { | 653 void SkGradientShaderBase::toString(SkString* str) const { |
| 591 | 654 |
| 592 str->appendf("%d colors: ", fColorCount); | 655 str->appendf("%d colors: ", fColorCount); |
| 593 | 656 |
| 594 for (int i = 0; i < fColorCount; ++i) { | 657 for (int i = 0; i < fColorCount; ++i) { |
| 595 str->appendHex(fOrigColors[i]); | 658 str->appendHex(fOrigColors[i]); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 colors = tmp; \ | 699 colors = tmp; \ |
| 637 pos = NULL; \ | 700 pos = NULL; \ |
| 638 count = 2; \ | 701 count = 2; \ |
| 639 } \ | 702 } \ |
| 640 } while (0) | 703 } while (0) |
| 641 | 704 |
| 642 static void desc_init(SkGradientShaderBase::Descriptor* desc, | 705 static void desc_init(SkGradientShaderBase::Descriptor* desc, |
| 643 const SkColor colors[], | 706 const SkColor colors[], |
| 644 const SkScalar pos[], int colorCount, | 707 const SkScalar pos[], int colorCount, |
| 645 SkShader::TileMode mode, | 708 SkShader::TileMode mode, |
| 646 SkUnitMapper* mapper) { | 709 SkUnitMapper* mapper, uint32_t flags) { |
| 647 desc->fColors = colors; | 710 desc->fColors = colors; |
| 648 desc->fPos = pos; | 711 desc->fPos = pos; |
| 649 desc->fCount = colorCount; | 712 desc->fCount = colorCount; |
| 650 desc->fTileMode = mode; | 713 desc->fTileMode = mode; |
| 651 desc->fMapper = mapper; | 714 desc->fMapper = mapper; |
| 715 desc->fFlags = flags; |
| 652 } | 716 } |
| 653 | 717 |
| 654 SkShader* SkGradientShader::CreateLinear(const SkPoint pts[2], | 718 SkShader* SkGradientShader::CreateLinear(const SkPoint pts[2], |
| 655 const SkColor colors[], | 719 const SkColor colors[], |
| 656 const SkScalar pos[], int colorCount, | 720 const SkScalar pos[], int colorCount, |
| 657 SkShader::TileMode mode, | 721 SkShader::TileMode mode, |
| 658 SkUnitMapper* mapper) { | 722 SkUnitMapper* mapper, |
| 723 uint32_t flags) { |
| 659 if (NULL == pts || NULL == colors || colorCount < 1) { | 724 if (NULL == pts || NULL == colors || colorCount < 1) { |
| 660 return NULL; | 725 return NULL; |
| 661 } | 726 } |
| 662 EXPAND_1_COLOR(colorCount); | 727 EXPAND_1_COLOR(colorCount); |
| 663 | 728 |
| 664 SkGradientShaderBase::Descriptor desc; | 729 SkGradientShaderBase::Descriptor desc; |
| 665 desc_init(&desc, colors, pos, colorCount, mode, mapper); | 730 desc_init(&desc, colors, pos, colorCount, mode, mapper, flags); |
| 666 return SkNEW_ARGS(SkLinearGradient, (pts, desc)); | 731 return SkNEW_ARGS(SkLinearGradient, (pts, desc)); |
| 667 } | 732 } |
| 668 | 733 |
| 669 SkShader* SkGradientShader::CreateRadial(const SkPoint& center, SkScalar radius, | 734 SkShader* SkGradientShader::CreateRadial(const SkPoint& center, SkScalar radius, |
| 670 const SkColor colors[], | 735 const SkColor colors[], |
| 671 const SkScalar pos[], int colorCount, | 736 const SkScalar pos[], int colorCount, |
| 672 SkShader::TileMode mode, | 737 SkShader::TileMode mode, |
| 673 SkUnitMapper* mapper) { | 738 SkUnitMapper* mapper, |
| 739 uint32_t flags) { |
| 674 if (radius <= 0 || NULL == colors || colorCount < 1) { | 740 if (radius <= 0 || NULL == colors || colorCount < 1) { |
| 675 return NULL; | 741 return NULL; |
| 676 } | 742 } |
| 677 EXPAND_1_COLOR(colorCount); | 743 EXPAND_1_COLOR(colorCount); |
| 678 | 744 |
| 679 SkGradientShaderBase::Descriptor desc; | 745 SkGradientShaderBase::Descriptor desc; |
| 680 desc_init(&desc, colors, pos, colorCount, mode, mapper); | 746 desc_init(&desc, colors, pos, colorCount, mode, mapper, flags); |
| 681 return SkNEW_ARGS(SkRadialGradient, (center, radius, desc)); | 747 return SkNEW_ARGS(SkRadialGradient, (center, radius, desc)); |
| 682 } | 748 } |
| 683 | 749 |
| 684 SkShader* SkGradientShader::CreateTwoPointRadial(const SkPoint& start, | 750 SkShader* SkGradientShader::CreateTwoPointRadial(const SkPoint& start, |
| 685 SkScalar startRadius, | 751 SkScalar startRadius, |
| 686 const SkPoint& end, | 752 const SkPoint& end, |
| 687 SkScalar endRadius, | 753 SkScalar endRadius, |
| 688 const SkColor colors[], | 754 const SkColor colors[], |
| 689 const SkScalar pos[], | 755 const SkScalar pos[], |
| 690 int colorCount, | 756 int colorCount, |
| 691 SkShader::TileMode mode, | 757 SkShader::TileMode mode, |
| 692 SkUnitMapper* mapper) { | 758 SkUnitMapper* mapper, |
| 759 uint32_t flags) { |
| 693 if (startRadius < 0 || endRadius < 0 || NULL == colors || colorCount < 1) { | 760 if (startRadius < 0 || endRadius < 0 || NULL == colors || colorCount < 1) { |
| 694 return NULL; | 761 return NULL; |
| 695 } | 762 } |
| 696 EXPAND_1_COLOR(colorCount); | 763 EXPAND_1_COLOR(colorCount); |
| 697 | 764 |
| 698 SkGradientShaderBase::Descriptor desc; | 765 SkGradientShaderBase::Descriptor desc; |
| 699 desc_init(&desc, colors, pos, colorCount, mode, mapper); | 766 desc_init(&desc, colors, pos, colorCount, mode, mapper, flags); |
| 700 return SkNEW_ARGS(SkTwoPointRadialGradient, | 767 return SkNEW_ARGS(SkTwoPointRadialGradient, |
| 701 (start, startRadius, end, endRadius, desc)); | 768 (start, startRadius, end, endRadius, desc)); |
| 702 } | 769 } |
| 703 | 770 |
| 704 SkShader* SkGradientShader::CreateTwoPointConical(const SkPoint& start, | 771 SkShader* SkGradientShader::CreateTwoPointConical(const SkPoint& start, |
| 705 SkScalar startRadius, | 772 SkScalar startRadius, |
| 706 const SkPoint& end, | 773 const SkPoint& end, |
| 707 SkScalar endRadius, | 774 SkScalar endRadius, |
| 708 const SkColor colors[], | 775 const SkColor colors[], |
| 709 const SkScalar pos[], | 776 const SkScalar pos[], |
| 710 int colorCount, | 777 int colorCount, |
| 711 SkShader::TileMode mode, | 778 SkShader::TileMode mode, |
| 712 SkUnitMapper* mapper) { | 779 SkUnitMapper* mapper, |
| 780 uint32_t flags) { |
| 713 if (startRadius < 0 || endRadius < 0 || NULL == colors || colorCount < 1) { | 781 if (startRadius < 0 || endRadius < 0 || NULL == colors || colorCount < 1) { |
| 714 return NULL; | 782 return NULL; |
| 715 } | 783 } |
| 716 if (start == end && startRadius == endRadius) { | 784 if (start == end && startRadius == endRadius) { |
| 717 return SkNEW(SkEmptyShader); | 785 return SkNEW(SkEmptyShader); |
| 718 } | 786 } |
| 719 EXPAND_1_COLOR(colorCount); | 787 EXPAND_1_COLOR(colorCount); |
| 720 | 788 |
| 721 SkGradientShaderBase::Descriptor desc; | 789 SkGradientShaderBase::Descriptor desc; |
| 722 desc_init(&desc, colors, pos, colorCount, mode, mapper); | 790 desc_init(&desc, colors, pos, colorCount, mode, mapper, flags); |
| 723 return SkNEW_ARGS(SkTwoPointConicalGradient, | 791 return SkNEW_ARGS(SkTwoPointConicalGradient, |
| 724 (start, startRadius, end, endRadius, desc)); | 792 (start, startRadius, end, endRadius, desc)); |
| 725 } | 793 } |
| 726 | 794 |
| 727 SkShader* SkGradientShader::CreateSweep(SkScalar cx, SkScalar cy, | 795 SkShader* SkGradientShader::CreateSweep(SkScalar cx, SkScalar cy, |
| 728 const SkColor colors[], | 796 const SkColor colors[], |
| 729 const SkScalar pos[], | 797 const SkScalar pos[], |
| 730 int colorCount, SkUnitMapper* mapper) { | 798 int colorCount, SkUnitMapper* mapper, |
| 799 uint32_t flags) { |
| 731 if (NULL == colors || colorCount < 1) { | 800 if (NULL == colors || colorCount < 1) { |
| 732 return NULL; | 801 return NULL; |
| 733 } | 802 } |
| 734 EXPAND_1_COLOR(colorCount); | 803 EXPAND_1_COLOR(colorCount); |
| 735 | 804 |
| 736 SkGradientShaderBase::Descriptor desc; | 805 SkGradientShaderBase::Descriptor desc; |
| 737 desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, mapper)
; | 806 desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, mapper,
flags); |
| 738 return SkNEW_ARGS(SkSweepGradient, (cx, cy, desc)); | 807 return SkNEW_ARGS(SkSweepGradient, (cx, cy, desc)); |
| 739 } | 808 } |
| 740 | 809 |
| 741 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader) | 810 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader) |
| 742 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient) | 811 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient) |
| 743 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient) | 812 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient) |
| 744 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient) | 813 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient) |
| 745 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointRadialGradient) | 814 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointRadialGradient) |
| 746 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient) | 815 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient) |
| 747 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 816 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 (*stops)[i] = stop; | 977 (*stops)[i] = stop; |
| 909 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st
op) : 1.f; | 978 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st
op) : 1.f; |
| 910 } | 979 } |
| 911 } | 980 } |
| 912 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM
odeCount)); | 981 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM
odeCount)); |
| 913 | 982 |
| 914 return outColors; | 983 return outColors; |
| 915 } | 984 } |
| 916 | 985 |
| 917 #endif | 986 #endif |
| OLD | NEW |