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

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

Issue 1653943002: unroll srcover_1 for blending a single color (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: separate src_1 functions Created 4 years, 10 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 13 matching lines...) Expand all
24 } 24 }
25 25
26 static Sk4f lerp(const Sk4f& src, const Sk4f& dst, uint8_t srcCoverage) { 26 static Sk4f lerp(const Sk4f& src, const Sk4f& dst, uint8_t srcCoverage) {
27 return dst + (src - dst) * Sk4f(srcCoverage * (1/255.0f)); 27 return dst + (src - dst) * Sk4f(srcCoverage * (1/255.0f));
28 } 28 }
29 29
30 template <DstType D> Sk4f load_dst(SkPMColor dstC) { 30 template <DstType D> Sk4f load_dst(SkPMColor dstC) {
31 return (D == kSRGB_Dst) ? Sk4f_fromS32(dstC) : Sk4f_fromL32(dstC); 31 return (D == kSRGB_Dst) ? Sk4f_fromS32(dstC) : Sk4f_fromL32(dstC);
32 } 32 }
33 33
34 static Sk4f srgb_4b_to_linear_unit(SkPMColor dstC) {
35 return Sk4f_fromS32(dstC);
36 }
37
34 template <DstType D> uint32_t store_dst(const Sk4f& x4) { 38 template <DstType D> uint32_t store_dst(const Sk4f& x4) {
35 return (D == kSRGB_Dst) ? Sk4f_toS32(x4) : Sk4f_toL32(x4); 39 return (D == kSRGB_Dst) ? Sk4f_toS32(x4) : Sk4f_toL32(x4);
36 } 40 }
37 41
42 static uint32_t linear_unit_to_srgb_32(const Sk4f& l4) {
43 return Sk4f_toL32(l4);
44 }
45
46 static Sk4f linear_unit_to_srgb_255f(const Sk4f& l4) {
47 return linear_to_srgb(l4) * Sk4f(255) + Sk4f(0.5f);
48 }
49
38 //////////////////////////////////////////////////////////////////////////////// /////////////////// 50 //////////////////////////////////////////////////////////////////////////////// ///////////////////
39 51
40 static Sk4f scale_255_round(const SkPM4f& pm4) { 52 static Sk4f scale_255_round(const SkPM4f& pm4) {
41 return Sk4f::Load(pm4.fVec) * Sk4f(255) + Sk4f(0.5f); 53 return Sk4f::Load(pm4.fVec) * Sk4f(255) + Sk4f(0.5f);
42 } 54 }
43 55
44 static void pm4f_to_linear_32(SkPMColor dst[], const SkPM4f src[], int count) { 56 static void pm4f_to_linear_32(SkPMColor dst[], const SkPM4f src[], int count) {
45 while (count >= 4) { 57 while (count >= 4) {
46 src[0].assertIsUnit(); 58 src[0].assertIsUnit();
47 src[1].assertIsUnit(); 59 src[1].assertIsUnit();
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 } else { 259 } else {
248 for (int i = 0; i < count; ++i) { 260 for (int i = 0; i < count; ++i) {
249 Sk4f s4 = Sk4f::Load(src[i].fVec); 261 Sk4f s4 = Sk4f::Load(src[i].fVec);
250 Sk4f d4 = load_dst<D>(dst[i]); 262 Sk4f d4 = load_dst<D>(dst[i]);
251 Sk4f r4 = s4 + d4 * Sk4f(1 - get_alpha(s4)); 263 Sk4f r4 = s4 + d4 * Sk4f(1 - get_alpha(s4));
252 dst[i] = store_dst<D>(r4); 264 dst[i] = store_dst<D>(r4);
253 } 265 }
254 } 266 }
255 } 267 }
256 268
257 template <DstType D> void srcover_1(const SkXfermode::PM4fState& state, uint32_t dst[], 269 static void srcover_linear_dst_1(const SkXfermode::PM4fState& state, uint32_t ds t[],
258 const SkPM4f& src, int count, const SkAlpha aa[]) { 270 const SkPM4f& src, int count, const SkAlpha aa[ ]) {
259 Sk4f s4 = Sk4f::Load(src.fVec); 271 Sk4f s4 = Sk4f::Load(src.fVec);
260 Sk4f scale = Sk4f(1 - get_alpha(s4)); 272 Sk4f dst_scale = Sk4f(1 - get_alpha(s4));
273
274 if (aa) {
275 for (int i = 0; i < count; ++i) {
276 unsigned a = aa[i];
277 if (0 == a) {
278 continue;
279 }
280 Sk4f d4 = Sk4f_fromL32(dst[i]);
281 Sk4f r4;
282 if (a != 0xFF) {
283 s4 = scale_by_coverage(s4, a);
284 r4 = s4 + d4 * Sk4f(1 - get_alpha(s4));
285 } else {
286 r4 = s4 + d4 * dst_scale;
287 }
288 dst[i] = Sk4f_toL32(r4);
289 }
290 } else {
291 s4 = s4 * Sk4f(255) + Sk4f(0.5f); // +0.5 to pre-bias for rounding
292 while (count >= 4) {
293 Sk4f d0 = to_4f(dst[0]);
294 Sk4f d1 = to_4f(dst[1]);
295 Sk4f d2 = to_4f(dst[2]);
296 Sk4f d3 = to_4f(dst[3]);
297 Sk4f_ToBytes((uint8_t*)dst,
298 s4 + d0 * dst_scale,
299 s4 + d1 * dst_scale,
300 s4 + d2 * dst_scale,
301 s4 + d3 * dst_scale);
302 dst += 4;
303 count -= 4;
304 }
305 for (int i = 0; i < count; ++i) {
306 Sk4f d4 = to_4f(dst[i]);
307 dst[i] = to_4b(s4 + d4 * dst_scale);
308 }
309 }
310 }
311
312 static void srcover_srgb_dst_1(const SkXfermode::PM4fState& state, uint32_t dst[ ],
313 const SkPM4f& src, int count, const SkAlpha aa[]) {
314 Sk4f s4 = Sk4f::Load(src.fVec);
315 Sk4f dst_scale = Sk4f(1 - get_alpha(s4));
261 316
262 if (aa) { 317 if (aa) {
263 for (int i = 0; i < count; ++i) { 318 for (int i = 0; i < count; ++i) {
264 unsigned a = aa[i]; 319 unsigned a = aa[i];
265 if (0 == a) { 320 if (0 == a) {
266 continue; 321 continue;
267 } 322 }
268 Sk4f d4 = load_dst<D>(dst[i]); 323 Sk4f d4 = srgb_4b_to_linear_unit(dst[i]);
269 Sk4f r4; 324 Sk4f r4;
270 if (a != 0xFF) { 325 if (a != 0xFF) {
271 s4 = scale_by_coverage(s4, a); 326 s4 = scale_by_coverage(s4, a);
272 r4 = s4 + d4 * Sk4f(1 - get_alpha(s4)); 327 r4 = s4 + d4 * Sk4f(1 - get_alpha(s4));
273 } else { 328 } else {
274 r4 = s4 + d4 * scale; 329 r4 = s4 + d4 * dst_scale;
275 } 330 }
276 dst[i] = store_dst<D>(r4); 331 dst[i] = linear_unit_to_srgb_32(r4);
277 } 332 }
278 } else { 333 } else {
334 while (count >= 4) {
335 Sk4f d0 = srgb_4b_to_linear_unit(dst[0]);
336 Sk4f d1 = srgb_4b_to_linear_unit(dst[1]);
337 Sk4f d2 = srgb_4b_to_linear_unit(dst[2]);
338 Sk4f d3 = srgb_4b_to_linear_unit(dst[3]);
339 Sk4f_ToBytes((uint8_t*)dst,
340 linear_unit_to_srgb_255f(s4 + d0 * dst_scale),
341 linear_unit_to_srgb_255f(s4 + d1 * dst_scale),
342 linear_unit_to_srgb_255f(s4 + d2 * dst_scale),
343 linear_unit_to_srgb_255f(s4 + d3 * dst_scale));
344 dst += 4;
345 count -= 4;
346 }
279 for (int i = 0; i < count; ++i) { 347 for (int i = 0; i < count; ++i) {
280 Sk4f d4 = load_dst<D>(dst[i]); 348 Sk4f d4 = srgb_4b_to_linear_unit(dst[i]);
281 Sk4f r4 = s4 + d4 * scale; 349 dst[i] = to_4b(linear_unit_to_srgb_255f(s4 + d4 * dst_scale));
282 dst[i] = store_dst<D>(r4);
283 } 350 }
284 } 351 }
285 } 352 }
286 353
287 const XferProcPair gProcs_SrcOver[] = { 354 const XferProcPair gProcs_SrcOver[] = {
288 { srcover_1<kLinear_Dst>, srcover_n<kLinear_Dst> }, // linear alpha 355 { srcover_linear_dst_1, srcover_n<kLinear_Dst> }, // linear alpha
289 { src_1<kLinear_Dst>, src_n<kLinear_Dst> }, // linear opaque [ we are src-mode ] 356 { src_1<kLinear_Dst>, src_n<kLinear_Dst> }, // linear opaque [ we are src-mode ]
290 { srcover_1<kSRGB_Dst>, srcover_n<kSRGB_Dst> }, // srgb alpha 357 { srcover_srgb_dst_1, srcover_n<kSRGB_Dst> }, // srgb alpha
291 { src_1<kSRGB_Dst>, src_n<kSRGB_Dst> }, // srgb opaque [ we are src-mode ] 358 { src_1<kSRGB_Dst>, src_n<kSRGB_Dst> }, // srgb opaque [ we are src-mode ]
292 }; 359 };
293 360
294 //////////////////////////////////////////////////////////////////////////////// /////////////////// 361 //////////////////////////////////////////////////////////////////////////////// ///////////////////
295 362
296 static XferProcPair find_procs(SkXfermode::Mode mode, uint32_t flags) { 363 static XferProcPair find_procs(SkXfermode::Mode mode, uint32_t flags) {
297 SkASSERT(0 == (flags & ~3)); 364 SkASSERT(0 == (flags & ~3));
298 flags &= 3; 365 flags &= 3;
299 366
300 switch (mode) { 367 switch (mode) {
301 case SkXfermode::kClear_Mode: return gProcs_Clear[flags]; 368 case SkXfermode::kClear_Mode: return gProcs_Clear[flags];
(...skipping 16 matching lines...) Expand all
318 385
319 SkXfermode::PM4fProc1 SkXfermode::getPM4fProc1(uint32_t flags) const { 386 SkXfermode::PM4fProc1 SkXfermode::getPM4fProc1(uint32_t flags) const {
320 Mode mode; 387 Mode mode;
321 return this->asMode(&mode) ? GetPM4fProc1(mode, flags) : xfer_pm4_proc_1; 388 return this->asMode(&mode) ? GetPM4fProc1(mode, flags) : xfer_pm4_proc_1;
322 } 389 }
323 390
324 SkXfermode::PM4fProcN SkXfermode::getPM4fProcN(uint32_t flags) const { 391 SkXfermode::PM4fProcN SkXfermode::getPM4fProcN(uint32_t flags) const {
325 Mode mode; 392 Mode mode;
326 return this->asMode(&mode) ? GetPM4fProcN(mode, flags) : xfer_pm4_proc_n; 393 return this->asMode(&mode) ? GetPM4fProcN(mode, flags) : xfer_pm4_proc_n;
327 } 394 }
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