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

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: SkGradientShader 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
210 bool SkGradientShaderBase::validContext(const SkBitmap& device, const SkPaint& p aint,
211 const SkMatrix& matrix, SkMatrix* totalI nverse) const {
212 // Make sure we can use totalInverse as a cache.
213 SkMatrix totalInverseLocal;
214 if (NULL == totalInverse) {
215 totalInverse = &totalInverseLocal;
216 }
217
218 if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
219 return false;
220 }
221
222 SkMatrix dstToIndex;
223 return dstToIndex.setConcat(fPtsToUnit, *totalInverse);
224 }
225
226 size_t SkGradientShaderBase::contextSize() const {
scroggo 2014/04/02 20:16:53 Is it possible to create an SkGradientShaderBase?
Dominik Grewe 2014/04/03 12:12:59 No. Removed.
227 return sizeof(GradientShaderBaseContext);
228 }
229
230 SkGradientShaderBase::GradientShaderBaseContext::GradientShaderBaseContext(
231 const SkGradientShaderBase& shader, const SkBitmap& device,
232 const SkPaint& paint, const SkMatrix& matrix)
233 : INHERITED(shader, device, paint, matrix), fCache(this->getPaintAlpha())
scroggo 2014/04/02 20:16:53 nit: fCache should go on its own line.
Dominik Grewe 2014/04/03 12:12:59 Done.
234 {
235 const SkMatrix& inverse = this->getTotalInverse();
236
237 SkAssertResult(fDstToIndex.setConcat(shader.fPtsToUnit, inverse));
scroggo 2014/04/02 20:16:53 I don't think you can assert this result unless yo
Dominik Grewe 2014/04/03 12:12:59 The constructor of SkShader::Context asserts that
238
239 fDstToIndexProc = fDstToIndex.getMapXYProc();
240 fDstToIndexClass = (uint8_t)SkShader::Context::ComputeMatrixClass(fDstToInde x);
241
242 // now convert our colors in to PMColors
243 unsigned paintAlpha = this->getPaintAlpha();
244
245 fFlags = this->INHERITED::getFlags();
246 if (shader.fColorsAreOpaque && paintAlpha == 0xFF) {
247 fFlags |= kOpaqueAlpha_Flag;
248 }
249 // we can do span16 as long as our individual colors are opaque,
250 // regardless of the paint's alpha
251 if (shader.fColorsAreOpaque) {
252 fFlags |= kHasSpan16_Flag;
253 }
254 }
255
256 #if 0
227 bool SkGradientShaderBase::setContext(const SkBitmap& device, 257 bool SkGradientShaderBase::setContext(const SkBitmap& device,
228 const SkPaint& paint, 258 const SkPaint& paint,
229 const SkMatrix& matrix) { 259 const SkMatrix& matrix) {
230 if (!this->INHERITED::setContext(device, paint, matrix)) { 260 if (!this->INHERITED::setContext(device, paint, matrix)) {
231 return false; 261 return false;
232 } 262 }
233 263
234 const SkMatrix& inverse = this->getTotalInverse(); 264 const SkMatrix& inverse = this->getTotalInverse();
235 265
236 if (!fDstToIndex.setConcat(fPtsToUnit, inverse)) { 266 if (!fDstToIndex.setConcat(fPtsToUnit, inverse)) {
(...skipping 14 matching lines...) Expand all
251 } 281 }
252 // we can do span16 as long as our individual colors are opaque, 282 // we can do span16 as long as our individual colors are opaque,
253 // regardless of the paint's alpha 283 // regardless of the paint's alpha
254 if (fColorsAreOpaque) { 284 if (fColorsAreOpaque) {
255 fFlags |= kHasSpan16_Flag; 285 fFlags |= kHasSpan16_Flag;
256 } 286 }
257 287
258 this->setCacheAlpha(paintAlpha); 288 this->setCacheAlpha(paintAlpha);
259 return true; 289 return true;
260 } 290 }
291 #endif
261 292
262 void SkGradientShaderBase::setCacheAlpha(U8CPU alpha) const { 293
263 // if the new alpha differs from the previous time we were called, inval our cache 294 SkGradientShaderBase::GradientShaderCache::GradientShaderCache(U8CPU alpha) {
264 // this will trigger the cache to be rebuilt. 295 // Invalidate the cache.
scroggo 2014/04/02 20:16:53 I don't think this comment is appropriate, given t
Dominik Grewe 2014/04/03 12:12:59 Maybe "invalidate" is the wrong term, but I wanted
265 // we don't care about the first time, since the cache ptrs will already be NULL 296 fCache16 = NULL;
266 if (fCacheAlpha != alpha) { 297 fCache32 = NULL;
267 fCache16 = NULL; // inval the cache 298 fCache16Storage = NULL;
268 fCache32 = NULL; // inval the cache 299 fCache32PixelRef = NULL;
269 fCacheAlpha = alpha; // record the new alpha 300 fCacheAlpha = alpha;
270 // inform our subclasses 301 }
271 if (fCache32PixelRef) { 302
272 fCache32PixelRef->notifyPixelsChanged(); 303 SkGradientShaderBase::GradientShaderCache::~GradientShaderCache() {
273 } 304 sk_free(fCache16Storage);
274 } 305 SkSafeUnref(fCache32PixelRef);
275 } 306 }
276 307
277 #define Fixed_To_Dot8(x) (((x) + 0x80) >> 8) 308 #define Fixed_To_Dot8(x) (((x) + 0x80) >> 8)
278 309
279 /** We take the original colors, not our premultiplied PMColors, since we can 310 /** We take the original colors, not our premultiplied PMColors, since we can
280 build a 16bit table as long as the original colors are opaque, even if the 311 build a 16bit table as long as the original colors are opaque, even if the
281 paint specifies a non-opaque alpha. 312 paint specifies a non-opaque alpha.
282 */ 313 */
283 void SkGradientShaderBase::Build16bitCache(uint16_t cache[], SkColor c0, SkColor c1, 314 void SkGradientShaderBase::GradientShaderCache::Build16bitCache(
284 int count) { 315 uint16_t cache[], SkColor c0, SkColor c1, int count) {
285 SkASSERT(count > 1); 316 SkASSERT(count > 1);
286 SkASSERT(SkColorGetA(c0) == 0xFF); 317 SkASSERT(SkColorGetA(c0) == 0xFF);
287 SkASSERT(SkColorGetA(c1) == 0xFF); 318 SkASSERT(SkColorGetA(c1) == 0xFF);
288 319
289 SkFixed r = SkColorGetR(c0); 320 SkFixed r = SkColorGetR(c0);
290 SkFixed g = SkColorGetG(c0); 321 SkFixed g = SkColorGetG(c0);
291 SkFixed b = SkColorGetB(c0); 322 SkFixed b = SkColorGetB(c0);
292 323
293 SkFixed dr = SkIntToFixed(SkColorGetR(c1) - r) / (count - 1); 324 SkFixed dr = SkIntToFixed(SkColorGetR(c1) - r) / (count - 1);
294 SkFixed dg = SkIntToFixed(SkColorGetG(c1) - g) / (count - 1); 325 SkFixed dg = SkIntToFixed(SkColorGetG(c1) - g) / (count - 1);
(...skipping 27 matching lines...) Expand all
322 * 2. change SkPackARGB32 to + its (a << SK_A32_SHIFT) value instead 353 * 2. change SkPackARGB32 to + its (a << SK_A32_SHIFT) value instead
323 * of using | 354 * of using |
324 * 355 *
325 * We chose #1 just because it was more localized. 356 * We chose #1 just because it was more localized.
326 * See http://code.google.com/p/skia/issues/detail?id=1113 357 * See http://code.google.com/p/skia/issues/detail?id=1113
327 * 358 *
328 * The type SkUFixed encapsulate this need for unsigned, but logically Fixed. 359 * The type SkUFixed encapsulate this need for unsigned, but logically Fixed.
329 */ 360 */
330 typedef uint32_t SkUFixed; 361 typedef uint32_t SkUFixed;
331 362
332 void SkGradientShaderBase::Build32bitCache(SkPMColor cache[], SkColor c0, SkColo r c1, 363 void SkGradientShaderBase::GradientShaderCache::Build32bitCache(
333 int count, U8CPU paintAlpha, uint32_t grad Flags) { 364 SkPMColor cache[], SkColor c0, SkColor c1,
365 int count, U8CPU paintAlpha, uint32_t gradFlags) {
334 SkASSERT(count > 1); 366 SkASSERT(count > 1);
335 367
336 // need to apply paintAlpha to our two endpoints 368 // need to apply paintAlpha to our two endpoints
337 uint32_t a0 = SkMulDiv255Round(SkColorGetA(c0), paintAlpha); 369 uint32_t a0 = SkMulDiv255Round(SkColorGetA(c0), paintAlpha);
338 uint32_t a1 = SkMulDiv255Round(SkColorGetA(c1), paintAlpha); 370 uint32_t a1 = SkMulDiv255Round(SkColorGetA(c1), paintAlpha);
339 371
340 372
341 const bool interpInPremul = SkToBool(gradFlags & 373 const bool interpInPremul = SkToBool(gradFlags &
342 SkGradientShader::kInterpolateColorsInPremul_Flag); 374 SkGradientShader::kInterpolateColorsInPremul_Flag);
343 375
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 if (6 == bits) { 498 if (6 == bits) {
467 return (x << 10) | (x << 4) | (x >> 2); 499 return (x << 10) | (x << 4) | (x >> 2);
468 } 500 }
469 if (8 == bits) { 501 if (8 == bits) {
470 return (x << 8) | x; 502 return (x << 8) | x;
471 } 503 }
472 sk_throw(); 504 sk_throw();
473 return 0; 505 return 0;
474 } 506 }
475 507
476 const uint16_t* SkGradientShaderBase::getCache16() const { 508 const uint16_t* SkGradientShaderBase::GradientShaderCache::getCache16(
509 const SkGradientShaderBase& shader) {
477 if (fCache16 == NULL) { 510 if (fCache16 == NULL) {
478 // double the count for dither entries 511 // double the count for dither entries
479 const int entryCount = kCache16Count * 2; 512 const int entryCount = kCache16Count * 2;
480 const size_t allocSize = sizeof(uint16_t) * entryCount; 513 const size_t allocSize = sizeof(uint16_t) * entryCount;
481 514
482 if (fCache16Storage == NULL) { // set the storage and our working ptr 515 if (fCache16Storage == NULL) { // set the storage and our working ptr
483 fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize); 516 fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize);
484 } 517 }
485 fCache16 = fCache16Storage; 518 fCache16 = fCache16Storage;
486 if (fColorCount == 2) { 519 if (shader.fColorCount == 2) {
487 Build16bitCache(fCache16, fOrigColors[0], fOrigColors[1], 520 Build16bitCache(fCache16, shader.fOrigColors[0], shader.fOrigColors[ 1],
488 kCache16Count); 521 kCache16Count);
489 } else { 522 } else {
490 Rec* rec = fRecs; 523 Rec* rec = shader.fRecs;
491 int prevIndex = 0; 524 int prevIndex = 0;
492 for (int i = 1; i < fColorCount; i++) { 525 for (int i = 1; i < shader.fColorCount; i++) {
493 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache16Shift; 526 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache16Shift;
494 SkASSERT(nextIndex < kCache16Count); 527 SkASSERT(nextIndex < kCache16Count);
495 528
496 if (nextIndex > prevIndex) 529 if (nextIndex > prevIndex)
497 Build16bitCache(fCache16 + prevIndex, fOrigColors[i-1], fOri gColors[i], nextIndex - prevIndex + 1); 530 Build16bitCache(fCache16 + prevIndex, shader.fOrigColors[i-1 ],
531 shader.fOrigColors[i], nextIndex - prevIndex + 1);
498 prevIndex = nextIndex; 532 prevIndex = nextIndex;
499 } 533 }
500 } 534 }
501 535
502 if (fMapper) { 536 if (shader.fMapper) {
503 fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize); 537 fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize);
504 uint16_t* linear = fCache16; // just computed linear data 538 uint16_t* linear = fCache16; // just computed linear data
505 uint16_t* mapped = fCache16Storage; // storage for mapped data 539 uint16_t* mapped = fCache16Storage; // storage for mapped data
506 SkUnitMapper* map = fMapper; 540 SkUnitMapper* map = shader.fMapper;
507 for (int i = 0; i < kCache16Count; i++) { 541 for (int i = 0; i < kCache16Count; i++) {
508 int index = map->mapUnit16(bitsTo16(i, kCache16Bits)) >> kCache1 6Shift; 542 int index = map->mapUnit16(bitsTo16(i, kCache16Bits)) >> kCache1 6Shift;
509 mapped[i] = linear[index]; 543 mapped[i] = linear[index];
510 mapped[i + kCache16Count] = linear[index + kCache16Count]; 544 mapped[i + kCache16Count] = linear[index + kCache16Count];
511 } 545 }
512 sk_free(fCache16); 546 sk_free(fCache16);
513 fCache16 = fCache16Storage; 547 fCache16 = fCache16Storage;
514 } 548 }
515 } 549 }
516 return fCache16; 550 return fCache16;
517 } 551 }
518 552
519 const SkPMColor* SkGradientShaderBase::getCache32() const { 553 const SkPMColor* SkGradientShaderBase::GradientShaderCache::getCache32(
554 const SkGradientShaderBase& shader) {
520 if (fCache32 == NULL) { 555 if (fCache32 == NULL) {
521 SkImageInfo info; 556 SkImageInfo info;
522 info.fWidth = kCache32Count; 557 info.fWidth = kCache32Count;
523 info.fHeight = 4; // for our 4 dither rows 558 info.fHeight = 4; // for our 4 dither rows
524 info.fAlphaType = kPremul_SkAlphaType; 559 info.fAlphaType = kPremul_SkAlphaType;
525 info.fColorType = kPMColor_SkColorType; 560 info.fColorType = kPMColor_SkColorType;
526 561
527 if (NULL == fCache32PixelRef) { 562 if (NULL == fCache32PixelRef) {
528 fCache32PixelRef = SkMallocPixelRef::NewAllocate(info, 0, NULL); 563 fCache32PixelRef = SkMallocPixelRef::NewAllocate(info, 0, NULL);
529 } 564 }
530 fCache32 = (SkPMColor*)fCache32PixelRef->getAddr(); 565 fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
531 if (fColorCount == 2) { 566 if (shader.fColorCount == 2) {
532 Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1], 567 Build32bitCache(fCache32, shader.fOrigColors[0], shader.fOrigColors[ 1],
533 kCache32Count, fCacheAlpha, fGradFlags); 568 kCache32Count, fCacheAlpha, shader.fGradFlags);
534 } else { 569 } else {
535 Rec* rec = fRecs; 570 Rec* rec = shader.fRecs;
536 int prevIndex = 0; 571 int prevIndex = 0;
537 for (int i = 1; i < fColorCount; i++) { 572 for (int i = 1; i < shader.fColorCount; i++) {
538 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache32Shift; 573 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache32Shift;
539 SkASSERT(nextIndex < kCache32Count); 574 SkASSERT(nextIndex < kCache32Count);
540 575
541 if (nextIndex > prevIndex) 576 if (nextIndex > prevIndex)
542 Build32bitCache(fCache32 + prevIndex, fOrigColors[i-1], 577 Build32bitCache(fCache32 + prevIndex, shader.fOrigColors[i-1 ],
543 fOrigColors[i], nextIndex - prevIndex + 1, 578 shader.fOrigColors[i], nextIndex - prevIndex + 1,
544 fCacheAlpha, fGradFlags); 579 fCacheAlpha, shader.fGradFlags);
545 prevIndex = nextIndex; 580 prevIndex = nextIndex;
546 } 581 }
547 } 582 }
548 583
549 if (fMapper) { 584 if (shader.fMapper) {
550 SkMallocPixelRef* newPR = SkMallocPixelRef::NewAllocate(info, 0, NUL L); 585 SkMallocPixelRef* newPR = SkMallocPixelRef::NewAllocate(info, 0, NUL L);
551 SkPMColor* linear = fCache32; // just computed linear data 586 SkPMColor* linear = fCache32; // just computed linear data
552 SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data 587 SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data
553 SkUnitMapper* map = fMapper; 588 SkUnitMapper* map = shader.fMapper;
554 for (int i = 0; i < kCache32Count; i++) { 589 for (int i = 0; i < kCache32Count; i++) {
555 int index = map->mapUnit16((i << 8) | i) >> 8; 590 int index = map->mapUnit16((i << 8) | i) >> 8;
556 mapped[i + kCache32Count*0] = linear[index + kCache32Count*0]; 591 mapped[i + kCache32Count*0] = linear[index + kCache32Count*0];
557 mapped[i + kCache32Count*1] = linear[index + kCache32Count*1]; 592 mapped[i + kCache32Count*1] = linear[index + kCache32Count*1];
558 mapped[i + kCache32Count*2] = linear[index + kCache32Count*2]; 593 mapped[i + kCache32Count*2] = linear[index + kCache32Count*2];
559 mapped[i + kCache32Count*3] = linear[index + kCache32Count*3]; 594 mapped[i + kCache32Count*3] = linear[index + kCache32Count*3];
560 } 595 }
561 fCache32PixelRef->unref(); 596 fCache32PixelRef->unref();
562 fCache32PixelRef = newPR; 597 fCache32PixelRef = newPR;
563 fCache32 = (SkPMColor*)newPR->getAddr(); 598 fCache32 = (SkPMColor*)newPR->getAddr();
564 } 599 }
565 } 600 }
566 return fCache32; 601 return fCache32;
567 } 602 }
568 603
569 /* 604 /*
570 * Because our caller might rebuild the same (logically the same) gradient 605 * Because our caller might rebuild the same (logically the same) gradient
571 * over and over, we'd like to return exactly the same "bitmap" if possible, 606 * over and over, we'd like to return exactly the same "bitmap" if possible,
572 * allowing the client to utilize a cache of our bitmap (e.g. with a GPU). 607 * allowing the client to utilize a cache of our bitmap (e.g. with a GPU).
573 * To do that, we maintain a private cache of built-bitmaps, based on our 608 * To do that, we maintain a private cache of built-bitmaps, based on our
574 * colors and positions. Note: we don't try to flatten the fMapper, so if one 609 * colors and positions. Note: we don't try to flatten the fMapper, so if one
575 * is present, we skip the cache for now. 610 * is present, we skip the cache for now.
576 */ 611 */
577 void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const { 612 void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const {
578 // our caller assumes no external alpha, so we ensure that our cache is 613 // our caller assumes no external alpha, so we ensure that our cache is
579 // built with 0xFF 614 // built with 0xFF
580 this->setCacheAlpha(0xFF); 615 GradientShaderCache cache(0xFF);
581 616
582 // don't have a way to put the mapper into our cache-key yet 617 // don't have a way to put the mapper into our cache-key yet
583 if (fMapper) { 618 if (fMapper) {
584 // force our cahce32pixelref to be built 619 // force our cahce32pixelref to be built
585 (void)this->getCache32(); 620 (void)cache.getCache32(*this);
586 bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1)); 621 bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1));
587 bitmap->setPixelRef(fCache32PixelRef); 622 bitmap->setPixelRef(cache.getCache32PixelRef());
588 return; 623 return;
589 } 624 }
590 625
591 // build our key: [numColors + colors[] + {positions[]} + flags ] 626 // build our key: [numColors + colors[] + {positions[]} + flags ]
592 int count = 1 + fColorCount + 1; 627 int count = 1 + fColorCount + 1;
593 if (fColorCount > 2) { 628 if (fColorCount > 2) {
594 count += fColorCount - 1; // fRecs[].fPos 629 count += fColorCount - 1; // fRecs[].fPos
595 } 630 }
596 631
597 SkAutoSTMalloc<16, int32_t> storage(count); 632 SkAutoSTMalloc<16, int32_t> storage(count);
(...skipping 18 matching lines...) Expand all
616 static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32; 651 static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32;
617 SkAutoMutexAcquire ama(gMutex); 652 SkAutoMutexAcquire ama(gMutex);
618 653
619 if (NULL == gCache) { 654 if (NULL == gCache) {
620 gCache = SkNEW_ARGS(SkBitmapCache, (MAX_NUM_CACHED_GRADIENT_BITMAPS)); 655 gCache = SkNEW_ARGS(SkBitmapCache, (MAX_NUM_CACHED_GRADIENT_BITMAPS));
621 } 656 }
622 size_t size = count * sizeof(int32_t); 657 size_t size = count * sizeof(int32_t);
623 658
624 if (!gCache->find(storage.get(), size, bitmap)) { 659 if (!gCache->find(storage.get(), size, bitmap)) {
625 // force our cahce32pixelref to be built 660 // force our cahce32pixelref to be built
626 (void)this->getCache32(); 661 (void)cache.getCache32(*this);
627 bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1)); 662 bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1));
628 bitmap->setPixelRef(fCache32PixelRef); 663 bitmap->setPixelRef(cache.getCache32PixelRef());
629 664
630 gCache->add(storage.get(), size, *bitmap); 665 gCache->add(storage.get(), size, *bitmap);
631 } 666 }
632 } 667 }
633 668
634 void SkGradientShaderBase::commonAsAGradient(GradientInfo* info) const { 669 void SkGradientShaderBase::commonAsAGradient(GradientInfo* info) const {
635 if (info) { 670 if (info) {
636 if (info->fColorCount >= fColorCount) { 671 if (info->fColorCount >= fColorCount) {
637 if (info->fColors) { 672 if (info->fColors) {
638 memcpy(info->fColors, fOrigColors, fColorCount * sizeof(SkColor) ); 673 memcpy(info->fColors, fOrigColors, fColorCount * sizeof(SkColor) );
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 (*stops)[i] = stop; 1173 (*stops)[i] = stop;
1139 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; 1174 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f;
1140 } 1175 }
1141 } 1176 }
1142 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); 1177 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount));
1143 1178
1144 return outColors; 1179 return outColors;
1145 } 1180 }
1146 1181
1147 #endif 1182 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698