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

Side by Side Diff: src/core/SkRasterPipelineBlitter.cpp

Issue 2181033002: Have SkRasterPipelineBlitter take over for F16 when it can. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 4 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
« no previous file with comments | « no previous file | no next file » | 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 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 "SkHalf.h"
11 #include "SkPM4f.h" 12 #include "SkPM4f.h"
12 #include "SkRasterPipeline.h" 13 #include "SkRasterPipeline.h"
13 #include "SkShader.h" 14 #include "SkShader.h"
14 #include "SkSRGB.h" 15 #include "SkSRGB.h"
15 #include "SkXfermode.h" 16 #include "SkXfermode.h"
16 17
17 18
18 class SkRasterPipelineBlitter : public SkBlitter { 19 class SkRasterPipelineBlitter : public SkBlitter {
19 public: 20 public:
20 static SkBlitter* Create(const SkPixmap&, const SkPaint&, SkTBlitterAllocato r*); 21 static SkBlitter* Create(const SkPixmap&, const SkPaint&, SkTBlitterAllocato r*);
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 } 218 }
218 219
219 // Store 1 565 pixel. 220 // Store 1 565 pixel.
220 static void SK_VECTORCALL store_565_1(SkRasterPipeline::Stage* st, size_t x, 221 static void SK_VECTORCALL store_565_1(SkRasterPipeline::Stage* st, size_t x,
221 Sk4f r, Sk4f g, Sk4f b, Sk4f a, 222 Sk4f r, Sk4f g, Sk4f b, Sk4f a,
222 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { 223 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) {
223 auto ptr = st->ctx<uint16_t*>() + x; 224 auto ptr = st->ctx<uint16_t*>() + x;
224 *ptr = to_565(r,g,b)[0]; 225 *ptr = to_565(r,g,b)[0];
225 } 226 }
226 227
228 // Load 4 F16 pixels.
229 static void SK_VECTORCALL load_d_f16(SkRasterPipeline::Stage* st, size_t x,
230 Sk4f r, Sk4f g, Sk4f b, Sk4f a,
231 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) {
232 auto ptr = st->ctx<const uint64_t*>() + x;
233
234 // TODO: This can be made a lot more efficient with platform-specific code.
235 auto p0 = SkHalfToFloat_finite(ptr[0]),
236 p1 = SkHalfToFloat_finite(ptr[1]),
237 p2 = SkHalfToFloat_finite(ptr[2]),
238 p3 = SkHalfToFloat_finite(ptr[3]);
239 dr = { p0[0], p1[0], p2[0], p3[0] };
240 dg = { p0[1], p1[1], p2[1], p3[1] };
241 db = { p0[2], p1[2], p2[2], p3[2] };
242 da = { p0[3], p1[3], p2[3], p3[3] };
243
244 st->next(x, r,g,b,a, dr,dg,db,da);
245 }
246
247 // Load 1 F16 pixel.
248 static void SK_VECTORCALL load_d_f16_1(SkRasterPipeline::Stage* st, size_t x,
249 Sk4f r, Sk4f g, Sk4f b, Sk4f a,
250 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) {
251 auto ptr = st->ctx<const uint64_t*>() + x;
252
253 auto p0 = SkHalfToFloat_finite(ptr[0]);
254 dr = { p0[0],0,0,0 };
255 dg = { p0[1],0,0,0 };
256 db = { p0[2],0,0,0 };
257 da = { p0[3],0,0,0 };
258
259 st->next(x, r,g,b,a, dr,dg,db,da);
260 }
261
262 // Store 4 F16 pixels.
263 static void SK_VECTORCALL store_f16(SkRasterPipeline::Stage* st, size_t x,
264 Sk4f r, Sk4f g, Sk4f b, Sk4f a,
265 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) {
266 auto ptr = st->ctx<uint64_t*>() + x;
267
268 Sk4h_store4(ptr, SkFloatToHalf_finite(r), SkFloatToHalf_finite(g),
269 SkFloatToHalf_finite(b), SkFloatToHalf_finite(a));
270 }
271
272 // Store 1 F16 pixel.
273 static void SK_VECTORCALL store_f16_1(SkRasterPipeline::Stage* st, size_t x,
274 Sk4f r, Sk4f g, Sk4f b, Sk4f a,
275 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) {
276 auto ptr = st->ctx<uint64_t*>() + x;
277
278 SkFloatToHalf_finite({r[0], g[0], b[0], a[0]}).store(ptr);
279 }
280
227 // Load 4 8-bit sRGB pixels from SkPMColor order to RGBA. 281 // Load 4 8-bit sRGB pixels from SkPMColor order to RGBA.
228 static void SK_VECTORCALL load_d_srgb(SkRasterPipeline::Stage* st, size_t x, 282 static void SK_VECTORCALL load_d_srgb(SkRasterPipeline::Stage* st, size_t x,
229 Sk4f r, Sk4f g, Sk4f b, Sk4f a, 283 Sk4f r, Sk4f g, Sk4f b, Sk4f a,
230 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { 284 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) {
231 auto ptr = st->ctx<const uint32_t*>() + x; 285 auto ptr = st->ctx<const uint32_t*>() + x;
232 286
233 dr = { sk_linear_from_srgb[(ptr[0] >> SK_R32_SHIFT) & 0xff], 287 dr = { sk_linear_from_srgb[(ptr[0] >> SK_R32_SHIFT) & 0xff],
234 sk_linear_from_srgb[(ptr[1] >> SK_R32_SHIFT) & 0xff], 288 sk_linear_from_srgb[(ptr[1] >> SK_R32_SHIFT) & 0xff],
235 sk_linear_from_srgb[(ptr[2] >> SK_R32_SHIFT) & 0xff], 289 sk_linear_from_srgb[(ptr[2] >> SK_R32_SHIFT) & 0xff],
236 sk_linear_from_srgb[(ptr[3] >> SK_R32_SHIFT) & 0xff] }; 290 sk_linear_from_srgb[(ptr[3] >> SK_R32_SHIFT) & 0xff] };
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 auto dst = st->ctx<uint32_t*>() + x; 337 auto dst = st->ctx<uint32_t*>() + x;
284 Sk4i rgb = sk_linear_to_srgb_noclamp(swizzle_rb_if_bgra({ r[0], g[0], b[0], 0.0f })); 338 Sk4i rgb = sk_linear_to_srgb_noclamp(swizzle_rb_if_bgra({ r[0], g[0], b[0], 0.0f }));
285 339
286 uint32_t rgba; 340 uint32_t rgba;
287 SkNx_cast<uint8_t>(rgb).store(&rgba); 341 SkNx_cast<uint8_t>(rgb).store(&rgba);
288 rgba |= (uint32_t)(255.0f * a[0] + 0.5f) << 24; 342 rgba |= (uint32_t)(255.0f * a[0] + 0.5f) << 24;
289 *dst = rgba; 343 *dst = rgba;
290 } 344 }
291 345
292 static bool supported(const SkImageInfo& info) { 346 static bool supported(const SkImageInfo& info) {
293 // TODO: f16, more?
294 switch (info.colorType()) { 347 switch (info.colorType()) {
295 case kN32_SkColorType: return info.gammaCloseToSRGB(); 348 case kN32_SkColorType: return info.gammaCloseToSRGB();
296 case kRGB_565_SkColorType: return true; 349 case kRGBA_F16_SkColorType: return true;
297 default: return false; 350 case kRGB_565_SkColorType: return true;
351 default: return false;
298 } 352 }
299 } 353 }
300 354
301 template <typename Effect> 355 template <typename Effect>
302 static bool append_effect_stages(const Effect* effect, SkRasterPipeline* pipelin e) { 356 static bool append_effect_stages(const Effect* effect, SkRasterPipeline* pipelin e) {
303 return !effect || effect->appendStages(pipeline); 357 return !effect || effect->appendStages(pipeline);
304 } 358 }
305 359
306 360
307 SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst, 361 SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
308 const SkPaint& paint, 362 const SkPaint& paint,
309 SkTBlitterAllocator* alloc) { 363 SkTBlitterAllocator* alloc) {
310 if (!supported(dst.info())) { 364 if (!supported(dst.info())) {
311 return nullptr; 365 return nullptr;
312 } 366 }
313 if (paint.getShader()) { 367 if (paint.getShader()) {
314 return nullptr; // TODO: need to work out how shaders and their context s work 368 return nullptr; // TODO: need to work out how shaders and their context s work
315 } 369 }
316 370
317 SkRasterPipeline shader, colorFilter, xfermode; 371 SkRasterPipeline shader, colorFilter, xfermode;
318 if (!append_effect_stages(paint.getColorFilter(), &colorFilter) || 372 if (!append_effect_stages(paint.getColorFilter(), &colorFilter) ||
319 !append_effect_stages(paint.getXfermode(), &xfermode )) { 373 !append_effect_stages(paint.getXfermode(), &xfermode )) {
320 return nullptr; 374 return nullptr;
321 } 375 }
322 376
323 uint32_t paintColor = paint.getColor(); 377 uint32_t paintColor = paint.getColor();
324 378
325 SkColor4f color; 379 SkColor4f color;
326 if (dst.info().colorSpace()) { 380 if (SkImageInfoIsGammaCorrect(dst.info())) {
327 color = SkColor4f::FromColor(paintColor); 381 color = SkColor4f::FromColor(paintColor);
328 } else { 382 } else {
329 swizzle_rb(SkNx_cast<float>(Sk4b::Load(&paintColor)) * (1/255.0f)).store (&color); 383 swizzle_rb(SkNx_cast<float>(Sk4b::Load(&paintColor)) * (1/255.0f)).store (&color);
330 } 384 }
331 385
332 auto blitter = alloc->createT<SkRasterPipelineBlitter>( 386 auto blitter = alloc->createT<SkRasterPipelineBlitter>(
333 dst, 387 dst,
334 shader, colorFilter, xfermode, 388 shader, colorFilter, xfermode,
335 color.premul()); 389 color.premul());
336 390
337 if (!paint.getShader()) { 391 if (!paint.getShader()) {
338 blitter->fShader.append(constant_color, &blitter->fPaintColor); 392 blitter->fShader.append(constant_color, &blitter->fPaintColor);
339 } 393 }
340 if (!paint.getXfermode()) { 394 if (!paint.getXfermode()) {
341 blitter->fXfermode.append(srcover); 395 blitter->fXfermode.append(srcover);
342 } 396 }
343 397
344 return blitter; 398 return blitter;
345 } 399 }
346 400
347 void SkRasterPipelineBlitter::append_load_d(SkRasterPipeline* p, const void* dst ) const { 401 void SkRasterPipelineBlitter::append_load_d(SkRasterPipeline* p, const void* dst ) const {
348 SkASSERT(supported(fDst.info())); 402 SkASSERT(supported(fDst.info()));
349 403
350 switch (fDst.info().colorType()) { 404 switch (fDst.info().colorType()) {
351 case kN32_SkColorType: 405 case kN32_SkColorType:
352 if (fDst.info().gammaCloseToSRGB()) { 406 if (fDst.info().gammaCloseToSRGB()) {
353 p->append(load_d_srgb, load_d_srgb_1, dst); 407 p->append(load_d_srgb, load_d_srgb_1, dst);
354 } 408 }
355 break; 409 break;
410 case kRGBA_F16_SkColorType:
411 p->append(load_d_f16, load_d_f16_1, dst);
412 break;
356 case kRGB_565_SkColorType: 413 case kRGB_565_SkColorType:
357 p->append(load_d_565, load_d_565_1, dst); 414 p->append(load_d_565, load_d_565_1, dst);
358 break; 415 break;
359 default: break; 416 default: break;
360 } 417 }
361 } 418 }
362 419
363 void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p, void* dst) const { 420 void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p, void* dst) const {
364 SkASSERT(supported(fDst.info())); 421 SkASSERT(supported(fDst.info()));
365 422
366 p->append(clamp_01_premul); 423 p->append(clamp_01_premul);
367 switch (fDst.info().colorType()) { 424 switch (fDst.info().colorType()) {
368 case kN32_SkColorType: 425 case kN32_SkColorType:
369 if (fDst.info().gammaCloseToSRGB()) { 426 if (fDst.info().gammaCloseToSRGB()) {
370 p->append(store_srgb, store_srgb_1, dst); 427 p->append(store_srgb, store_srgb_1, dst);
371 } 428 }
372 break; 429 break;
430 case kRGBA_F16_SkColorType:
431 p->append(store_f16, store_f16_1, dst);
432 break;
373 case kRGB_565_SkColorType: 433 case kRGB_565_SkColorType:
374 p->append(store_565, store_565_1, dst); 434 p->append(store_565, store_565_1, dst);
375 break; 435 break;
376 default: break; 436 default: break;
377 } 437 }
378 } 438 }
379 439
380 void SkRasterPipelineBlitter::blitH(int x, int y, int w) { 440 void SkRasterPipelineBlitter::blitH(int x, int y, int w) {
381 auto dst = fDst.writable_addr(0,y); 441 auto dst = fDst.writable_addr(0,y);
382 442
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 case SkMask::kLCD16_Format: 494 case SkMask::kLCD16_Format:
435 p.append(lerp_lcd16, lerp_lcd16_1, mask.getAddrLCD16(x,y)-x); 495 p.append(lerp_lcd16, lerp_lcd16_1, mask.getAddrLCD16(x,y)-x);
436 break; 496 break;
437 default: break; 497 default: break;
438 } 498 }
439 this->append_store(&p, dst); 499 this->append_store(&p, dst);
440 500
441 p.run(x, clip.width()); 501 p.run(x, clip.width());
442 } 502 }
443 } 503 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698