| 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 "Sk4fLinearGradient.h" | 8 #include "Sk4fLinearGradient.h" |
| 9 #include "SkGradientShaderPriv.h" | 9 #include "SkGradientShaderPriv.h" |
| 10 #include "SkLinearGradient.h" | 10 #include "SkLinearGradient.h" |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 fFlags |= kOpaqueAlpha_Flag; | 299 fFlags |= kOpaqueAlpha_Flag; |
| 300 } | 300 } |
| 301 } | 301 } |
| 302 | 302 |
| 303 SkGradientShaderBase::GradientShaderCache::GradientShaderCache( | 303 SkGradientShaderBase::GradientShaderCache::GradientShaderCache( |
| 304 U8CPU alpha, bool dither, const SkGradientShaderBase& shader) | 304 U8CPU alpha, bool dither, const SkGradientShaderBase& shader) |
| 305 : fCacheAlpha(alpha) | 305 : fCacheAlpha(alpha) |
| 306 , fCacheDither(dither) | 306 , fCacheDither(dither) |
| 307 , fShader(shader) | 307 , fShader(shader) |
| 308 { | 308 { |
| 309 // Only initialize the cache in getCache16/32. | 309 // Only initialize the cache in getCache32. |
| 310 fCache16 = nullptr; | |
| 311 fCache32 = nullptr; | 310 fCache32 = nullptr; |
| 312 fCache16Storage = nullptr; | |
| 313 fCache32PixelRef = nullptr; | 311 fCache32PixelRef = nullptr; |
| 314 } | 312 } |
| 315 | 313 |
| 316 SkGradientShaderBase::GradientShaderCache::~GradientShaderCache() { | 314 SkGradientShaderBase::GradientShaderCache::~GradientShaderCache() { |
| 317 sk_free(fCache16Storage); | |
| 318 SkSafeUnref(fCache32PixelRef); | 315 SkSafeUnref(fCache32PixelRef); |
| 319 } | 316 } |
| 320 | 317 |
| 321 #define Fixed_To_Dot8(x) (((x) + 0x80) >> 8) | |
| 322 | |
| 323 /** We take the original colors, not our premultiplied PMColors, since we can | |
| 324 build a 16bit table as long as the original colors are opaque, even if the | |
| 325 paint specifies a non-opaque alpha. | |
| 326 */ | |
| 327 void SkGradientShaderBase::GradientShaderCache::Build16bitCache( | |
| 328 uint16_t cache[], SkColor c0, SkColor c1, int count, bool dither) { | |
| 329 SkASSERT(count > 1); | |
| 330 SkASSERT(SkColorGetA(c0) == 0xFF); | |
| 331 SkASSERT(SkColorGetA(c1) == 0xFF); | |
| 332 | |
| 333 SkFixed r = SkColorGetR(c0); | |
| 334 SkFixed g = SkColorGetG(c0); | |
| 335 SkFixed b = SkColorGetB(c0); | |
| 336 | |
| 337 SkFixed dr = SkIntToFixed(SkColorGetR(c1) - r) / (count - 1); | |
| 338 SkFixed dg = SkIntToFixed(SkColorGetG(c1) - g) / (count - 1); | |
| 339 SkFixed db = SkIntToFixed(SkColorGetB(c1) - b) / (count - 1); | |
| 340 | |
| 341 r = SkIntToFixed(r) + 0x8000; | |
| 342 g = SkIntToFixed(g) + 0x8000; | |
| 343 b = SkIntToFixed(b) + 0x8000; | |
| 344 | |
| 345 if (dither) { | |
| 346 do { | |
| 347 unsigned rr = r >> 16; | |
| 348 unsigned gg = g >> 16; | |
| 349 unsigned bb = b >> 16; | |
| 350 cache[0] = SkPackRGB16(SkR32ToR16(rr), SkG32ToG16(gg), SkB32ToB16(bb
)); | |
| 351 cache[kCache16Count] = SkDitherPack888ToRGB16(rr, gg, bb); | |
| 352 cache += 1; | |
| 353 r += dr; | |
| 354 g += dg; | |
| 355 b += db; | |
| 356 } while (--count != 0); | |
| 357 } else { | |
| 358 do { | |
| 359 unsigned rr = r >> 16; | |
| 360 unsigned gg = g >> 16; | |
| 361 unsigned bb = b >> 16; | |
| 362 cache[0] = SkPackRGB16(SkR32ToR16(rr), SkG32ToG16(gg), SkB32ToB16(bb
)); | |
| 363 cache[kCache16Count] = cache[0]; | |
| 364 cache += 1; | |
| 365 r += dr; | |
| 366 g += dg; | |
| 367 b += db; | |
| 368 } while (--count != 0); | |
| 369 } | |
| 370 } | |
| 371 | |
| 372 /* | 318 /* |
| 373 * r,g,b used to be SkFixed, but on gcc (4.2.1 mac and 4.6.3 goobuntu) in | 319 * r,g,b used to be SkFixed, but on gcc (4.2.1 mac and 4.6.3 goobuntu) in |
| 374 * release builds, we saw a compiler error where the 0xFF parameter in | 320 * release builds, we saw a compiler error where the 0xFF parameter in |
| 375 * SkPackARGB32() was being totally ignored whenever it was called with | 321 * SkPackARGB32() was being totally ignored whenever it was called with |
| 376 * a non-zero add (e.g. 0x8000). | 322 * a non-zero add (e.g. 0x8000). |
| 377 * | 323 * |
| 378 * We found two work-arounds: | 324 * We found two work-arounds: |
| 379 * 1. change r,g,b to unsigned (or just one of them) | 325 * 1. change r,g,b to unsigned (or just one of them) |
| 380 * 2. change SkPackARGB32 to + its (a << SK_A32_SHIFT) value instead | 326 * 2. change SkPackARGB32 to + its (a << SK_A32_SHIFT) value instead |
| 381 * of using | | 327 * of using | |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 b += db; | 464 b += db; |
| 519 } while (--count != 0); | 465 } while (--count != 0); |
| 520 } | 466 } |
| 521 } | 467 } |
| 522 | 468 |
| 523 static inline int SkFixedToFFFF(SkFixed x) { | 469 static inline int SkFixedToFFFF(SkFixed x) { |
| 524 SkASSERT((unsigned)x <= SK_Fixed1); | 470 SkASSERT((unsigned)x <= SK_Fixed1); |
| 525 return x - (x >> 16); | 471 return x - (x >> 16); |
| 526 } | 472 } |
| 527 | 473 |
| 528 const uint16_t* SkGradientShaderBase::GradientShaderCache::getCache16() { | |
| 529 fCache16InitOnce(SkGradientShaderBase::GradientShaderCache::initCache16, thi
s); | |
| 530 SkASSERT(fCache16); | |
| 531 return fCache16; | |
| 532 } | |
| 533 | |
| 534 void SkGradientShaderBase::GradientShaderCache::initCache16(GradientShaderCache*
cache) { | |
| 535 // double the count for dither entries | |
| 536 const int entryCount = kCache16Count * 2; | |
| 537 const size_t allocSize = sizeof(uint16_t) * entryCount; | |
| 538 | |
| 539 SkASSERT(nullptr == cache->fCache16Storage); | |
| 540 cache->fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize); | |
| 541 cache->fCache16 = cache->fCache16Storage; | |
| 542 if (cache->fShader.fColorCount == 2) { | |
| 543 Build16bitCache(cache->fCache16, cache->fShader.fOrigColors[0], | |
| 544 cache->fShader.fOrigColors[1], kCache16Count, cache->fCa
cheDither); | |
| 545 } else { | |
| 546 Rec* rec = cache->fShader.fRecs; | |
| 547 int prevIndex = 0; | |
| 548 for (int i = 1; i < cache->fShader.fColorCount; i++) { | |
| 549 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache16Shift; | |
| 550 SkASSERT(nextIndex < kCache16Count); | |
| 551 | |
| 552 if (nextIndex > prevIndex) | |
| 553 Build16bitCache(cache->fCache16 + prevIndex, cache->fShader.fOri
gColors[i-1], | |
| 554 cache->fShader.fOrigColors[i], nextIndex - prevI
ndex + 1, | |
| 555 cache->fCacheDither); | |
| 556 prevIndex = nextIndex; | |
| 557 } | |
| 558 } | |
| 559 } | |
| 560 | |
| 561 const SkPMColor* SkGradientShaderBase::GradientShaderCache::getCache32() { | 474 const SkPMColor* SkGradientShaderBase::GradientShaderCache::getCache32() { |
| 562 fCache32InitOnce(SkGradientShaderBase::GradientShaderCache::initCache32, thi
s); | 475 fCache32InitOnce(SkGradientShaderBase::GradientShaderCache::initCache32, thi
s); |
| 563 SkASSERT(fCache32); | 476 SkASSERT(fCache32); |
| 564 return fCache32; | 477 return fCache32; |
| 565 } | 478 } |
| 566 | 479 |
| 567 void SkGradientShaderBase::GradientShaderCache::initCache32(GradientShaderCache*
cache) { | 480 void SkGradientShaderBase::GradientShaderCache::initCache32(GradientShaderCache*
cache) { |
| 568 const int kNumberOfDitherRows = 4; | 481 const int kNumberOfDitherRows = 4; |
| 569 const SkImageInfo info = SkImageInfo::MakeN32Premul(kCache32Count, kNumberOf
DitherRows); | 482 const SkImageInfo info = SkImageInfo::MakeN32Premul(kCache32Count, kNumberOf
DitherRows); |
| 570 | 483 |
| (...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1484 (*stops)[i] = stop; | 1397 (*stops)[i] = stop; |
| 1485 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st
op) : 1.f; | 1398 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st
op) : 1.f; |
| 1486 } | 1399 } |
| 1487 } | 1400 } |
| 1488 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM
odeCount)); | 1401 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM
odeCount)); |
| 1489 | 1402 |
| 1490 return outColors; | 1403 return outColors; |
| 1491 } | 1404 } |
| 1492 | 1405 |
| 1493 #endif | 1406 #endif |
| OLD | NEW |