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

Side by Side Diff: src/opts/SkXfermode_opts.h

Issue 1308903003: Templatize SkPMFloat to support both 1 and 255 biases. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: pump the loops for Android Created 5 years, 3 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
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 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 #ifndef Sk4pxXfermode_DEFINED 8 #ifndef Sk4pxXfermode_DEFINED
9 #define Sk4pxXfermode_DEFINED 9 #define Sk4pxXfermode_DEFINED
10 10
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 103
104 auto srcover = s + (d * sa.inv()).div255(), 104 auto srcover = s + (d * sa.inv()).div255(),
105 dstover = d + (s * da.inv()).div255(); 105 dstover = d + (s * da.inv()).div255();
106 auto alphas = srcover, 106 auto alphas = srcover,
107 colors = (dsa < sda).thenElse(srcover, dstover); 107 colors = (dsa < sda).thenElse(srcover, dstover);
108 return alphas.zeroColors() + colors.zeroAlphas(); 108 return alphas.zeroColors() + colors.zeroAlphas();
109 } 109 }
110 #undef XFERMODE 110 #undef XFERMODE
111 111
112 // Some xfermodes use math like divide or sqrt that's best done in floats 1 pixe l at a time. 112 // Some xfermodes use math like divide or sqrt that's best done in floats 1 pixe l at a time.
113 #define XFERMODE(Name) static SkPMFloat SK_VECTORCALL Name(SkPMFloat d, SkPMFloa t s) 113 #define XFERMODE(Name) static SkPMFloat<1> SK_VECTORCALL Name(SkPMFloat<1> d, Sk PMFloat<1> s)
114 114
115 XFERMODE(ColorDodge) { 115 XFERMODE(ColorDodge) {
116 auto sa = s.alphas(), 116 auto sa = s.alphas(),
117 da = d.alphas(), 117 da = d.alphas(),
118 isa = Sk4f(1)-sa, 118 isa = Sk4f(1)-sa,
119 ida = Sk4f(1)-da; 119 ida = Sk4f(1)-da;
120 120
121 auto srcover = s + d*isa, 121 auto srcover = s + d*isa,
122 dstover = d + s*ida, 122 dstover = d + s*ida,
123 otherwise = sa * Sk4f::Min(da, (d*sa)*(sa-s).approxInvert()) + s*ida + d*isa; 123 otherwise = sa * Sk4f::Min(da, (d*sa)*(sa-s).approxInvert()) + s*ida + d*isa;
124 124
125 // Order matters here, preferring d==0 over s==sa. 125 // Order matters here, preferring d==0 over s==sa.
126 auto colors = (d == Sk4f(0)).thenElse(dstover, 126 auto colors = (d == Sk4f(0)).thenElse(dstover,
127 (s == sa).thenElse(srcover, 127 (s == sa).thenElse(srcover,
128 otherwise)); 128 otherwise));
129 return srcover * SkPMFloat(1,0,0,0) + colors * SkPMFloat(0,1,1,1); 129 return srcover * SkPMFloat<1>(1,0,0,0) + colors * SkPMFloat<1>(0,1,1,1);
130 } 130 }
131 XFERMODE(ColorBurn) { 131 XFERMODE(ColorBurn) {
132 auto sa = s.alphas(), 132 auto sa = s.alphas(),
133 da = d.alphas(), 133 da = d.alphas(),
134 isa = Sk4f(1)-sa, 134 isa = Sk4f(1)-sa,
135 ida = Sk4f(1)-da; 135 ida = Sk4f(1)-da;
136 136
137 auto srcover = s + d*isa, 137 auto srcover = s + d*isa,
138 dstover = d + s*ida, 138 dstover = d + s*ida,
139 otherwise = sa*(da-Sk4f::Min(da, (da-d)*sa*s.approxInvert())) + s*ida + d*isa; 139 otherwise = sa*(da-Sk4f::Min(da, (da-d)*sa*s.approxInvert())) + s*ida + d*isa;
140 140
141 // Order matters here, preferring d==da over s==0. 141 // Order matters here, preferring d==da over s==0.
142 auto colors = (d == da).thenElse(dstover, 142 auto colors = (d == da).thenElse(dstover,
143 (s == Sk4f(0)).thenElse(srcover, 143 (s == Sk4f(0)).thenElse(srcover,
144 otherwise)); 144 otherwise));
145 return srcover * SkPMFloat(1,0,0,0) + colors * SkPMFloat(0,1,1,1); 145 return srcover * SkPMFloat<1>(1,0,0,0) + colors * SkPMFloat<1>(0,1,1,1);
146 } 146 }
147 XFERMODE(SoftLight) { 147 XFERMODE(SoftLight) {
148 auto sa = s.alphas(), 148 auto sa = s.alphas(),
149 da = d.alphas(), 149 da = d.alphas(),
150 isa = Sk4f(1)-sa, 150 isa = Sk4f(1)-sa,
151 ida = Sk4f(1)-da; 151 ida = Sk4f(1)-da;
152 152
153 // Some common terms. 153 // Some common terms.
154 auto m = (da > Sk4f(0)).thenElse(d / da, Sk4f(0)), 154 auto m = (da > Sk4f(0)).thenElse(d / da, Sk4f(0)),
155 s2 = Sk4f(2)*s, 155 s2 = Sk4f(2)*s,
156 m4 = Sk4f(4)*m; 156 m4 = Sk4f(4)*m;
157 157
158 // The logic forks three ways: 158 // The logic forks three ways:
159 // 1. dark src? 159 // 1. dark src?
160 // 2. light src, dark dst? 160 // 2. light src, dark dst?
161 // 3. light src, light dst? 161 // 3. light src, light dst?
162 auto darkSrc = d*(sa + (s2 - sa)*(Sk4f(1) - m)), // Used in case 1. 162 auto darkSrc = d*(sa + (s2 - sa)*(Sk4f(1) - m)), // Used in case 1.
163 darkDst = (m4*m4 + m4)*(m - Sk4f(1)) + Sk4f(7)*m, // Used in case 2. 163 darkDst = (m4*m4 + m4)*(m - Sk4f(1)) + Sk4f(7)*m, // Used in case 2.
164 liteDst = m.sqrt() - m, // Used in case 3. 164 liteDst = m.sqrt() - m, // Used in case 3.
165 liteSrc = d*sa + da*(s2-sa)*(Sk4f(4)*d <= da).thenElse(darkDst, liteDst ); // Case 2 or 3? 165 liteSrc = d*sa + da*(s2-sa)*(Sk4f(4)*d <= da).thenElse(darkDst, liteDst ); // Case 2 or 3?
166 166
167 auto alpha = s + d*isa; 167 auto alpha = s + d*isa;
168 auto colors = s*ida + d*isa + (s2 <= sa).thenElse(darkSrc, liteSrc); // Case 1 or 2/3? 168 auto colors = s*ida + d*isa + (s2 <= sa).thenElse(darkSrc, liteSrc); // Case 1 or 2/3?
169 169
170 return alpha * SkPMFloat(1,0,0,0) + colors * SkPMFloat(0,1,1,1); 170 return alpha * SkPMFloat<1>(1,0,0,0) + colors * SkPMFloat<1>(0,1,1,1);
171 } 171 }
172 #undef XFERMODE 172 #undef XFERMODE
173 173
174 // A reasonable fallback mode for doing AA is to simply apply the transfermode f irst, 174 // A reasonable fallback mode for doing AA is to simply apply the transfermode f irst,
175 // then linearly interpolate the AA. 175 // then linearly interpolate the AA.
176 template <Sk4px (SK_VECTORCALL *Mode)(Sk4px, Sk4px)> 176 template <Sk4px (SK_VECTORCALL *Mode)(Sk4px, Sk4px)>
177 static Sk4px SK_VECTORCALL xfer_aa(Sk4px s, Sk4px d, Sk4px aa) { 177 static Sk4px SK_VECTORCALL xfer_aa(Sk4px s, Sk4px d, Sk4px aa) {
178 Sk4px bw = Mode(s, d); 178 Sk4px bw = Mode(s, d);
179 return (bw * aa + d * aa.inv()).div255(); 179 return (bw * aa + d * aa.inv()).div255();
180 } 180 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 } 227 }
228 228
229 private: 229 private:
230 Proc4 fProc4; 230 Proc4 fProc4;
231 AAProc4 fAAProc4; 231 AAProc4 fAAProc4;
232 typedef SkProcCoeffXfermode INHERITED; 232 typedef SkProcCoeffXfermode INHERITED;
233 }; 233 };
234 234
235 class SkPMFloatXfermode : public SkProcCoeffXfermode { 235 class SkPMFloatXfermode : public SkProcCoeffXfermode {
236 public: 236 public:
237 typedef SkPMFloat (SK_VECTORCALL *ProcF)(SkPMFloat, SkPMFloat); 237 typedef SkPMFloat<1> (SK_VECTORCALL *ProcF)(SkPMFloat<1>, SkPMFloat<1>);
238 SkPMFloatXfermode(const ProcCoeff& rec, SkXfermode::Mode mode, ProcF procf) 238 SkPMFloatXfermode(const ProcCoeff& rec, SkXfermode::Mode mode, ProcF procf)
239 : INHERITED(rec, mode) 239 : INHERITED(rec, mode)
240 , fProcF(procf) {} 240 , fProcF(procf) {}
241 241
242 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[ ]) const override { 242 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[ ]) const override {
243 for (int i = 0; i < n; i++) { 243 for (int i = 0; i < n; i++) {
244 dst[i] = aa ? this->xfer32(dst[i], src[i], aa[i]) 244 dst[i] = aa ? this->xfer32(dst[i], src[i], aa[i])
245 : this->xfer32(dst[i], src[i]); 245 : this->xfer32(dst[i], src[i]);
246 } 246 }
247 } 247 }
248 248
249 void xfer16(uint16_t dst[], const SkPMColor src[], int n, const SkAlpha aa[] ) const override { 249 void xfer16(uint16_t dst[], const SkPMColor src[], int n, const SkAlpha aa[] ) const override {
250 for (int i = 0; i < n; i++) { 250 for (int i = 0; i < n; i++) {
251 SkPMColor dst32 = SkPixel16ToPixel32(dst[i]); 251 SkPMColor dst32 = SkPixel16ToPixel32(dst[i]);
252 dst32 = aa ? this->xfer32(dst32, src[i], aa[i]) 252 dst32 = aa ? this->xfer32(dst32, src[i], aa[i])
253 : this->xfer32(dst32, src[i]); 253 : this->xfer32(dst32, src[i]);
254 dst[i] = SkPixel32ToPixel16(dst32); 254 dst[i] = SkPixel32ToPixel16(dst32);
255 } 255 }
256 } 256 }
257 257
258 private: 258 private:
259 inline SkPMColor xfer32(SkPMColor dst, SkPMColor src) const { 259 inline SkPMColor xfer32(SkPMColor dst, SkPMColor src) const {
260 return fProcF(SkPMFloat(dst), SkPMFloat(src)).round(); 260 return fProcF(SkPMFloat<1>(dst), SkPMFloat<1>(src)).round();
261 } 261 }
262 262
263 inline SkPMColor xfer32(SkPMColor dst, SkPMColor src, SkAlpha aa) const { 263 inline SkPMColor xfer32(SkPMColor dst, SkPMColor src, SkAlpha aa) const {
264 SkPMFloat s(src), 264 SkPMFloat<1> s(src),
265 d(dst), 265 d(dst),
266 b(fProcF(d,s)); 266 b(fProcF(d,s));
267 // We do aa in full float precision before going back down to bytes, bec ause we can! 267 // We do aa in full float precision before going back down to bytes, bec ause we can!
268 SkPMFloat a = Sk4f(aa) * Sk4f(1.0f/255); 268 SkPMFloat<1> a = Sk4f(aa) * Sk4f(1.0f/255);
269 b = b*a + d*(Sk4f(1)-a); 269 b = b*a + d*(Sk4f(1)-a);
270 return b.round(); 270 return b.round();
271 } 271 }
272 272
273 ProcF fProcF; 273 ProcF fProcF;
274 typedef SkProcCoeffXfermode INHERITED; 274 typedef SkProcCoeffXfermode INHERITED;
275 }; 275 };
276 276
277 } // namespace 277 } // namespace
278 278
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 #undef CASE 316 #undef CASE
317 317
318 default: break; 318 default: break;
319 } 319 }
320 return nullptr; 320 return nullptr;
321 } 321 }
322 322
323 } // namespace SK_OPTS_NS 323 } // namespace SK_OPTS_NS
324 324
325 #endif//Sk4pxXfermode_DEFINED 325 #endif//Sk4pxXfermode_DEFINED
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698