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

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

Issue 1324743002: Clean up remaining users of SkPMFloat (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: scale_rgb 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
« no previous file with comments | « src/effects/SkColorMatrixFilter.cpp ('k') | tests/PMFloatTest.cpp » ('j') | 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 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
11 #include "Sk4px.h" 11 #include "Sk4px.h"
12 #include "SkPMFloat.h" 12 #include "SkNx.h"
13 #include "SkXfermode_proccoeff.h" 13 #include "SkXfermode_proccoeff.h"
14 14
15 namespace { 15 namespace {
16 16
17 // Most xfermodes can be done most efficiently 4 pixels at a time in 8 or 16-bit fixed point. 17 // Most xfermodes can be done most efficiently 4 pixels at a time in 8 or 16-bit fixed point.
18 #define XFERMODE(Name) static Sk4px SK_VECTORCALL Name(Sk4px s, Sk4px d) 18 #define XFERMODE(Name) static Sk4px SK_VECTORCALL Name(Sk4px s, Sk4px d)
19 19
20 XFERMODE(Clear) { return Sk4px::DupPMColor(0); } 20 XFERMODE(Clear) { return Sk4px::DupPMColor(0); }
21 XFERMODE(Src) { return s; } 21 XFERMODE(Src) { return s; }
22 XFERMODE(Dst) { return d; } 22 XFERMODE(Dst) { return d; }
(...skipping 80 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 Sk4f SK_VECTORCALL Name(Sk4f d, Sk4f s)
114
115 static inline Sk4f a_rgb(const Sk4f& a, const Sk4f& rgb) {
116 static_assert(SK_A32_SHIFT == 24, "");
117 return a * Sk4f(0,0,0,1) + rgb * Sk4f(1,1,1,0);
118 }
119 static inline Sk4f alphas(const Sk4f& f) {
120 return Sk4f(f.kth<SK_A32_SHIFT/8>());
121 }
114 122
115 XFERMODE(ColorDodge) { 123 XFERMODE(ColorDodge) {
116 auto sa = s.alphas(), 124 auto sa = alphas(s),
117 da = d.alphas(), 125 da = alphas(d),
118 isa = Sk4f(1)-sa, 126 isa = Sk4f(1)-sa,
119 ida = Sk4f(1)-da; 127 ida = Sk4f(1)-da;
120 128
121 auto srcover = s + d*isa, 129 auto srcover = s + d*isa,
122 dstover = d + s*ida, 130 dstover = d + s*ida,
123 otherwise = sa * Sk4f::Min(da, (d*sa)*(sa-s).approxInvert()) + s*ida + d*isa; 131 otherwise = sa * Sk4f::Min(da, (d*sa)*(sa-s).approxInvert()) + s*ida + d*isa;
124 132
125 // Order matters here, preferring d==0 over s==sa. 133 // Order matters here, preferring d==0 over s==sa.
126 auto colors = (d == Sk4f(0)).thenElse(dstover, 134 auto colors = (d == Sk4f(0)).thenElse(dstover,
127 (s == sa).thenElse(srcover, 135 (s == sa).thenElse(srcover,
128 otherwise)); 136 otherwise));
129 return srcover * SkPMFloat(1,0,0,0) + colors * SkPMFloat(0,1,1,1); 137 return a_rgb(srcover, colors);
130 } 138 }
131 XFERMODE(ColorBurn) { 139 XFERMODE(ColorBurn) {
132 auto sa = s.alphas(), 140 auto sa = alphas(s),
133 da = d.alphas(), 141 da = alphas(d),
134 isa = Sk4f(1)-sa, 142 isa = Sk4f(1)-sa,
135 ida = Sk4f(1)-da; 143 ida = Sk4f(1)-da;
136 144
137 auto srcover = s + d*isa, 145 auto srcover = s + d*isa,
138 dstover = d + s*ida, 146 dstover = d + s*ida,
139 otherwise = sa*(da-Sk4f::Min(da, (da-d)*sa*s.approxInvert())) + s*ida + d*isa; 147 otherwise = sa*(da-Sk4f::Min(da, (da-d)*sa*s.approxInvert())) + s*ida + d*isa;
140 148
141 // Order matters here, preferring d==da over s==0. 149 // Order matters here, preferring d==da over s==0.
142 auto colors = (d == da).thenElse(dstover, 150 auto colors = (d == da).thenElse(dstover,
143 (s == Sk4f(0)).thenElse(srcover, 151 (s == Sk4f(0)).thenElse(srcover,
144 otherwise)); 152 otherwise));
145 return srcover * SkPMFloat(1,0,0,0) + colors * SkPMFloat(0,1,1,1); 153 return a_rgb(srcover, colors);
146 } 154 }
147 XFERMODE(SoftLight) { 155 XFERMODE(SoftLight) {
148 auto sa = s.alphas(), 156 auto sa = alphas(s),
149 da = d.alphas(), 157 da = alphas(d),
150 isa = Sk4f(1)-sa, 158 isa = Sk4f(1)-sa,
151 ida = Sk4f(1)-da; 159 ida = Sk4f(1)-da;
152 160
153 // Some common terms. 161 // Some common terms.
154 auto m = (da > Sk4f(0)).thenElse(d / da, Sk4f(0)), 162 auto m = (da > Sk4f(0)).thenElse(d / da, Sk4f(0)),
155 s2 = Sk4f(2)*s, 163 s2 = Sk4f(2)*s,
156 m4 = Sk4f(4)*m; 164 m4 = Sk4f(4)*m;
157 165
158 // The logic forks three ways: 166 // The logic forks three ways:
159 // 1. dark src? 167 // 1. dark src?
160 // 2. light src, dark dst? 168 // 2. light src, dark dst?
161 // 3. light src, light dst? 169 // 3. light src, light dst?
162 auto darkSrc = d*(sa + (s2 - sa)*(Sk4f(1) - m)), // Used in case 1. 170 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. 171 darkDst = (m4*m4 + m4)*(m - Sk4f(1)) + Sk4f(7)*m, // Used in case 2.
164 liteDst = m.sqrt() - m, // Used in case 3. 172 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? 173 liteSrc = d*sa + da*(s2-sa)*(Sk4f(4)*d <= da).thenElse(darkDst, liteDst ); // Case 2 or 3?
166 174
167 auto alpha = s + d*isa; 175 auto alpha = s + d*isa;
168 auto colors = s*ida + d*isa + (s2 <= sa).thenElse(darkSrc, liteSrc); // Case 1 or 2/3? 176 auto colors = s*ida + d*isa + (s2 <= sa).thenElse(darkSrc, liteSrc); // Case 1 or 2/3?
169 177
170 return alpha * SkPMFloat(1,0,0,0) + colors * SkPMFloat(0,1,1,1); 178 return a_rgb(alpha, colors);
171 } 179 }
172 #undef XFERMODE 180 #undef XFERMODE
173 181
174 // A reasonable fallback mode for doing AA is to simply apply the transfermode f irst, 182 // A reasonable fallback mode for doing AA is to simply apply the transfermode f irst,
175 // then linearly interpolate the AA. 183 // then linearly interpolate the AA.
176 template <Sk4px (SK_VECTORCALL *Mode)(Sk4px, Sk4px)> 184 template <Sk4px (SK_VECTORCALL *Mode)(Sk4px, Sk4px)>
177 static Sk4px SK_VECTORCALL xfer_aa(Sk4px s, Sk4px d, Sk4px aa) { 185 static Sk4px SK_VECTORCALL xfer_aa(Sk4px s, Sk4px d, Sk4px aa) {
178 Sk4px bw = Mode(s, d); 186 Sk4px bw = Mode(s, d);
179 return (bw * aa + d * aa.inv()).div255(); 187 return (bw * aa + d * aa.inv()).div255();
180 } 188 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 }); 233 });
226 } 234 }
227 } 235 }
228 236
229 private: 237 private:
230 Proc4 fProc4; 238 Proc4 fProc4;
231 AAProc4 fAAProc4; 239 AAProc4 fAAProc4;
232 typedef SkProcCoeffXfermode INHERITED; 240 typedef SkProcCoeffXfermode INHERITED;
233 }; 241 };
234 242
235 class SkPMFloatXfermode : public SkProcCoeffXfermode { 243 class Sk4fXfermode : public SkProcCoeffXfermode {
236 public: 244 public:
237 typedef SkPMFloat (SK_VECTORCALL *ProcF)(SkPMFloat, SkPMFloat); 245 typedef Sk4f (SK_VECTORCALL *ProcF)(Sk4f, Sk4f);
238 SkPMFloatXfermode(const ProcCoeff& rec, SkXfermode::Mode mode, ProcF procf) 246 Sk4fXfermode(const ProcCoeff& rec, SkXfermode::Mode mode, ProcF procf)
239 : INHERITED(rec, mode) 247 : INHERITED(rec, mode)
240 , fProcF(procf) {} 248 , fProcF(procf) {}
241 249
242 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[ ]) const override { 250 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[ ]) const override {
243 for (int i = 0; i < n; i++) { 251 for (int i = 0; i < n; i++) {
244 dst[i] = aa ? this->xfer32(dst[i], src[i], aa[i]) 252 dst[i] = aa ? this->xfer32(dst[i], src[i], aa[i])
245 : this->xfer32(dst[i], src[i]); 253 : this->xfer32(dst[i], src[i]);
246 } 254 }
247 } 255 }
248 256
249 void xfer16(uint16_t dst[], const SkPMColor src[], int n, const SkAlpha aa[] ) const override { 257 void xfer16(uint16_t dst[], const SkPMColor src[], int n, const SkAlpha aa[] ) const override {
250 for (int i = 0; i < n; i++) { 258 for (int i = 0; i < n; i++) {
251 SkPMColor dst32 = SkPixel16ToPixel32(dst[i]); 259 SkPMColor dst32 = SkPixel16ToPixel32(dst[i]);
252 dst32 = aa ? this->xfer32(dst32, src[i], aa[i]) 260 dst32 = aa ? this->xfer32(dst32, src[i], aa[i])
253 : this->xfer32(dst32, src[i]); 261 : this->xfer32(dst32, src[i]);
254 dst[i] = SkPixel32ToPixel16(dst32); 262 dst[i] = SkPixel32ToPixel16(dst32);
255 } 263 }
256 } 264 }
257 265
258 private: 266 private:
267 static Sk4f Load(SkPMColor c) {
268 return Sk4f::FromBytes((uint8_t*)&c) * Sk4f(1.0f/255);
269 }
270 static SkPMColor Round(const Sk4f& f) {
271 SkPMColor c;
272 (f * Sk4f(255) + Sk4f(0.5f)).toBytes((uint8_t*)&c);
273 return c;
274 }
259 inline SkPMColor xfer32(SkPMColor dst, SkPMColor src) const { 275 inline SkPMColor xfer32(SkPMColor dst, SkPMColor src) const {
260 return fProcF(SkPMFloat(dst), SkPMFloat(src)).round(); 276 return Round(fProcF(Load(dst), Load(src)));
261 } 277 }
262 278
263 inline SkPMColor xfer32(SkPMColor dst, SkPMColor src, SkAlpha aa) const { 279 inline SkPMColor xfer32(SkPMColor dst, SkPMColor src, SkAlpha aa) const {
264 SkPMFloat s(src), 280 Sk4f s(Load(src)),
265 d(dst), 281 d(Load(dst)),
266 b(fProcF(d,s)); 282 b(fProcF(d,s));
267 // We do aa in full float precision before going back down to bytes, bec ause we can! 283 // 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); 284 Sk4f a = Sk4f(aa) * Sk4f(1.0f/255);
269 b = b*a + d*(Sk4f(1)-a); 285 b = b*a + d*(Sk4f(1)-a);
270 return b.round(); 286 return Round(b);
271 } 287 }
272 288
273 ProcF fProcF; 289 ProcF fProcF;
274 typedef SkProcCoeffXfermode INHERITED; 290 typedef SkProcCoeffXfermode INHERITED;
275 }; 291 };
276 292
277 } // namespace 293 } // namespace
278 294
279 namespace SK_OPTS_NS { 295 namespace SK_OPTS_NS {
280 296
281 static SkXfermode* create_xfermode(const ProcCoeff& rec, SkXfermode::Mode mode) { 297 static SkXfermode* create_xfermode(const ProcCoeff& rec, SkXfermode::Mode mode) {
282 switch (mode) { 298 switch (mode) {
283 #define CASE(Mode) \ 299 #define CASE(Mode) \
284 case SkXfermode::k##Mode##_Mode: \ 300 case SkXfermode::k##Mode##_Mode: return new Sk4pxXfermode(rec, mode, &Mode, &xfer_aa<Mode>)
285 return new Sk4pxXfermode(rec, mode, &Mode, &xfer_aa<Mode>)
286 CASE(Clear); 301 CASE(Clear);
287 CASE(Src); 302 CASE(Src);
288 CASE(Dst); 303 CASE(Dst);
289 CASE(SrcOver); 304 CASE(SrcOver);
290 CASE(DstOver); 305 CASE(DstOver);
291 CASE(SrcIn); 306 CASE(SrcIn);
292 CASE(DstIn); 307 CASE(DstIn);
293 CASE(SrcOut); 308 CASE(SrcOut);
294 CASE(DstOut); 309 CASE(DstOut);
295 CASE(SrcATop); 310 CASE(SrcATop);
296 CASE(DstATop); 311 CASE(DstATop);
297 CASE(Xor); 312 CASE(Xor);
298 CASE(Plus); 313 CASE(Plus);
299 CASE(Modulate); 314 CASE(Modulate);
300 CASE(Screen); 315 CASE(Screen);
301 CASE(Multiply); 316 CASE(Multiply);
302 CASE(Difference); 317 CASE(Difference);
303 CASE(Exclusion); 318 CASE(Exclusion);
304 CASE(HardLight); 319 CASE(HardLight);
305 CASE(Overlay); 320 CASE(Overlay);
306 CASE(Darken); 321 CASE(Darken);
307 CASE(Lighten); 322 CASE(Lighten);
308 #undef CASE 323 #undef CASE
309 324
310 #define CASE(Mode) \ 325 #define CASE(Mode) \
311 case SkXfermode::k##Mode##_Mode: \ 326 case SkXfermode::k##Mode##_Mode: return new Sk4fXfermode(rec, mode, &Mode)
312 return new SkPMFloatXfermode(rec, mode, &Mode)
313 CASE(ColorDodge); 327 CASE(ColorDodge);
314 CASE(ColorBurn); 328 CASE(ColorBurn);
315 CASE(SoftLight); 329 CASE(SoftLight);
316 #undef CASE 330 #undef CASE
317 331
318 default: break; 332 default: break;
319 } 333 }
320 return nullptr; 334 return nullptr;
321 } 335 }
322 336
323 } // namespace SK_OPTS_NS 337 } // namespace SK_OPTS_NS
324 338
325 #endif//Sk4pxXfermode_DEFINED 339 #endif//Sk4pxXfermode_DEFINED
OLDNEW
« no previous file with comments | « src/effects/SkColorMatrixFilter.cpp ('k') | tests/PMFloatTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698