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

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

Issue 1829513002: Use Sk4x4f in srcover_srgb_dst_1. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: tweaks for clarity Created 4 years, 9 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 "SkPM4fPriv.h" 8 #include "SkPM4fPriv.h"
9 #include "SkUtils.h" 9 #include "SkUtils.h"
10 #include "SkXfermode.h" 10 #include "SkXfermode.h"
(...skipping 29 matching lines...) Expand all
40 } 40 }
41 41
42 template <DstType D> uint32_t store_dst(const Sk4f& x4) { 42 template <DstType D> uint32_t store_dst(const Sk4f& x4) {
43 return (D == kSRGB_Dst) ? Sk4f_toS32(x4) : Sk4f_toL32(x4); 43 return (D == kSRGB_Dst) ? Sk4f_toS32(x4) : Sk4f_toL32(x4);
44 } 44 }
45 45
46 static Sk4f linear_unit_to_srgb_255f(const Sk4f& l4) { 46 static Sk4f linear_unit_to_srgb_255f(const Sk4f& l4) {
47 return linear_to_srgb(l4) * Sk4f(255) + Sk4f(0.5f); 47 return linear_to_srgb(l4) * Sk4f(255) + Sk4f(0.5f);
48 } 48 }
49 49
50 // Load 4 interlaced 8888 sRGB pixels as an Sk4x4f, transposed and converted to float.
51 static Sk4x4f load_4_srgb(const void* ptr) {
52 auto p = Sk4x4f::Transpose((const uint8_t*)ptr);
53
54 // Scale to [0,1].
55 p.r *= 1/255.0f;
56 p.g *= 1/255.0f;
57 p.b *= 1/255.0f;
58 p.a *= 1/255.0f;
59
60 // Apply approximate sRGB gamma correction to convert to linear (as if gamma were 2).
61 p.r *= p.r;
62 p.g *= p.g;
63 p.b *= p.b;
64
65 return p;
66 }
67
68 // Store an Sk4x4f back to 4 interlaced 8888 sRGB pixels.
69 static void store_4_srgb(void* ptr, const Sk4x4f& p) {
70 // Convert back to sRGB and [0,255], again approximating sRGB as gamma == 2.
71 auto r = p.r.sqrt() * 255.0f + 0.5f,
72 g = p.g.sqrt() * 255.0f + 0.5f,
73 b = p.b.sqrt() * 255.0f + 0.5f,
74 a = p.a * 255.0f + 0.5f;
75 Sk4x4f{r,g,b,a}.transpose((uint8_t*)ptr);
76 }
77
50 //////////////////////////////////////////////////////////////////////////////// /////////////////// 78 //////////////////////////////////////////////////////////////////////////////// ///////////////////
51 79
52 template <DstType D> void general_1(const SkXfermode* xfer, uint32_t dst[], 80 template <DstType D> void general_1(const SkXfermode* xfer, uint32_t dst[],
53 const SkPM4f* src, int count, const SkAlpha aa[]) { 81 const SkPM4f* src, int count, const SkAlpha aa[]) {
54 const SkPM4f s = rgba_to_pmcolor_order(*src); 82 const SkPM4f s = rgba_to_pmcolor_order(*src);
55 SkXfermodeProc4f proc = xfer->getProc4f(); 83 SkXfermodeProc4f proc = xfer->getProc4f();
56 SkPM4f d; 84 SkPM4f d;
57 if (aa) { 85 if (aa) {
58 for (int i = 0; i < count; ++i) { 86 for (int i = 0; i < count; ++i) {
59 Sk4f d4 = load_dst<D>(dst[i]); 87 Sk4f d4 = load_dst<D>(dst[i]);
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 256
229 static void dst(const SkXfermode*, uint32_t dst[], const SkPM4f[], int count, co nst SkAlpha aa[]) {} 257 static void dst(const SkXfermode*, uint32_t dst[], const SkPM4f[], int count, co nst SkAlpha aa[]) {}
230 258
231 const SkXfermode::D32Proc gProcs_Dst[] = { 259 const SkXfermode::D32Proc gProcs_Dst[] = {
232 dst, dst, dst, dst, dst, dst, dst, dst, 260 dst, dst, dst, dst, dst, dst, dst, dst,
233 }; 261 };
234 262
235 //////////////////////////////////////////////////////////////////////////////// /////////////////// 263 //////////////////////////////////////////////////////////////////////////////// ///////////////////
236 264
237 265
238 static void srcover_n_srgb_bw(uint32_t dst[], const SkPM4f src[], int count) {
239 while (count >= 4) {
240 // Load 4 sRGB RGBA/BGRA 8888 dst pixels.
241 // We'll write most of this as if they're RGBA, and just swizzle the src pixels to match.
242 auto d = Sk4x4f::Transpose((const uint8_t*)dst);
243
244 // Scale to [0,1].
245 d.r *= 1/255.0f;
246 d.g *= 1/255.0f;
247 d.b *= 1/255.0f;
248 d.a *= 1/255.0f;
249
250 // Apply approximate sRGB gamma correction to convert to linear (as if g amma were 2).
251 d.r *= d.r;
252 d.g *= d.g;
253 d.b *= d.b;
254
255 // Load 4 linear float src pixels.
256 auto s = Sk4x4f::Transpose(src->fVec);
257
258 // Match color order with destination, if necessary.
259 #if defined(SK_PMCOLOR_IS_BGRA)
260 SkTSwap(s.r, s.b);
261 #endif
262
263 // Now, the meat of what we wanted to do... perform the srcover blend.
264 auto invSA = 1.0f - s.a;
265 auto r = s.r + d.r * invSA,
266 g = s.g + d.g * invSA,
267 b = s.b + d.b * invSA,
268 a = s.a + d.a * invSA;
269
270 // Convert back to sRGB and [0,255], again approximating sRGB as gamma = = 2.
271 r = r.sqrt() * 255.0f + 0.5f;
272 g = g.sqrt() * 255.0f + 0.5f;
273 b = b.sqrt() * 255.0f + 0.5f;
274 a = a * 255.0f + 0.5f;
275
276 Sk4x4f{r,g,b,a}.transpose((uint8_t*)dst);
277
278 count -= 4;
279 dst += 4;
280 src += 4;
281 }
282
283 // This should look just like the non-specialized case in srcover_n.
284 for (int i = 0; i < count; ++i) {
285 Sk4f s4 = src[i].to4f_pmorder();
286 Sk4f d4 = load_dst<kSRGB_Dst>(dst[i]);
287 Sk4f r4 = s4 + d4 * Sk4f(1 - get_alpha(s4));
288 dst[i] = store_dst<kSRGB_Dst>(r4);
289 }
290 }
291
292 template <DstType D> void srcover_n(const SkXfermode*, uint32_t dst[], 266 template <DstType D> void srcover_n(const SkXfermode*, uint32_t dst[],
293 const SkPM4f src[], int count, const SkAlpha aa[]) { 267 const SkPM4f src[], int count, const SkAlpha aa[]) {
294 if (aa) { 268 if (aa) {
295 for (int i = 0; i < count; ++i) { 269 for (int i = 0; i < count; ++i) {
296 unsigned a = aa[i]; 270 unsigned a = aa[i];
297 if (0 == a) { 271 if (0 == a) {
298 continue; 272 continue;
299 } 273 }
300 Sk4f s4 = src[i].to4f_pmorder(); 274 Sk4f s4 = src[i].to4f_pmorder();
301 Sk4f d4 = load_dst<D>(dst[i]); 275 Sk4f d4 = load_dst<D>(dst[i]);
302 if (a != 0xFF) { 276 if (a != 0xFF) {
303 s4 = scale_by_coverage(s4, a); 277 s4 = scale_by_coverage(s4, a);
304 } 278 }
305 Sk4f r4 = s4 + d4 * Sk4f(1 - get_alpha(s4)); 279 Sk4f r4 = s4 + d4 * Sk4f(1 - get_alpha(s4));
306 dst[i] = store_dst<D>(r4); 280 dst[i] = store_dst<D>(r4);
307 } 281 }
308 } else { 282 } else {
309 if (D == kSRGB_Dst) { 283 while (count >= 4 && D == kSRGB_Dst) {
310 srcover_n_srgb_bw(dst, src, count); 284 auto d = load_4_srgb(dst);
311 } else { 285
312 for (int i = 0; i < count; ++i) { 286 auto s = Sk4x4f::Transpose(src->fVec);
313 Sk4f s4 = src[i].to4f_pmorder(); 287 #if defined(SK_PMCOLOR_IS_BGRA)
314 Sk4f d4 = load_dst<D>(dst[i]); 288 SkTSwap(s.r, s.b);
315 Sk4f r4 = s4 + d4 * Sk4f(1 - get_alpha(s4)); 289 #endif
316 dst[i] = store_dst<D>(r4); 290
317 } 291 auto invSA = 1.0f - s.a;
292 auto r = s.r + d.r * invSA,
293 g = s.g + d.g * invSA,
294 b = s.b + d.b * invSA,
295 a = s.a + d.a * invSA;
296
297 store_4_srgb(dst, Sk4x4f{r,g,b,a});
298 count -= 4;
299 dst += 4;
300 src += 4;
301 }
302 for (int i = 0; i < count; ++i) {
303 Sk4f s4 = src[i].to4f_pmorder();
304 Sk4f d4 = load_dst<D>(dst[i]);
305 Sk4f r4 = s4 + d4 * Sk4f(1 - get_alpha(s4));
306 dst[i] = store_dst<D>(r4);
318 } 307 }
319 } 308 }
320 } 309 }
321 310
322 static void srcover_linear_dst_1(const SkXfermode*, uint32_t dst[], 311 static void srcover_linear_dst_1(const SkXfermode*, uint32_t dst[],
323 const SkPM4f* src, int count, const SkAlpha aa[ ]) { 312 const SkPM4f* src, int count, const SkAlpha aa[ ]) {
324 const Sk4f s4 = src->to4f_pmorder(); 313 const Sk4f s4 = src->to4f_pmorder();
325 const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); 314 const Sk4f dst_scale = Sk4f(1 - get_alpha(s4));
326 315
327 if (aa) { 316 if (aa) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 if (a != 0xFF) { 367 if (a != 0xFF) {
379 const Sk4f s4_aa = scale_by_coverage(s4, a); 368 const Sk4f s4_aa = scale_by_coverage(s4, a);
380 r4 = s4_aa + d4 * Sk4f(1 - get_alpha(s4_aa)); 369 r4 = s4_aa + d4 * Sk4f(1 - get_alpha(s4_aa));
381 } else { 370 } else {
382 r4 = s4 + d4 * dst_scale; 371 r4 = s4 + d4 * dst_scale;
383 } 372 }
384 dst[i] = to_4b(linear_unit_to_srgb_255f(r4)); 373 dst[i] = to_4b(linear_unit_to_srgb_255f(r4));
385 } 374 }
386 } else { 375 } else {
387 while (count >= 4) { 376 while (count >= 4) {
388 Sk4f d0 = srgb_4b_to_linear_unit(dst[0]); 377 auto d = load_4_srgb(dst);
389 Sk4f d1 = srgb_4b_to_linear_unit(dst[1]); 378
390 Sk4f d2 = srgb_4b_to_linear_unit(dst[2]); 379 auto s = Sk4x4f{{ src->r() }, { src->g() }, { src->b() }, { src->a() }};
391 Sk4f d3 = srgb_4b_to_linear_unit(dst[3]); 380 #if defined(SK_PMCOLOR_IS_BGRA)
392 Sk4f_ToBytes((uint8_t*)dst, 381 SkTSwap(s.r, s.b);
393 linear_unit_to_srgb_255f(s4 + d0 * dst_scale), 382 #endif
394 linear_unit_to_srgb_255f(s4 + d1 * dst_scale), 383
395 linear_unit_to_srgb_255f(s4 + d2 * dst_scale), 384 auto invSA = 1.0f - s.a;
396 linear_unit_to_srgb_255f(s4 + d3 * dst_scale)); 385 auto r = s.r + d.r * invSA,
386 g = s.g + d.g * invSA,
387 b = s.b + d.b * invSA,
388 a = s.a + d.a * invSA;
389
390 store_4_srgb(dst, Sk4x4f{r,g,b,a});
391 count -= 4;
397 dst += 4; 392 dst += 4;
398 count -= 4;
399 } 393 }
400 for (int i = 0; i < count; ++i) { 394 for (int i = 0; i < count; ++i) {
401 Sk4f d4 = srgb_4b_to_linear_unit(dst[i]); 395 Sk4f d4 = srgb_4b_to_linear_unit(dst[i]);
402 dst[i] = to_4b(linear_unit_to_srgb_255f(s4 + d4 * dst_scale)); 396 dst[i] = to_4b(linear_unit_to_srgb_255f(s4 + d4 * dst_scale));
403 } 397 }
404 } 398 }
405 } 399 }
406 400
407 const SkXfermode::D32Proc gProcs_SrcOver[] = { 401 const SkXfermode::D32Proc gProcs_SrcOver[] = {
408 srcover_n<kLinear_Dst>, src_n<kLinear_Dst>, 402 srcover_n<kLinear_Dst>, src_n<kLinear_Dst>,
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 526
533 const LCD32Proc procs[] = { 527 const LCD32Proc procs[] = {
534 srcover_n_lcd<kSRGB_Dst>, src_n_lcd<kSRGB_Dst>, 528 srcover_n_lcd<kSRGB_Dst>, src_n_lcd<kSRGB_Dst>,
535 srcover_1_lcd<kSRGB_Dst>, src_1_lcd<kSRGB_Dst>, 529 srcover_1_lcd<kSRGB_Dst>, src_1_lcd<kSRGB_Dst>,
536 530
537 srcover_n_lcd<kLinear_Dst>, src_n_lcd<kLinear_Dst>, 531 srcover_n_lcd<kLinear_Dst>, src_n_lcd<kLinear_Dst>,
538 srcover_1_lcd<kLinear_Dst>, src_1_lcd<kLinear_Dst>, 532 srcover_1_lcd<kLinear_Dst>, src_1_lcd<kLinear_Dst>,
539 }; 533 };
540 return procs[flags]; 534 return procs[flags];
541 } 535 }
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