OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |