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

Side by Side Diff: src/effects/gradients/SkGradientShader.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
« no previous file with comments | « src/effects/SkTransparentShader.cpp ('k') | src/effects/gradients/SkGradientShaderPriv.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
19
18 fMapper = desc.fMapper; 20 fMapper = desc.fMapper;
19 SkSafeRef(fMapper); 21 SkSafeRef(fMapper);
20 fGradFlags = SkToU8(desc.fGradFlags); 22 fGradFlags = SkToU8(desc.fGradFlags);
21 23
22 SkASSERT((unsigned)desc.fTileMode < SkShader::kTileModeCount); 24 SkASSERT((unsigned)desc.fTileMode < SkShader::kTileModeCount);
23 SkASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gTileProcs)); 25 SkASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gTileProcs));
24 fTileMode = desc.fTileMode; 26 fTileMode = desc.fTileMode;
25 fTileProc = gTileProcs[desc.fTileMode]; 27 fTileProc = gTileProcs[desc.fTileMode];
26 28
29 fCache16 = fCache16Storage = NULL;
30 fCache32 = NULL;
31 fCache32PixelRef = NULL;
32
27 /* Note: we let the caller skip the first and/or last position. 33 /* Note: we let the caller skip the first and/or last position.
28 i.e. pos[0] = 0.3, pos[1] = 0.7 34 i.e. pos[0] = 0.3, pos[1] = 0.7
29 In these cases, we insert dummy entries to ensure that the final data 35 In these cases, we insert dummy entries to ensure that the final data
30 will be bracketed by [0, 1]. 36 will be bracketed by [0, 1].
31 i.e. our_pos[0] = 0, our_pos[1] = 0.3, our_pos[2] = 0.7, our_pos[3] = 1 37 i.e. our_pos[0] = 0, our_pos[1] = 0.3, our_pos[2] = 0.7, our_pos[3] = 1
32 38
33 Thus colorCount (the caller's value, and fColorCount (our value) may 39 Thus colorCount (the caller's value, and fColorCount (our value) may
34 differ by up to 2. In the above example: 40 differ by up to 2. In the above example:
35 colorCount = 2 41 colorCount = 2
36 fColorCount = 4 42 fColorCount = 4
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 139
134 static SkShader::TileMode unpack_mode(uint32_t packed) { 140 static SkShader::TileMode unpack_mode(uint32_t packed) {
135 return (SkShader::TileMode)(packed & 0xF); 141 return (SkShader::TileMode)(packed & 0xF);
136 } 142 }
137 143
138 static uint32_t unpack_flags(uint32_t packed) { 144 static uint32_t unpack_flags(uint32_t packed) {
139 return packed >> 4; 145 return packed >> 4;
140 } 146 }
141 147
142 SkGradientShaderBase::SkGradientShaderBase(SkReadBuffer& buffer) : INHERITED(buf fer) { 148 SkGradientShaderBase::SkGradientShaderBase(SkReadBuffer& buffer) : INHERITED(buf fer) {
149 fCacheAlpha = 256;
150
143 fMapper = buffer.readUnitMapper(); 151 fMapper = buffer.readUnitMapper();
144 152
153 fCache16 = fCache16Storage = NULL;
154 fCache32 = NULL;
155 fCache32PixelRef = NULL;
156
145 int colorCount = fColorCount = buffer.getArrayCount(); 157 int colorCount = fColorCount = buffer.getArrayCount();
146 if (colorCount > kColorStorageCount) { 158 if (colorCount > kColorStorageCount) {
147 size_t allocSize = (sizeof(SkColor) + sizeof(SkPMColor) + sizeof(Rec)) * colorCount; 159 size_t allocSize = (sizeof(SkColor) + sizeof(SkPMColor) + sizeof(Rec)) * colorCount;
148 if (buffer.validateAvailable(allocSize)) { 160 if (buffer.validateAvailable(allocSize)) {
149 fOrigColors = reinterpret_cast<SkColor*>(sk_malloc_throw(allocSize)) ; 161 fOrigColors = reinterpret_cast<SkColor*>(sk_malloc_throw(allocSize)) ;
150 } else { 162 } else {
151 fOrigColors = NULL; 163 fOrigColors = NULL;
152 colorCount = fColorCount = 0; 164 colorCount = fColorCount = 0;
153 } 165 }
154 } else { 166 } else {
(...skipping 14 matching lines...) Expand all
169 for (int i = 1; i < colorCount; i++) { 181 for (int i = 1; i < colorCount; i++) {
170 recs[i].fPos = buffer.readInt(); 182 recs[i].fPos = buffer.readInt();
171 recs[i].fScale = buffer.readUInt(); 183 recs[i].fScale = buffer.readUInt();
172 } 184 }
173 } 185 }
174 buffer.readMatrix(&fPtsToUnit); 186 buffer.readMatrix(&fPtsToUnit);
175 this->initCommon(); 187 this->initCommon();
176 } 188 }
177 189
178 SkGradientShaderBase::~SkGradientShaderBase() { 190 SkGradientShaderBase::~SkGradientShaderBase() {
191 if (fCache16Storage) {
192 sk_free(fCache16Storage);
193 }
194 SkSafeUnref(fCache32PixelRef);
179 if (fOrigColors != fStorage) { 195 if (fOrigColors != fStorage) {
180 sk_free(fOrigColors); 196 sk_free(fOrigColors);
181 } 197 }
182 SkSafeUnref(fMapper); 198 SkSafeUnref(fMapper);
183 } 199 }
184 200
185 void SkGradientShaderBase::initCommon() { 201 void SkGradientShaderBase::initCommon() {
202 fFlags = 0;
186 unsigned colorAlpha = 0xFF; 203 unsigned colorAlpha = 0xFF;
187 for (int i = 0; i < fColorCount; i++) { 204 for (int i = 0; i < fColorCount; i++) {
188 colorAlpha &= SkColorGetA(fOrigColors[i]); 205 colorAlpha &= SkColorGetA(fOrigColors[i]);
189 } 206 }
190 fColorsAreOpaque = colorAlpha == 0xFF; 207 fColorsAreOpaque = colorAlpha == 0xFF;
191 } 208 }
192 209
193 void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const { 210 void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const {
194 this->INHERITED::flatten(buffer); 211 this->INHERITED::flatten(buffer);
195 buffer.writeFlattenable(fMapper); 212 buffer.writeFlattenable(fMapper);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 } 260 }
244 261
245 void SkGradientShaderBase::flipGradientColors() { 262 void SkGradientShaderBase::flipGradientColors() {
246 FlipGradientColors(fOrigColors, fRecs, fOrigColors, fRecs, fColorCount); 263 FlipGradientColors(fOrigColors, fRecs, fOrigColors, fRecs, fColorCount);
247 } 264 }
248 265
249 bool SkGradientShaderBase::isOpaque() const { 266 bool SkGradientShaderBase::isOpaque() const {
250 return fColorsAreOpaque; 267 return fColorsAreOpaque;
251 } 268 }
252 269
253 SkGradientShaderBase::GradientShaderBaseContext::GradientShaderBaseContext( 270 bool SkGradientShaderBase::setContext(const SkBitmap& device,
254 const SkGradientShaderBase& shader, const SkBitmap& device, 271 const SkPaint& paint,
255 const SkPaint& paint, const SkMatrix& matrix) 272 const SkMatrix& matrix) {
256 : INHERITED(shader, device, paint, matrix) 273 if (!this->INHERITED::setContext(device, paint, matrix)) {
257 , fCache(shader.refCache(getPaintAlpha())) 274 return false;
258 { 275 }
276
259 const SkMatrix& inverse = this->getTotalInverse(); 277 const SkMatrix& inverse = this->getTotalInverse();
260 278
261 fDstToIndex.setConcat(shader.fPtsToUnit, inverse); 279 fDstToIndex.setConcat(fPtsToUnit, inverse);
262
263 fDstToIndexProc = fDstToIndex.getMapXYProc(); 280 fDstToIndexProc = fDstToIndex.getMapXYProc();
264 fDstToIndexClass = (uint8_t)SkShader::Context::ComputeMatrixClass(fDstToInde x); 281 fDstToIndexClass = (uint8_t)SkShader::ComputeMatrixClass(fDstToIndex);
265 282
266 // now convert our colors in to PMColors 283 // now convert our colors in to PMColors
267 unsigned paintAlpha = this->getPaintAlpha(); 284 unsigned paintAlpha = this->getPaintAlpha();
268 285
269 fFlags = this->INHERITED::getFlags(); 286 fFlags = this->INHERITED::getFlags();
270 if (shader.fColorsAreOpaque && paintAlpha == 0xFF) { 287 if (fColorsAreOpaque && paintAlpha == 0xFF) {
271 fFlags |= kOpaqueAlpha_Flag; 288 fFlags |= kOpaqueAlpha_Flag;
272 } 289 }
273 // we can do span16 as long as our individual colors are opaque, 290 // we can do span16 as long as our individual colors are opaque,
274 // regardless of the paint's alpha 291 // regardless of the paint's alpha
275 if (shader.fColorsAreOpaque) { 292 if (fColorsAreOpaque) {
276 fFlags |= kHasSpan16_Flag; 293 fFlags |= kHasSpan16_Flag;
277 } 294 }
295
296 this->setCacheAlpha(paintAlpha);
297 return true;
298 }
299
300 void SkGradientShaderBase::setCacheAlpha(U8CPU alpha) const {
301 // if the new alpha differs from the previous time we were called, inval our cache
302 // this will trigger the cache to be rebuilt.
303 // we don't care about the first time, since the cache ptrs will already be NULL
304 if (fCacheAlpha != alpha) {
305 fCache16 = NULL; // inval the cache
306 fCache32 = NULL; // inval the cache
307 fCacheAlpha = alpha; // record the new alpha
308 // inform our subclasses
309 if (fCache32PixelRef) {
310 fCache32PixelRef->notifyPixelsChanged();
311 }
312 }
278 } 313 }
279 314
280 SkGradientShaderBase::GradientShaderCache::GradientShaderCache(
281 U8CPU alpha, const SkGradientShaderBase& shader)
282 : fCacheAlpha(alpha)
283 , fShader(shader)
284 , fCache16Inited(false)
285 , fCache32Inited(false)
286 {
287 // Only initialize the cache in getCache16/32.
288 fCache16 = NULL;
289 fCache32 = NULL;
290 fCache16Storage = NULL;
291 fCache32PixelRef = NULL;
292 }
293
294 SkGradientShaderBase::GradientShaderCache::~GradientShaderCache() {
295 sk_free(fCache16Storage);
296 SkSafeUnref(fCache32PixelRef);
297 }
298
299 #define Fixed_To_Dot8(x) (((x) + 0x80) >> 8) 315 #define Fixed_To_Dot8(x) (((x) + 0x80) >> 8)
300 316
301 /** We take the original colors, not our premultiplied PMColors, since we can 317 /** We take the original colors, not our premultiplied PMColors, since we can
302 build a 16bit table as long as the original colors are opaque, even if the 318 build a 16bit table as long as the original colors are opaque, even if the
303 paint specifies a non-opaque alpha. 319 paint specifies a non-opaque alpha.
304 */ 320 */
305 void SkGradientShaderBase::GradientShaderCache::Build16bitCache( 321 void SkGradientShaderBase::Build16bitCache(uint16_t cache[], SkColor c0, SkColor c1,
306 uint16_t cache[], SkColor c0, SkColor c1, int count) { 322 int count) {
307 SkASSERT(count > 1); 323 SkASSERT(count > 1);
308 SkASSERT(SkColorGetA(c0) == 0xFF); 324 SkASSERT(SkColorGetA(c0) == 0xFF);
309 SkASSERT(SkColorGetA(c1) == 0xFF); 325 SkASSERT(SkColorGetA(c1) == 0xFF);
310 326
311 SkFixed r = SkColorGetR(c0); 327 SkFixed r = SkColorGetR(c0);
312 SkFixed g = SkColorGetG(c0); 328 SkFixed g = SkColorGetG(c0);
313 SkFixed b = SkColorGetB(c0); 329 SkFixed b = SkColorGetB(c0);
314 330
315 SkFixed dr = SkIntToFixed(SkColorGetR(c1) - r) / (count - 1); 331 SkFixed dr = SkIntToFixed(SkColorGetR(c1) - r) / (count - 1);
316 SkFixed dg = SkIntToFixed(SkColorGetG(c1) - g) / (count - 1); 332 SkFixed dg = SkIntToFixed(SkColorGetG(c1) - g) / (count - 1);
(...skipping 27 matching lines...) Expand all
344 * 2. change SkPackARGB32 to + its (a << SK_A32_SHIFT) value instead 360 * 2. change SkPackARGB32 to + its (a << SK_A32_SHIFT) value instead
345 * of using | 361 * of using |
346 * 362 *
347 * We chose #1 just because it was more localized. 363 * We chose #1 just because it was more localized.
348 * See http://code.google.com/p/skia/issues/detail?id=1113 364 * See http://code.google.com/p/skia/issues/detail?id=1113
349 * 365 *
350 * The type SkUFixed encapsulate this need for unsigned, but logically Fixed. 366 * The type SkUFixed encapsulate this need for unsigned, but logically Fixed.
351 */ 367 */
352 typedef uint32_t SkUFixed; 368 typedef uint32_t SkUFixed;
353 369
354 void SkGradientShaderBase::GradientShaderCache::Build32bitCache( 370 void SkGradientShaderBase::Build32bitCache(SkPMColor cache[], SkColor c0, SkColo r c1,
355 SkPMColor cache[], SkColor c0, SkColor c1, 371 int count, U8CPU paintAlpha, uint32_t grad Flags) {
356 int count, U8CPU paintAlpha, uint32_t gradFlags) {
357 SkASSERT(count > 1); 372 SkASSERT(count > 1);
358 373
359 // need to apply paintAlpha to our two endpoints 374 // need to apply paintAlpha to our two endpoints
360 uint32_t a0 = SkMulDiv255Round(SkColorGetA(c0), paintAlpha); 375 uint32_t a0 = SkMulDiv255Round(SkColorGetA(c0), paintAlpha);
361 uint32_t a1 = SkMulDiv255Round(SkColorGetA(c1), paintAlpha); 376 uint32_t a1 = SkMulDiv255Round(SkColorGetA(c1), paintAlpha);
362 377
363 378
364 const bool interpInPremul = SkToBool(gradFlags & 379 const bool interpInPremul = SkToBool(gradFlags &
365 SkGradientShader::kInterpolateColorsInPremul_Flag); 380 SkGradientShader::kInterpolateColorsInPremul_Flag);
366 381
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 if (6 == bits) { 504 if (6 == bits) {
490 return (x << 10) | (x << 4) | (x >> 2); 505 return (x << 10) | (x << 4) | (x >> 2);
491 } 506 }
492 if (8 == bits) { 507 if (8 == bits) {
493 return (x << 8) | x; 508 return (x << 8) | x;
494 } 509 }
495 sk_throw(); 510 sk_throw();
496 return 0; 511 return 0;
497 } 512 }
498 513
499 const uint16_t* SkGradientShaderBase::GradientShaderCache::getCache16() { 514 const uint16_t* SkGradientShaderBase::getCache16() const {
500 SkOnce(&fCache16Inited, &fCache16Mutex, SkGradientShaderBase::GradientShader Cache::initCache16, 515 if (fCache16 == NULL) {
501 this); 516 // double the count for dither entries
502 SkASSERT(fCache16); 517 const int entryCount = kCache16Count * 2;
518 const size_t allocSize = sizeof(uint16_t) * entryCount;
519
520 if (fCache16Storage == NULL) { // set the storage and our working ptr
521 fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize);
522 }
523 fCache16 = fCache16Storage;
524 if (fColorCount == 2) {
525 Build16bitCache(fCache16, fOrigColors[0], fOrigColors[1],
526 kCache16Count);
527 } else {
528 Rec* rec = fRecs;
529 int prevIndex = 0;
530 for (int i = 1; i < fColorCount; i++) {
531 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache16Shift;
532 SkASSERT(nextIndex < kCache16Count);
533
534 if (nextIndex > prevIndex)
535 Build16bitCache(fCache16 + prevIndex, fOrigColors[i-1], fOri gColors[i], nextIndex - prevIndex + 1);
536 prevIndex = nextIndex;
537 }
538 }
539
540 if (fMapper) {
541 fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize);
542 uint16_t* linear = fCache16; // just computed linear data
543 uint16_t* mapped = fCache16Storage; // storage for mapped data
544 SkUnitMapper* map = fMapper;
545 for (int i = 0; i < kCache16Count; i++) {
546 int index = map->mapUnit16(bitsTo16(i, kCache16Bits)) >> kCache1 6Shift;
547 mapped[i] = linear[index];
548 mapped[i + kCache16Count] = linear[index + kCache16Count];
549 }
550 sk_free(fCache16);
551 fCache16 = fCache16Storage;
552 }
553 }
503 return fCache16; 554 return fCache16;
504 } 555 }
505 556
506 void SkGradientShaderBase::GradientShaderCache::initCache16(GradientShaderCache* cache) { 557 const SkPMColor* SkGradientShaderBase::getCache32() const {
507 // double the count for dither entries 558 if (fCache32 == NULL) {
508 const int entryCount = kCache16Count * 2; 559 SkImageInfo info;
509 const size_t allocSize = sizeof(uint16_t) * entryCount; 560 info.fWidth = kCache32Count;
561 info.fHeight = 4; // for our 4 dither rows
562 info.fAlphaType = kPremul_SkAlphaType;
563 info.fColorType = kN32_SkColorType;
510 564
511 SkASSERT(NULL == cache->fCache16Storage); 565 if (NULL == fCache32PixelRef) {
512 cache->fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize); 566 fCache32PixelRef = SkMallocPixelRef::NewAllocate(info, 0, NULL);
513 cache->fCache16 = cache->fCache16Storage; 567 }
514 if (cache->fShader.fColorCount == 2) { 568 fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
515 Build16bitCache(cache->fCache16, cache->fShader.fOrigColors[0], 569 if (fColorCount == 2) {
516 cache->fShader.fOrigColors[1], kCache16Count); 570 Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1],
517 } else { 571 kCache32Count, fCacheAlpha, fGradFlags);
518 Rec* rec = cache->fShader.fRecs; 572 } else {
519 int prevIndex = 0; 573 Rec* rec = fRecs;
520 for (int i = 1; i < cache->fShader.fColorCount; i++) { 574 int prevIndex = 0;
521 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache16Shift; 575 for (int i = 1; i < fColorCount; i++) {
522 SkASSERT(nextIndex < kCache16Count); 576 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache32Shift;
577 SkASSERT(nextIndex < kCache32Count);
523 578
524 if (nextIndex > prevIndex) 579 if (nextIndex > prevIndex)
525 Build16bitCache(cache->fCache16 + prevIndex, cache->fShader.fOri gColors[i-1], 580 Build32bitCache(fCache32 + prevIndex, fOrigColors[i-1],
526 cache->fShader.fOrigColors[i], nextIndex - prevI ndex + 1); 581 fOrigColors[i], nextIndex - prevIndex + 1,
527 prevIndex = nextIndex; 582 fCacheAlpha, fGradFlags);
583 prevIndex = nextIndex;
584 }
585 }
586
587 if (fMapper) {
588 SkMallocPixelRef* newPR = SkMallocPixelRef::NewAllocate(info, 0, NUL L);
589 SkPMColor* linear = fCache32; // just computed linear data
590 SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data
591 SkUnitMapper* map = fMapper;
592 for (int i = 0; i < kCache32Count; i++) {
593 int index = map->mapUnit16((i << 8) | i) >> 8;
594 mapped[i + kCache32Count*0] = linear[index + kCache32Count*0];
595 mapped[i + kCache32Count*1] = linear[index + kCache32Count*1];
596 mapped[i + kCache32Count*2] = linear[index + kCache32Count*2];
597 mapped[i + kCache32Count*3] = linear[index + kCache32Count*3];
598 }
599 fCache32PixelRef->unref();
600 fCache32PixelRef = newPR;
601 fCache32 = (SkPMColor*)newPR->getAddr();
528 } 602 }
529 } 603 }
530
531 if (cache->fShader.fMapper) {
532 cache->fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize);
533 uint16_t* linear = cache->fCache16; // just computed linear data
534 uint16_t* mapped = cache->fCache16Storage; // storage for mapped data
535 SkUnitMapper* map = cache->fShader.fMapper;
536 for (int i = 0; i < kCache16Count; i++) {
537 int index = map->mapUnit16(bitsTo16(i, kCache16Bits)) >> kCache16Shi ft;
538 mapped[i] = linear[index];
539 mapped[i + kCache16Count] = linear[index + kCache16Count];
540 }
541 sk_free(cache->fCache16);
542 cache->fCache16 = cache->fCache16Storage;
543 }
544 }
545
546 const SkPMColor* SkGradientShaderBase::GradientShaderCache::getCache32() {
547 SkOnce(&fCache32Inited, &fCache32Mutex, SkGradientShaderBase::GradientShader Cache::initCache32,
548 this);
549 SkASSERT(fCache32);
550 return fCache32; 604 return fCache32;
551 } 605 }
552 606
553 void SkGradientShaderBase::GradientShaderCache::initCache32(GradientShaderCache* cache) {
554 SkImageInfo info;
555 info.fWidth = kCache32Count;
556 info.fHeight = 4; // for our 4 dither rows
557 info.fAlphaType = kPremul_SkAlphaType;
558 info.fColorType = kN32_SkColorType;
559
560 SkASSERT(NULL == cache->fCache32PixelRef);
561 cache->fCache32PixelRef = SkMallocPixelRef::NewAllocate(info, 0, NULL);
562 cache->fCache32 = (SkPMColor*)cache->fCache32PixelRef->getAddr();
563 if (cache->fShader.fColorCount == 2) {
564 Build32bitCache(cache->fCache32, cache->fShader.fOrigColors[0],
565 cache->fShader.fOrigColors[1], kCache32Count, cache->fCa cheAlpha,
566 cache->fShader.fGradFlags);
567 } else {
568 Rec* rec = cache->fShader.fRecs;
569 int prevIndex = 0;
570 for (int i = 1; i < cache->fShader.fColorCount; i++) {
571 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache32Shift;
572 SkASSERT(nextIndex < kCache32Count);
573
574 if (nextIndex > prevIndex)
575 Build32bitCache(cache->fCache32 + prevIndex, cache->fShader.fOri gColors[i-1],
576 cache->fShader.fOrigColors[i], nextIndex - prevI ndex + 1,
577 cache->fCacheAlpha, cache->fShader.fGradFlags);
578 prevIndex = nextIndex;
579 }
580 }
581
582 if (cache->fShader.fMapper) {
583 SkMallocPixelRef* newPR = SkMallocPixelRef::NewAllocate(info, 0, NULL);
584 SkPMColor* linear = cache->fCache32; // just computed linear d ata
585 SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapp ed data
586 SkUnitMapper* map = cache->fShader.fMapper;
587 for (int i = 0; i < kCache32Count; i++) {
588 int index = map->mapUnit16((i << 8) | i) >> 8;
589 mapped[i + kCache32Count*0] = linear[index + kCache32Count*0];
590 mapped[i + kCache32Count*1] = linear[index + kCache32Count*1];
591 mapped[i + kCache32Count*2] = linear[index + kCache32Count*2];
592 mapped[i + kCache32Count*3] = linear[index + kCache32Count*3];
593 }
594 cache->fCache32PixelRef->unref();
595 cache->fCache32PixelRef = newPR;
596 cache->fCache32 = (SkPMColor*)newPR->getAddr();
597 }
598 }
599
600 /* 607 /*
601 * The gradient holds a cache for the most recent value of alpha. Successive
602 * callers with the same alpha value will share the same cache.
603 */
604 SkGradientShaderBase::GradientShaderCache* SkGradientShaderBase::refCache(U8CPU alpha) const {
605 SkAutoMutexAcquire ama(fCacheMutex);
606 if (!fCache || fCache->getAlpha() != alpha) {
607 fCache.reset(SkNEW_ARGS(GradientShaderCache, (alpha, *this)));
608 }
609 // Increment the ref counter inside the mutex to ensure the returned pointer is still valid.
610 // Otherwise, the pointer may have been overwritten on a different thread be fore the object's
611 // ref count was incremented.
612 fCache.get()->ref();
613 return fCache;
614 }
615
616 /*
617 * Because our caller might rebuild the same (logically the same) gradient 608 * Because our caller might rebuild the same (logically the same) gradient
618 * over and over, we'd like to return exactly the same "bitmap" if possible, 609 * over and over, we'd like to return exactly the same "bitmap" if possible,
619 * allowing the client to utilize a cache of our bitmap (e.g. with a GPU). 610 * allowing the client to utilize a cache of our bitmap (e.g. with a GPU).
620 * To do that, we maintain a private cache of built-bitmaps, based on our 611 * To do that, we maintain a private cache of built-bitmaps, based on our
621 * colors and positions. Note: we don't try to flatten the fMapper, so if one 612 * colors and positions. Note: we don't try to flatten the fMapper, so if one
622 * is present, we skip the cache for now. 613 * is present, we skip the cache for now.
623 */ 614 */
624 void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const { 615 void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const {
625 // our caller assumes no external alpha, so we ensure that our cache is 616 // our caller assumes no external alpha, so we ensure that our cache is
626 // built with 0xFF 617 // built with 0xFF
627 SkAutoTUnref<GradientShaderCache> cache(this->refCache(0xFF)); 618 this->setCacheAlpha(0xFF);
628 619
629 // don't have a way to put the mapper into our cache-key yet 620 // don't have a way to put the mapper into our cache-key yet
630 if (fMapper) { 621 if (fMapper) {
631 // force our cache32pixelref to be built 622 // force our cahce32pixelref to be built
632 (void)cache->getCache32(); 623 (void)this->getCache32();
633 bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1)); 624 bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1));
634 bitmap->setPixelRef(cache->getCache32PixelRef()); 625 bitmap->setPixelRef(fCache32PixelRef);
635 return; 626 return;
636 } 627 }
637 628
638 // build our key: [numColors + colors[] + {positions[]} + flags ] 629 // build our key: [numColors + colors[] + {positions[]} + flags ]
639 int count = 1 + fColorCount + 1; 630 int count = 1 + fColorCount + 1;
640 if (fColorCount > 2) { 631 if (fColorCount > 2) {
641 count += fColorCount - 1; // fRecs[].fPos 632 count += fColorCount - 1; // fRecs[].fPos
642 } 633 }
643 634
644 SkAutoSTMalloc<16, int32_t> storage(count); 635 SkAutoSTMalloc<16, int32_t> storage(count);
(...skipping 18 matching lines...) Expand all
663 static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32; 654 static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32;
664 SkAutoMutexAcquire ama(gMutex); 655 SkAutoMutexAcquire ama(gMutex);
665 656
666 if (NULL == gCache) { 657 if (NULL == gCache) {
667 gCache = SkNEW_ARGS(SkBitmapCache, (MAX_NUM_CACHED_GRADIENT_BITMAPS)); 658 gCache = SkNEW_ARGS(SkBitmapCache, (MAX_NUM_CACHED_GRADIENT_BITMAPS));
668 } 659 }
669 size_t size = count * sizeof(int32_t); 660 size_t size = count * sizeof(int32_t);
670 661
671 if (!gCache->find(storage.get(), size, bitmap)) { 662 if (!gCache->find(storage.get(), size, bitmap)) {
672 // force our cahce32pixelref to be built 663 // force our cahce32pixelref to be built
673 (void)cache->getCache32(); 664 (void)this->getCache32();
674 bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1)); 665 bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1));
675 bitmap->setPixelRef(cache->getCache32PixelRef()); 666 bitmap->setPixelRef(fCache32PixelRef);
676 667
677 gCache->add(storage.get(), size, *bitmap); 668 gCache->add(storage.get(), size, *bitmap);
678 } 669 }
679 } 670 }
680 671
681 void SkGradientShaderBase::commonAsAGradient(GradientInfo* info, bool flipGrad) const { 672 void SkGradientShaderBase::commonAsAGradient(GradientInfo* info, bool flipGrad) const {
682 if (info) { 673 if (info) {
683 if (info->fColorCount >= fColorCount) { 674 if (info->fColorCount >= fColorCount) {
684 SkColor* colorLoc; 675 SkColor* colorLoc;
685 Rec* recLoc; 676 Rec* recLoc;
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
1204 (*stops)[i] = stop; 1195 (*stops)[i] = stop;
1205 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; 1196 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f;
1206 } 1197 }
1207 } 1198 }
1208 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); 1199 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount));
1209 1200
1210 return outColors; 1201 return outColors;
1211 } 1202 }
1212 1203
1213 #endif 1204 #endif
OLDNEW
« no previous file with comments | « src/effects/SkTransparentShader.cpp ('k') | src/effects/gradients/SkGradientShaderPriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698