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

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

Issue 15893002: Add flag to gradients to interpolate colors in premul space. Experimental API to encapsulate the sh… (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « include/effects/SkGradientShader.h ('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 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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « include/effects/SkGradientShader.h ('k') | src/effects/gradients/SkGradientShaderPriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698