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

Side by Side Diff: src/effects/gradients/SkGradientShader.cpp

Issue 207683004: 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: rebase & cleanup 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
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
20 fMapper = desc.fMapper; 18 fMapper = desc.fMapper;
21 SkSafeRef(fMapper); 19 SkSafeRef(fMapper);
22 fGradFlags = SkToU8(desc.fFlags); 20 fGradFlags = SkToU8(desc.fFlags);
23 21
24 SkASSERT((unsigned)desc.fTileMode < SkShader::kTileModeCount); 22 SkASSERT((unsigned)desc.fTileMode < SkShader::kTileModeCount);
25 SkASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gTileProcs)); 23 SkASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gTileProcs));
26 fTileMode = desc.fTileMode; 24 fTileMode = desc.fTileMode;
27 fTileProc = gTileProcs[desc.fTileMode]; 25 fTileProc = gTileProcs[desc.fTileMode];
28 26
29 fCache16 = fCache16Storage = NULL;
30 fCache32 = NULL;
31 fCache32PixelRef = NULL;
32
33 /* Note: we let the caller skip the first and/or last position. 27 /* Note: we let the caller skip the first and/or last position.
34 i.e. pos[0] = 0.3, pos[1] = 0.7 28 i.e. pos[0] = 0.3, pos[1] = 0.7
35 In these cases, we insert dummy entries to ensure that the final data 29 In these cases, we insert dummy entries to ensure that the final data
36 will be bracketed by [0, 1]. 30 will be bracketed by [0, 1].
37 i.e. our_pos[0] = 0, our_pos[1] = 0.3, our_pos[2] = 0.7, our_pos[3] = 1 31 i.e. our_pos[0] = 0, our_pos[1] = 0.3, our_pos[2] = 0.7, our_pos[3] = 1
38 32
39 Thus colorCount (the caller's value, and fColorCount (our value) may 33 Thus colorCount (the caller's value, and fColorCount (our value) may
40 differ by up to 2. In the above example: 34 differ by up to 2. In the above example:
41 colorCount = 2 35 colorCount = 2
42 fColorCount = 4 36 fColorCount = 4
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 131
138 static SkShader::TileMode unpack_mode(uint32_t packed) { 132 static SkShader::TileMode unpack_mode(uint32_t packed) {
139 return (SkShader::TileMode)(packed & 0xF); 133 return (SkShader::TileMode)(packed & 0xF);
140 } 134 }
141 135
142 static uint32_t unpack_flags(uint32_t packed) { 136 static uint32_t unpack_flags(uint32_t packed) {
143 return packed >> 4; 137 return packed >> 4;
144 } 138 }
145 139
146 SkGradientShaderBase::SkGradientShaderBase(SkReadBuffer& buffer) : INHERITED(buf fer) { 140 SkGradientShaderBase::SkGradientShaderBase(SkReadBuffer& buffer) : INHERITED(buf fer) {
147 fCacheAlpha = 256;
148
149 fMapper = buffer.readUnitMapper(); 141 fMapper = buffer.readUnitMapper();
150 142
151 fCache16 = fCache16Storage = NULL;
152 fCache32 = NULL;
153 fCache32PixelRef = NULL;
154
155 int colorCount = fColorCount = buffer.getArrayCount(); 143 int colorCount = fColorCount = buffer.getArrayCount();
156 if (colorCount > kColorStorageCount) { 144 if (colorCount > kColorStorageCount) {
157 size_t allocSize = (sizeof(SkColor) + sizeof(SkPMColor) + sizeof(Rec)) * colorCount; 145 size_t allocSize = (sizeof(SkColor) + sizeof(SkPMColor) + sizeof(Rec)) * colorCount;
158 if (buffer.validateAvailable(allocSize)) { 146 if (buffer.validateAvailable(allocSize)) {
159 fOrigColors = reinterpret_cast<SkColor*>(sk_malloc_throw(allocSize)) ; 147 fOrigColors = reinterpret_cast<SkColor*>(sk_malloc_throw(allocSize)) ;
160 } else { 148 } else {
161 fOrigColors = NULL; 149 fOrigColors = NULL;
162 colorCount = fColorCount = 0; 150 colorCount = fColorCount = 0;
163 } 151 }
164 } else { 152 } else {
(...skipping 14 matching lines...) Expand all
179 for (int i = 1; i < colorCount; i++) { 167 for (int i = 1; i < colorCount; i++) {
180 recs[i].fPos = buffer.readInt(); 168 recs[i].fPos = buffer.readInt();
181 recs[i].fScale = buffer.readUInt(); 169 recs[i].fScale = buffer.readUInt();
182 } 170 }
183 } 171 }
184 buffer.readMatrix(&fPtsToUnit); 172 buffer.readMatrix(&fPtsToUnit);
185 this->initCommon(); 173 this->initCommon();
186 } 174 }
187 175
188 SkGradientShaderBase::~SkGradientShaderBase() { 176 SkGradientShaderBase::~SkGradientShaderBase() {
189 if (fCache16Storage) {
190 sk_free(fCache16Storage);
191 }
192 SkSafeUnref(fCache32PixelRef);
193 if (fOrigColors != fStorage) { 177 if (fOrigColors != fStorage) {
194 sk_free(fOrigColors); 178 sk_free(fOrigColors);
195 } 179 }
196 SkSafeUnref(fMapper); 180 SkSafeUnref(fMapper);
197 } 181 }
198 182
199 void SkGradientShaderBase::initCommon() { 183 void SkGradientShaderBase::initCommon() {
200 fFlags = 0;
201 unsigned colorAlpha = 0xFF; 184 unsigned colorAlpha = 0xFF;
202 for (int i = 0; i < fColorCount; i++) { 185 for (int i = 0; i < fColorCount; i++) {
203 colorAlpha &= SkColorGetA(fOrigColors[i]); 186 colorAlpha &= SkColorGetA(fOrigColors[i]);
204 } 187 }
205 fColorsAreOpaque = colorAlpha == 0xFF; 188 fColorsAreOpaque = colorAlpha == 0xFF;
206 } 189 }
207 190
208 void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const { 191 void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const {
209 this->INHERITED::flatten(buffer); 192 this->INHERITED::flatten(buffer);
210 buffer.writeFlattenable(fMapper); 193 buffer.writeFlattenable(fMapper);
211 buffer.writeColorArray(fOrigColors, fColorCount); 194 buffer.writeColorArray(fOrigColors, fColorCount);
212 buffer.writeUInt(pack_mode_flags(fTileMode, fGradFlags)); 195 buffer.writeUInt(pack_mode_flags(fTileMode, fGradFlags));
213 if (fColorCount > 2) { 196 if (fColorCount > 2) {
214 Rec* recs = fRecs; 197 Rec* recs = fRecs;
215 for (int i = 1; i < fColorCount; i++) { 198 for (int i = 1; i < fColorCount; i++) {
216 buffer.writeInt(recs[i].fPos); 199 buffer.writeInt(recs[i].fPos);
217 buffer.writeUInt(recs[i].fScale); 200 buffer.writeUInt(recs[i].fScale);
218 } 201 }
219 } 202 }
220 buffer.writeMatrix(fPtsToUnit); 203 buffer.writeMatrix(fPtsToUnit);
221 } 204 }
222 205
223 bool SkGradientShaderBase::isOpaque() const { 206 bool SkGradientShaderBase::isOpaque() const {
224 return fColorsAreOpaque; 207 return fColorsAreOpaque;
225 } 208 }
226 209
227 bool SkGradientShaderBase::setContext(const SkBitmap& device, 210 SkGradientShaderBase::GradientShaderBaseContext::GradientShaderBaseContext(
228 const SkPaint& paint, 211 const SkGradientShaderBase& shader, const SkBitmap& device,
229 const SkMatrix& matrix) { 212 const SkPaint& paint, const SkMatrix& matrix)
230 if (!this->INHERITED::setContext(device, paint, matrix)) { 213 : INHERITED(shader, device, paint, matrix)
231 return false; 214 , fCache(this->getPaintAlpha())
232 } 215 {
233
234 const SkMatrix& inverse = this->getTotalInverse(); 216 const SkMatrix& inverse = this->getTotalInverse();
235 217
236 fDstToIndex.setConcat(fPtsToUnit, inverse); 218 fDstToIndex.setConcat(shader.fPtsToUnit, inverse);
219
237 fDstToIndexProc = fDstToIndex.getMapXYProc(); 220 fDstToIndexProc = fDstToIndex.getMapXYProc();
238 fDstToIndexClass = (uint8_t)SkShader::ComputeMatrixClass(fDstToIndex); 221 fDstToIndexClass = (uint8_t)SkShader::Context::ComputeMatrixClass(fDstToInde x);
239 222
240 // now convert our colors in to PMColors 223 // now convert our colors in to PMColors
241 unsigned paintAlpha = this->getPaintAlpha(); 224 unsigned paintAlpha = this->getPaintAlpha();
242 225
243 fFlags = this->INHERITED::getFlags(); 226 fFlags = this->INHERITED::getFlags();
244 if (fColorsAreOpaque && paintAlpha == 0xFF) { 227 if (shader.fColorsAreOpaque && paintAlpha == 0xFF) {
245 fFlags |= kOpaqueAlpha_Flag; 228 fFlags |= kOpaqueAlpha_Flag;
246 } 229 }
247 // we can do span16 as long as our individual colors are opaque, 230 // we can do span16 as long as our individual colors are opaque,
248 // regardless of the paint's alpha 231 // regardless of the paint's alpha
249 if (fColorsAreOpaque) { 232 if (shader.fColorsAreOpaque) {
250 fFlags |= kHasSpan16_Flag; 233 fFlags |= kHasSpan16_Flag;
251 } 234 }
252
253 this->setCacheAlpha(paintAlpha);
254 return true;
255 }
256
257 void SkGradientShaderBase::setCacheAlpha(U8CPU alpha) const {
258 // if the new alpha differs from the previous time we were called, inval our cache
259 // this will trigger the cache to be rebuilt.
260 // we don't care about the first time, since the cache ptrs will already be NULL
261 if (fCacheAlpha != alpha) {
262 fCache16 = NULL; // inval the cache
263 fCache32 = NULL; // inval the cache
264 fCacheAlpha = alpha; // record the new alpha
265 // inform our subclasses
266 if (fCache32PixelRef) {
267 fCache32PixelRef->notifyPixelsChanged();
268 }
269 }
270 } 235 }
271 236
237 SkGradientShaderBase::GradientShaderCache::GradientShaderCache(U8CPU alpha) {
238 // Only initialize the cache in getCache16/32.
239 fCache16 = NULL;
240 fCache32 = NULL;
241 fCache16Storage = NULL;
242 fCache32PixelRef = NULL;
243 fCacheAlpha = alpha;
244 }
245
246 SkGradientShaderBase::GradientShaderCache::~GradientShaderCache() {
247 sk_free(fCache16Storage);
248 SkSafeUnref(fCache32PixelRef);
249 }
250
272 #define Fixed_To_Dot8(x) (((x) + 0x80) >> 8) 251 #define Fixed_To_Dot8(x) (((x) + 0x80) >> 8)
273 252
274 /** We take the original colors, not our premultiplied PMColors, since we can 253 /** We take the original colors, not our premultiplied PMColors, since we can
275 build a 16bit table as long as the original colors are opaque, even if the 254 build a 16bit table as long as the original colors are opaque, even if the
276 paint specifies a non-opaque alpha. 255 paint specifies a non-opaque alpha.
277 */ 256 */
278 void SkGradientShaderBase::Build16bitCache(uint16_t cache[], SkColor c0, SkColor c1, 257 void SkGradientShaderBase::GradientShaderCache::Build16bitCache(
279 int count) { 258 uint16_t cache[], SkColor c0, SkColor c1, int count) {
280 SkASSERT(count > 1); 259 SkASSERT(count > 1);
281 SkASSERT(SkColorGetA(c0) == 0xFF); 260 SkASSERT(SkColorGetA(c0) == 0xFF);
282 SkASSERT(SkColorGetA(c1) == 0xFF); 261 SkASSERT(SkColorGetA(c1) == 0xFF);
283 262
284 SkFixed r = SkColorGetR(c0); 263 SkFixed r = SkColorGetR(c0);
285 SkFixed g = SkColorGetG(c0); 264 SkFixed g = SkColorGetG(c0);
286 SkFixed b = SkColorGetB(c0); 265 SkFixed b = SkColorGetB(c0);
287 266
288 SkFixed dr = SkIntToFixed(SkColorGetR(c1) - r) / (count - 1); 267 SkFixed dr = SkIntToFixed(SkColorGetR(c1) - r) / (count - 1);
289 SkFixed dg = SkIntToFixed(SkColorGetG(c1) - g) / (count - 1); 268 SkFixed dg = SkIntToFixed(SkColorGetG(c1) - g) / (count - 1);
(...skipping 27 matching lines...) Expand all
317 * 2. change SkPackARGB32 to + its (a << SK_A32_SHIFT) value instead 296 * 2. change SkPackARGB32 to + its (a << SK_A32_SHIFT) value instead
318 * of using | 297 * of using |
319 * 298 *
320 * We chose #1 just because it was more localized. 299 * We chose #1 just because it was more localized.
321 * See http://code.google.com/p/skia/issues/detail?id=1113 300 * See http://code.google.com/p/skia/issues/detail?id=1113
322 * 301 *
323 * The type SkUFixed encapsulate this need for unsigned, but logically Fixed. 302 * The type SkUFixed encapsulate this need for unsigned, but logically Fixed.
324 */ 303 */
325 typedef uint32_t SkUFixed; 304 typedef uint32_t SkUFixed;
326 305
327 void SkGradientShaderBase::Build32bitCache(SkPMColor cache[], SkColor c0, SkColo r c1, 306 void SkGradientShaderBase::GradientShaderCache::Build32bitCache(
328 int count, U8CPU paintAlpha, uint32_t grad Flags) { 307 SkPMColor cache[], SkColor c0, SkColor c1,
308 int count, U8CPU paintAlpha, uint32_t gradFlags) {
329 SkASSERT(count > 1); 309 SkASSERT(count > 1);
330 310
331 // need to apply paintAlpha to our two endpoints 311 // need to apply paintAlpha to our two endpoints
332 uint32_t a0 = SkMulDiv255Round(SkColorGetA(c0), paintAlpha); 312 uint32_t a0 = SkMulDiv255Round(SkColorGetA(c0), paintAlpha);
333 uint32_t a1 = SkMulDiv255Round(SkColorGetA(c1), paintAlpha); 313 uint32_t a1 = SkMulDiv255Round(SkColorGetA(c1), paintAlpha);
334 314
335 315
336 const bool interpInPremul = SkToBool(gradFlags & 316 const bool interpInPremul = SkToBool(gradFlags &
337 SkGradientShader::kInterpolateColorsInPremul_Flag); 317 SkGradientShader::kInterpolateColorsInPremul_Flag);
338 318
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 if (6 == bits) { 441 if (6 == bits) {
462 return (x << 10) | (x << 4) | (x >> 2); 442 return (x << 10) | (x << 4) | (x >> 2);
463 } 443 }
464 if (8 == bits) { 444 if (8 == bits) {
465 return (x << 8) | x; 445 return (x << 8) | x;
466 } 446 }
467 sk_throw(); 447 sk_throw();
468 return 0; 448 return 0;
469 } 449 }
470 450
471 const uint16_t* SkGradientShaderBase::getCache16() const { 451 const uint16_t* SkGradientShaderBase::GradientShaderCache::getCache16(
452 const SkGradientShaderBase& shader) {
472 if (fCache16 == NULL) { 453 if (fCache16 == NULL) {
473 // double the count for dither entries 454 // double the count for dither entries
474 const int entryCount = kCache16Count * 2; 455 const int entryCount = kCache16Count * 2;
475 const size_t allocSize = sizeof(uint16_t) * entryCount; 456 const size_t allocSize = sizeof(uint16_t) * entryCount;
476 457
477 if (fCache16Storage == NULL) { // set the storage and our working ptr 458 if (fCache16Storage == NULL) { // set the storage and our working ptr
478 fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize); 459 fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize);
479 } 460 }
480 fCache16 = fCache16Storage; 461 fCache16 = fCache16Storage;
481 if (fColorCount == 2) { 462 if (shader.fColorCount == 2) {
482 Build16bitCache(fCache16, fOrigColors[0], fOrigColors[1], 463 Build16bitCache(fCache16, shader.fOrigColors[0], shader.fOrigColors[ 1],
483 kCache16Count); 464 kCache16Count);
484 } else { 465 } else {
485 Rec* rec = fRecs; 466 Rec* rec = shader.fRecs;
486 int prevIndex = 0; 467 int prevIndex = 0;
487 for (int i = 1; i < fColorCount; i++) { 468 for (int i = 1; i < shader.fColorCount; i++) {
488 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache16Shift; 469 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache16Shift;
489 SkASSERT(nextIndex < kCache16Count); 470 SkASSERT(nextIndex < kCache16Count);
490 471
491 if (nextIndex > prevIndex) 472 if (nextIndex > prevIndex)
492 Build16bitCache(fCache16 + prevIndex, fOrigColors[i-1], fOri gColors[i], nextIndex - prevIndex + 1); 473 Build16bitCache(fCache16 + prevIndex, shader.fOrigColors[i-1 ],
474 shader.fOrigColors[i], nextIndex - prevIndex + 1);
493 prevIndex = nextIndex; 475 prevIndex = nextIndex;
494 } 476 }
495 } 477 }
496 478
497 if (fMapper) { 479 if (shader.fMapper) {
498 fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize); 480 fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize);
499 uint16_t* linear = fCache16; // just computed linear data 481 uint16_t* linear = fCache16; // just computed linear data
500 uint16_t* mapped = fCache16Storage; // storage for mapped data 482 uint16_t* mapped = fCache16Storage; // storage for mapped data
501 SkUnitMapper* map = fMapper; 483 SkUnitMapper* map = shader.fMapper;
502 for (int i = 0; i < kCache16Count; i++) { 484 for (int i = 0; i < kCache16Count; i++) {
503 int index = map->mapUnit16(bitsTo16(i, kCache16Bits)) >> kCache1 6Shift; 485 int index = map->mapUnit16(bitsTo16(i, kCache16Bits)) >> kCache1 6Shift;
504 mapped[i] = linear[index]; 486 mapped[i] = linear[index];
505 mapped[i + kCache16Count] = linear[index + kCache16Count]; 487 mapped[i + kCache16Count] = linear[index + kCache16Count];
506 } 488 }
507 sk_free(fCache16); 489 sk_free(fCache16);
508 fCache16 = fCache16Storage; 490 fCache16 = fCache16Storage;
509 } 491 }
510 } 492 }
511 return fCache16; 493 return fCache16;
512 } 494 }
513 495
514 const SkPMColor* SkGradientShaderBase::getCache32() const { 496 const SkPMColor* SkGradientShaderBase::GradientShaderCache::getCache32(
497 const SkGradientShaderBase& shader) {
515 if (fCache32 == NULL) { 498 if (fCache32 == NULL) {
516 SkImageInfo info; 499 SkImageInfo info;
517 info.fWidth = kCache32Count; 500 info.fWidth = kCache32Count;
518 info.fHeight = 4; // for our 4 dither rows 501 info.fHeight = 4; // for our 4 dither rows
519 info.fAlphaType = kPremul_SkAlphaType; 502 info.fAlphaType = kPremul_SkAlphaType;
520 info.fColorType = kPMColor_SkColorType; 503 info.fColorType = kPMColor_SkColorType;
521 504
522 if (NULL == fCache32PixelRef) { 505 if (NULL == fCache32PixelRef) {
523 fCache32PixelRef = SkMallocPixelRef::NewAllocate(info, 0, NULL); 506 fCache32PixelRef = SkMallocPixelRef::NewAllocate(info, 0, NULL);
524 } 507 }
525 fCache32 = (SkPMColor*)fCache32PixelRef->getAddr(); 508 fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
526 if (fColorCount == 2) { 509 if (shader.fColorCount == 2) {
527 Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1], 510 Build32bitCache(fCache32, shader.fOrigColors[0], shader.fOrigColors[ 1],
528 kCache32Count, fCacheAlpha, fGradFlags); 511 kCache32Count, fCacheAlpha, shader.fGradFlags);
529 } else { 512 } else {
530 Rec* rec = fRecs; 513 Rec* rec = shader.fRecs;
531 int prevIndex = 0; 514 int prevIndex = 0;
532 for (int i = 1; i < fColorCount; i++) { 515 for (int i = 1; i < shader.fColorCount; i++) {
533 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache32Shift; 516 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache32Shift;
534 SkASSERT(nextIndex < kCache32Count); 517 SkASSERT(nextIndex < kCache32Count);
535 518
536 if (nextIndex > prevIndex) 519 if (nextIndex > prevIndex)
537 Build32bitCache(fCache32 + prevIndex, fOrigColors[i-1], 520 Build32bitCache(fCache32 + prevIndex, shader.fOrigColors[i-1 ],
538 fOrigColors[i], nextIndex - prevIndex + 1, 521 shader.fOrigColors[i], nextIndex - prevIndex + 1,
539 fCacheAlpha, fGradFlags); 522 fCacheAlpha, shader.fGradFlags);
540 prevIndex = nextIndex; 523 prevIndex = nextIndex;
541 } 524 }
542 } 525 }
543 526
544 if (fMapper) { 527 if (shader.fMapper) {
545 SkMallocPixelRef* newPR = SkMallocPixelRef::NewAllocate(info, 0, NUL L); 528 SkMallocPixelRef* newPR = SkMallocPixelRef::NewAllocate(info, 0, NUL L);
546 SkPMColor* linear = fCache32; // just computed linear data 529 SkPMColor* linear = fCache32; // just computed linear data
547 SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data 530 SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data
548 SkUnitMapper* map = fMapper; 531 SkUnitMapper* map = shader.fMapper;
549 for (int i = 0; i < kCache32Count; i++) { 532 for (int i = 0; i < kCache32Count; i++) {
550 int index = map->mapUnit16((i << 8) | i) >> 8; 533 int index = map->mapUnit16((i << 8) | i) >> 8;
551 mapped[i + kCache32Count*0] = linear[index + kCache32Count*0]; 534 mapped[i + kCache32Count*0] = linear[index + kCache32Count*0];
552 mapped[i + kCache32Count*1] = linear[index + kCache32Count*1]; 535 mapped[i + kCache32Count*1] = linear[index + kCache32Count*1];
553 mapped[i + kCache32Count*2] = linear[index + kCache32Count*2]; 536 mapped[i + kCache32Count*2] = linear[index + kCache32Count*2];
554 mapped[i + kCache32Count*3] = linear[index + kCache32Count*3]; 537 mapped[i + kCache32Count*3] = linear[index + kCache32Count*3];
555 } 538 }
556 fCache32PixelRef->unref(); 539 fCache32PixelRef->unref();
557 fCache32PixelRef = newPR; 540 fCache32PixelRef = newPR;
558 fCache32 = (SkPMColor*)newPR->getAddr(); 541 fCache32 = (SkPMColor*)newPR->getAddr();
559 } 542 }
560 } 543 }
561 return fCache32; 544 return fCache32;
562 } 545 }
563 546
564 /* 547 /*
565 * Because our caller might rebuild the same (logically the same) gradient 548 * Because our caller might rebuild the same (logically the same) gradient
566 * over and over, we'd like to return exactly the same "bitmap" if possible, 549 * over and over, we'd like to return exactly the same "bitmap" if possible,
scroggo 2014/04/03 15:35:54 Now that the cache is not on the SkGradientShader,
Dominik Grewe 2014/04/04 10:59:41 I think the comment is referring to the SkBitmapCa
567 * allowing the client to utilize a cache of our bitmap (e.g. with a GPU). 550 * allowing the client to utilize a cache of our bitmap (e.g. with a GPU).
568 * To do that, we maintain a private cache of built-bitmaps, based on our 551 * To do that, we maintain a private cache of built-bitmaps, based on our
569 * colors and positions. Note: we don't try to flatten the fMapper, so if one 552 * colors and positions. Note: we don't try to flatten the fMapper, so if one
570 * is present, we skip the cache for now. 553 * is present, we skip the cache for now.
571 */ 554 */
572 void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const { 555 void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const {
573 // our caller assumes no external alpha, so we ensure that our cache is 556 // our caller assumes no external alpha, so we ensure that our cache is
574 // built with 0xFF 557 // built with 0xFF
575 this->setCacheAlpha(0xFF); 558 GradientShaderCache cache(0xFF);
576 559
577 // don't have a way to put the mapper into our cache-key yet 560 // don't have a way to put the mapper into our cache-key yet
578 if (fMapper) { 561 if (fMapper) {
579 // force our cahce32pixelref to be built 562 // force our cahce32pixelref to be built
580 (void)this->getCache32(); 563 (void)cache.getCache32(*this);
581 bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1)); 564 bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1));
582 bitmap->setPixelRef(fCache32PixelRef); 565 bitmap->setPixelRef(cache.getCache32PixelRef());
583 return; 566 return;
584 } 567 }
585 568
586 // build our key: [numColors + colors[] + {positions[]} + flags ] 569 // build our key: [numColors + colors[] + {positions[]} + flags ]
587 int count = 1 + fColorCount + 1; 570 int count = 1 + fColorCount + 1;
588 if (fColorCount > 2) { 571 if (fColorCount > 2) {
589 count += fColorCount - 1; // fRecs[].fPos 572 count += fColorCount - 1; // fRecs[].fPos
590 } 573 }
591 574
592 SkAutoSTMalloc<16, int32_t> storage(count); 575 SkAutoSTMalloc<16, int32_t> storage(count);
(...skipping 18 matching lines...) Expand all
611 static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32; 594 static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32;
612 SkAutoMutexAcquire ama(gMutex); 595 SkAutoMutexAcquire ama(gMutex);
613 596
614 if (NULL == gCache) { 597 if (NULL == gCache) {
615 gCache = SkNEW_ARGS(SkBitmapCache, (MAX_NUM_CACHED_GRADIENT_BITMAPS)); 598 gCache = SkNEW_ARGS(SkBitmapCache, (MAX_NUM_CACHED_GRADIENT_BITMAPS));
616 } 599 }
617 size_t size = count * sizeof(int32_t); 600 size_t size = count * sizeof(int32_t);
618 601
619 if (!gCache->find(storage.get(), size, bitmap)) { 602 if (!gCache->find(storage.get(), size, bitmap)) {
620 // force our cahce32pixelref to be built 603 // force our cahce32pixelref to be built
621 (void)this->getCache32(); 604 (void)cache.getCache32(*this);
622 bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1)); 605 bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1));
623 bitmap->setPixelRef(fCache32PixelRef); 606 bitmap->setPixelRef(cache.getCache32PixelRef());
624 607
625 gCache->add(storage.get(), size, *bitmap); 608 gCache->add(storage.get(), size, *bitmap);
626 } 609 }
627 } 610 }
628 611
629 void SkGradientShaderBase::commonAsAGradient(GradientInfo* info) const { 612 void SkGradientShaderBase::commonAsAGradient(GradientInfo* info) const {
630 if (info) { 613 if (info) {
631 if (info->fColorCount >= fColorCount) { 614 if (info->fColorCount >= fColorCount) {
632 if (info->fColors) { 615 if (info->fColors) {
633 memcpy(info->fColors, fOrigColors, fColorCount * sizeof(SkColor) ); 616 memcpy(info->fColors, fOrigColors, fColorCount * sizeof(SkColor) );
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 (*stops)[i] = stop; 1116 (*stops)[i] = stop;
1134 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; 1117 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f;
1135 } 1118 }
1136 } 1119 }
1137 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); 1120 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount));
1138 1121
1139 return outColors; 1122 return outColors;
1140 } 1123 }
1141 1124
1142 #endif 1125 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698