OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
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 "SkBlitter.h" | 8 #include "SkBlitter.h" |
9 #include "SkColor.h" | 9 #include "SkColor.h" |
10 #include "SkColorFilter.h" | 10 #include "SkColorFilter.h" |
11 #include "SkPM4f.h" | 11 #include "SkPM4f.h" |
12 #include "SkPM4fPriv.h" | |
13 #include "SkRasterPipeline.h" | 12 #include "SkRasterPipeline.h" |
14 #include "SkShader.h" | 13 #include "SkShader.h" |
15 #include "SkSRGB.h" | 14 #include "SkSRGB.h" |
16 #include "SkXfermode.h" | 15 #include "SkXfermode.h" |
17 | 16 |
18 | 17 |
19 class SkRasterPipelineBlitter : public SkBlitter { | 18 class SkRasterPipelineBlitter : public SkBlitter { |
20 public: | 19 public: |
21 static SkBlitter* Create(const SkPixmap&, const SkPaint&, SkTBlitterAllocato
r*); | 20 static SkBlitter* Create(const SkPixmap&, const SkPaint&, SkTBlitterAllocato
r*); |
22 | 21 |
(...skipping 27 matching lines...) Expand all Loading... |
50 | 49 |
51 typedef SkBlitter INHERITED; | 50 typedef SkBlitter INHERITED; |
52 }; | 51 }; |
53 | 52 |
54 SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst, | 53 SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst, |
55 const SkPaint& paint, | 54 const SkPaint& paint, |
56 SkTBlitterAllocator* alloc) { | 55 SkTBlitterAllocator* alloc) { |
57 return SkRasterPipelineBlitter::Create(dst, paint, alloc); | 56 return SkRasterPipelineBlitter::Create(dst, paint, alloc); |
58 } | 57 } |
59 | 58 |
| 59 // Clamp colors into [0,1] premul (e.g. just before storing back to memory). |
| 60 static void SK_VECTORCALL clamp_01_premul(SkRasterPipeline::Stage* st, size_t x, |
| 61 Sk4f r, Sk4f g, Sk4f b, Sk4f a, |
| 62 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { |
| 63 a = Sk4f::Max(a, 0.0f); |
| 64 r = Sk4f::Max(r, 0.0f); |
| 65 g = Sk4f::Max(g, 0.0f); |
| 66 b = Sk4f::Max(b, 0.0f); |
| 67 |
| 68 a = Sk4f::Min(a, 1.0f); |
| 69 r = Sk4f::Min(r, a); |
| 70 g = Sk4f::Min(g, a); |
| 71 b = Sk4f::Min(b, a); |
| 72 |
| 73 st->next(x, r,g,b,a, dr,dg,db,da); |
| 74 } |
60 | 75 |
61 // The default shader produces a constant color (from the SkPaint). | 76 // The default shader produces a constant color (from the SkPaint). |
62 static void SK_VECTORCALL constant_color(SkRasterPipeline::Stage* st, size_t x, | 77 static void SK_VECTORCALL constant_color(SkRasterPipeline::Stage* st, size_t x, |
63 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 78 Sk4f r, Sk4f g, Sk4f b, Sk4f a, |
64 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | 79 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { |
65 auto color = st->ctx<const SkPM4f*>(); | 80 auto color = st->ctx<const SkPM4f*>(); |
66 r = color->r(); | 81 r = color->r(); |
67 g = color->g(); | 82 g = color->g(); |
68 b = color->b(); | 83 b = color->b(); |
69 a = color->a(); | 84 a = color->a(); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 da = { (1/255.0f) * (*ptr >> SK_A32_SHIFT) , 0,0,0 }; | 263 da = { (1/255.0f) * (*ptr >> SK_A32_SHIFT) , 0,0,0 }; |
249 | 264 |
250 st->next(x, r,g,b,a, dr,dg,db,da); | 265 st->next(x, r,g,b,a, dr,dg,db,da); |
251 } | 266 } |
252 | 267 |
253 // Write out 4 pixels as 8-bit SkPMColor-order sRGB. | 268 // Write out 4 pixels as 8-bit SkPMColor-order sRGB. |
254 static void SK_VECTORCALL store_srgb(SkRasterPipeline::Stage* st, size_t x, | 269 static void SK_VECTORCALL store_srgb(SkRasterPipeline::Stage* st, size_t x, |
255 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 270 Sk4f r, Sk4f g, Sk4f b, Sk4f a, |
256 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | 271 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { |
257 auto dst = st->ctx<uint32_t*>() + x; | 272 auto dst = st->ctx<uint32_t*>() + x; |
258 ( sk_linear_to_srgb(r) << SK_R32_SHIFT | 273 ( sk_linear_to_srgb_noclamp(r) << SK_R32_SHIFT |
259 | sk_linear_to_srgb(g) << SK_G32_SHIFT | 274 | sk_linear_to_srgb_noclamp(g) << SK_G32_SHIFT |
260 | sk_linear_to_srgb(b) << SK_B32_SHIFT | 275 | sk_linear_to_srgb_noclamp(b) << SK_B32_SHIFT |
261 | Sk4f_round(255.0f*a) << SK_A32_SHIFT).store(dst); | 276 | Sk4f_round(255.0f * a) << SK_A32_SHIFT).store(dst); |
262 } | 277 } |
263 | 278 |
264 // Tail variant of store_srgb() handling 1 pixel at a time. | 279 // Tail variant of store_srgb() handling 1 pixel at a time. |
265 static void SK_VECTORCALL store_srgb_1(SkRasterPipeline::Stage* st, size_t x, | 280 static void SK_VECTORCALL store_srgb_1(SkRasterPipeline::Stage* st, size_t x, |
266 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 281 Sk4f r, Sk4f g, Sk4f b, Sk4f a, |
267 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | 282 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { |
268 auto dst = st->ctx<uint32_t*>() + x; | 283 auto dst = st->ctx<uint32_t*>() + x; |
269 *dst = Sk4f_toS32(swizzle_rb_if_bgra({ r[0], g[0], b[0], a[0] })); | 284 Sk4i rgb = sk_linear_to_srgb_noclamp(swizzle_rb_if_bgra({ r[0], g[0], b[0],
0.0f })); |
| 285 |
| 286 uint32_t rgba; |
| 287 SkNx_cast<uint8_t>(rgb).store(&rgba); |
| 288 rgba |= (uint32_t)(255.0f * a[0] + 0.5f) << 24; |
| 289 *dst = rgba; |
270 } | 290 } |
271 | 291 |
272 static bool supported(const SkImageInfo& info) { | 292 static bool supported(const SkImageInfo& info) { |
273 // TODO: f16, more? | 293 // TODO: f16, more? |
274 switch (info.colorType()) { | 294 switch (info.colorType()) { |
275 case kN32_SkColorType: return info.gammaCloseToSRGB(); | 295 case kN32_SkColorType: return info.gammaCloseToSRGB(); |
276 case kRGB_565_SkColorType: return true; | 296 case kRGB_565_SkColorType: return true; |
277 default: return false; | 297 default: return false; |
278 } | 298 } |
279 } | 299 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 case kRGB_565_SkColorType: | 356 case kRGB_565_SkColorType: |
337 p->append(load_d_565, load_d_565_1, dst); | 357 p->append(load_d_565, load_d_565_1, dst); |
338 break; | 358 break; |
339 default: break; | 359 default: break; |
340 } | 360 } |
341 } | 361 } |
342 | 362 |
343 void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p, void* dst) const
{ | 363 void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p, void* dst) const
{ |
344 SkASSERT(supported(fDst.info())); | 364 SkASSERT(supported(fDst.info())); |
345 | 365 |
| 366 p->append(clamp_01_premul); |
346 switch (fDst.info().colorType()) { | 367 switch (fDst.info().colorType()) { |
347 case kN32_SkColorType: | 368 case kN32_SkColorType: |
348 if (fDst.info().gammaCloseToSRGB()) { | 369 if (fDst.info().gammaCloseToSRGB()) { |
349 p->append(store_srgb, store_srgb_1, dst); | 370 p->append(store_srgb, store_srgb_1, dst); |
350 } | 371 } |
351 break; | 372 break; |
352 case kRGB_565_SkColorType: | 373 case kRGB_565_SkColorType: |
353 p->append(store_565, store_565_1, dst); | 374 p->append(store_565, store_565_1, dst); |
354 break; | 375 break; |
355 default: break; | 376 default: break; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 case SkMask::kLCD16_Format: | 434 case SkMask::kLCD16_Format: |
414 p.append(lerp_lcd16, lerp_lcd16_1, mask.getAddrLCD16(x,y)-x); | 435 p.append(lerp_lcd16, lerp_lcd16_1, mask.getAddrLCD16(x,y)-x); |
415 break; | 436 break; |
416 default: break; | 437 default: break; |
417 } | 438 } |
418 this->append_store(&p, dst); | 439 this->append_store(&p, dst); |
419 | 440 |
420 p.run(x, clip.width()); | 441 p.run(x, clip.width()); |
421 } | 442 } |
422 } | 443 } |
OLD | NEW |