| 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 |