• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkHalf.h"
9 #include "SkPM4fPriv.h"
10 #include "SkUtils.h"
11 #include "SkXfermodePriv.h"
12 
lerp_by_coverage(const Sk4f & src,const Sk4f & dst,uint8_t srcCoverage)13 static Sk4f lerp_by_coverage(const Sk4f& src, const Sk4f& dst, uint8_t srcCoverage) {
14     return dst + (src - dst) * Sk4f(srcCoverage * (1/255.0f));
15 }
16 
17 ///////////////////////////////////////////////////////////////////////////////////////////////////
18 
xfer_1(SkBlendMode mode,uint64_t dst[],const SkPM4f * src,int count,const SkAlpha aa[])19 static void xfer_1(SkBlendMode mode, uint64_t dst[], const SkPM4f* src, int count,
20                        const SkAlpha aa[]) {
21     SkXfermodeProc4f proc = SkXfermode::GetProc4f(mode);
22     SkPM4f d;
23     if (aa) {
24         for (int i = 0; i < count; ++i) {
25             Sk4f d4 = SkHalfToFloat_finite_ftz(dst[i]);
26             d4.store(d.fVec);
27             Sk4f r4 = Sk4f::Load(proc(*src, d).fVec);
28             SkFloatToHalf_finite_ftz(lerp_by_coverage(r4, d4, aa[i])).store(&dst[i]);
29         }
30     } else {
31         for (int i = 0; i < count; ++i) {
32             SkHalfToFloat_finite_ftz(dst[i]).store(d.fVec);
33             Sk4f r4 = Sk4f::Load(proc(*src, d).fVec);
34             SkFloatToHalf_finite_ftz(r4).store(&dst[i]);
35         }
36     }
37 }
38 
xfer_n(SkBlendMode mode,uint64_t dst[],const SkPM4f src[],int count,const SkAlpha aa[])39 static void xfer_n(SkBlendMode mode, uint64_t dst[], const SkPM4f src[], int count,
40                        const SkAlpha aa[]) {
41     SkXfermodeProc4f proc = SkXfermode::GetProc4f(mode);
42     SkPM4f d;
43     if (aa) {
44         for (int i = 0; i < count; ++i) {
45             Sk4f d4 = SkHalfToFloat_finite_ftz(dst[i]);
46             d4.store(d.fVec);
47             Sk4f r4 = Sk4f::Load(proc(src[i], d).fVec);
48             SkFloatToHalf_finite_ftz(lerp_by_coverage(r4, d4, aa[i])).store(&dst[i]);
49         }
50     } else {
51         for (int i = 0; i < count; ++i) {
52             SkHalfToFloat_finite_ftz(dst[i]).store(d.fVec);
53             Sk4f r4 = Sk4f::Load(proc(src[i], d).fVec);
54             SkFloatToHalf_finite_ftz(r4).store(&dst[i]);
55         }
56     }
57 }
58 
59 const SkXfermode::F16Proc gProcs_General[] = { xfer_n, xfer_n, xfer_1, xfer_1 };
60 
61 ///////////////////////////////////////////////////////////////////////////////////////////////////
62 
clear(SkBlendMode,uint64_t dst[],const SkPM4f *,int count,const SkAlpha aa[])63 static void clear(SkBlendMode, uint64_t dst[], const SkPM4f*, int count, const SkAlpha aa[]) {
64     if (aa) {
65         for (int i = 0; i < count; ++i) {
66             if (aa[i]) {
67                 const Sk4f d4 = SkHalfToFloat_finite_ftz(dst[i]);
68                 SkFloatToHalf_finite_ftz(d4 * Sk4f((255 - aa[i]) * 1.0f/255)).store(&dst[i]);
69             }
70         }
71     } else {
72         sk_memset64(dst, 0, count);
73     }
74 }
75 
76 const SkXfermode::F16Proc gProcs_Clear[] = { clear, clear, clear, clear };
77 
78 ///////////////////////////////////////////////////////////////////////////////////////////////////
79 
src_1(SkBlendMode,uint64_t dst[],const SkPM4f * src,int count,const SkAlpha aa[])80 static void src_1(SkBlendMode, uint64_t dst[], const SkPM4f* src, int count, const SkAlpha aa[]) {
81     const Sk4f s4 = Sk4f::Load(src->fVec);
82     if (aa) {
83         for (int i = 0; i < count; ++i) {
84             const Sk4f d4 = SkHalfToFloat_finite_ftz(dst[i]);
85             SkFloatToHalf_finite_ftz(lerp_by_coverage(s4, d4, aa[i])).store(&dst[i]);
86         }
87     } else {
88         uint64_t s4h;
89         SkFloatToHalf_finite_ftz(s4).store(&s4h);
90         sk_memset64(dst, s4h, count);
91     }
92 }
93 
src_n(SkBlendMode,uint64_t dst[],const SkPM4f src[],int count,const SkAlpha aa[])94 static void src_n(SkBlendMode, uint64_t dst[], const SkPM4f src[], int count, const SkAlpha aa[]) {
95     if (aa) {
96         for (int i = 0; i < count; ++i) {
97             const Sk4f s4 = Sk4f::Load(src[i].fVec);
98             const Sk4f d4 = SkHalfToFloat_finite_ftz(dst[i]);
99             SkFloatToHalf_finite_ftz(lerp_by_coverage(s4, d4, aa[i])).store(&dst[i]);
100         }
101     } else {
102         for (int i = 0; i < count; ++i) {
103             const Sk4f s4 = Sk4f::Load(src[i].fVec);
104             SkFloatToHalf_finite_ftz(s4).store(&dst[i]);
105         }
106     }
107 }
108 
109 const SkXfermode::F16Proc gProcs_Src[] = { src_n, src_n, src_1,  src_1 };
110 
111 ///////////////////////////////////////////////////////////////////////////////////////////////////
112 
dst(SkBlendMode,uint64_t *,const SkPM4f *,int count,const SkAlpha[])113 static void dst(SkBlendMode, uint64_t*, const SkPM4f*, int count, const SkAlpha[]) {}
114 
115 const SkXfermode::F16Proc gProcs_Dst[] = { dst, dst, dst, dst };
116 
117 ///////////////////////////////////////////////////////////////////////////////////////////////////
118 
srcover_1(SkBlendMode,uint64_t dst[],const SkPM4f * src,int count,const SkAlpha aa[])119 static void srcover_1(SkBlendMode, uint64_t dst[], const SkPM4f* src, int count,
120                       const SkAlpha aa[]) {
121     const Sk4f s4 = Sk4f::Load(src->fVec);
122     const Sk4f dst_scale = Sk4f(1 - get_alpha(s4));
123     for (int i = 0; i < count; ++i) {
124         const Sk4f d4 = SkHalfToFloat_finite_ftz(dst[i]);
125         const Sk4f r4 = s4 + d4 * dst_scale;
126         if (aa) {
127             SkFloatToHalf_finite_ftz(lerp_by_coverage(r4, d4, aa[i])).store(&dst[i]);
128         } else {
129             SkFloatToHalf_finite_ftz(r4).store(&dst[i]);
130         }
131     }
132 }
133 
srcover_n(SkBlendMode,uint64_t dst[],const SkPM4f src[],int count,const SkAlpha aa[])134 static void srcover_n(SkBlendMode, uint64_t dst[], const SkPM4f src[], int count,
135                       const SkAlpha aa[]) {
136     for (int i = 0; i < count; ++i) {
137         Sk4f s = Sk4f::Load(src+i),
138              d = SkHalfToFloat_finite_ftz(dst[i]),
139              r = s + d*(1.0f - SkNx_shuffle<3,3,3,3>(s));
140         if (aa) {
141             r = lerp_by_coverage(r, d, aa[i]);
142         }
143         SkFloatToHalf_finite_ftz(r).store(&dst[i]);
144     }
145 }
146 
147 const SkXfermode::F16Proc gProcs_SrcOver[] = { srcover_n, src_n, srcover_1, src_1 };
148 
149 ///////////////////////////////////////////////////////////////////////////////////////////////////
150 
GetF16Proc(SkBlendMode mode,uint32_t flags)151 SkXfermode::F16Proc SkXfermode::GetF16Proc(SkBlendMode mode, uint32_t flags) {
152     SkASSERT(0 == (flags & ~3));
153     flags &= 3;
154 
155     switch (mode) {
156         case SkBlendMode::kClear:   return gProcs_Clear[flags];
157         case SkBlendMode::kSrc:     return gProcs_Src[flags];
158         case SkBlendMode::kDst:     return gProcs_Dst[flags];
159         case SkBlendMode::kSrcOver: return gProcs_SrcOver[flags];
160         default:
161             break;
162     }
163     return gProcs_General[flags];
164 }
165