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

Side by Side Diff: src/core/Sk4pxXfermode.h

Issue 1241683003: Fix buggy blend modes. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 5 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 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 // There's no chance of underflow, and if we subtract m before adding s+d, n o overflow. 55 // There's no chance of underflow, and if we subtract m before adding s+d, n o overflow.
56 return (s - m) + (d - m.zeroAlphas()); 56 return (s - m) + (d - m.zeroAlphas());
57 } 57 }
58 // [ Sa + Da - Sa*Da, Sc + Dc - 2*Sc*Dc ] 58 // [ Sa + Da - Sa*Da, Sc + Dc - 2*Sc*Dc ]
59 XFERMODE(Exclusion) { 59 XFERMODE(Exclusion) {
60 auto p = s.approxMulDiv255(d); 60 auto p = s.approxMulDiv255(d);
61 // There's no chance of underflow, and if we subtract p before adding src+ds t, no overflow. 61 // There's no chance of underflow, and if we subtract p before adding src+ds t, no overflow.
62 return (s - p) + (d - p.zeroAlphas()); 62 return (s - p) + (d - p.zeroAlphas());
63 } 63 }
64 64
65 // We take care to use exact math for these next few modes where alphas
66 // and colors are calculated using significantly different math. We need
67 // to preserve premul invariants, and exact math makes this easier.
68 //
69 // TODO: Some of these implementations might be able to be sped up a bit
70 // while maintaining exact math, but let's follow up with that.
71
65 XFERMODE(HardLight) { 72 XFERMODE(HardLight) {
66 auto alphas = SrcOver::Xfer(s,d);
67
68 auto sa = s.alphas(), 73 auto sa = s.alphas(),
69 da = d.alphas(); 74 da = d.alphas();
70 75
76 auto srcover = s + (d * sa.inv()).div255();
77
71 auto isLite = ((sa-s) < s).widenLoHi(); 78 auto isLite = ((sa-s) < s).widenLoHi();
72 79
73 auto dark = s*d << 1, 80 auto lite = sa*da - ((da-d)*(sa-s) << 1),
74 lite = sa*da - ((da-d)*(sa-s) << 1), 81 dark = s*d << 1,
75 both = s*da.inv() + d*sa.inv(); 82 both = s*da.inv() + d*sa.inv();
76 83
84 auto alphas = srcover;
77 auto colors = (both + isLite.thenElse(lite, dark)).div255(); 85 auto colors = (both + isLite.thenElse(lite, dark)).div255();
78 return alphas.zeroColors() + colors.zeroAlphas(); 86 return alphas.zeroColors() + colors.zeroAlphas();
79 } 87 }
80 XFERMODE(Overlay) { return HardLight::Xfer(d,s); } 88 XFERMODE(Overlay) { return HardLight::Xfer(d,s); }
81 89
82 XFERMODE(Darken) { 90 XFERMODE(Darken) {
83 auto sda = s.approxMulDiv255(d.alphas()), 91 auto sa = s.alphas(),
84 dsa = d.approxMulDiv255(s.alphas()); 92 da = d.alphas();
85 auto srcover = s + (d - dsa), 93
86 dstover = d + (s - sda); 94 auto sda = (s*da).div255(),
95 dsa = (d*sa).div255();
96
97 auto srcover = s + (d * sa.inv()).div255(),
98 dstover = d + (s * da.inv()).div255();
87 auto alphas = srcover, 99 auto alphas = srcover,
88 colors = (sda < dsa).thenElse(srcover, dstover); 100 colors = (sda < dsa).thenElse(srcover, dstover);
89 return alphas.zeroColors() + colors.zeroAlphas(); 101 return alphas.zeroColors() + colors.zeroAlphas();
90 } 102 }
91 XFERMODE(Lighten) { 103 XFERMODE(Lighten) {
92 auto sda = s.approxMulDiv255(d.alphas()), 104 auto sa = s.alphas(),
93 dsa = d.approxMulDiv255(s.alphas()); 105 da = d.alphas();
94 auto srcover = s + (d - dsa), 106
95 dstover = d + (s - sda); 107 auto sda = (s*da).div255(),
108 dsa = (d*sa).div255();
109
110 auto srcover = s + (d * sa.inv()).div255(),
111 dstover = d + (s * da.inv()).div255();
96 auto alphas = srcover, 112 auto alphas = srcover,
97 colors = (dsa < sda).thenElse(srcover, dstover); 113 colors = (dsa < sda).thenElse(srcover, dstover);
98 return alphas.zeroColors() + colors.zeroAlphas(); 114 return alphas.zeroColors() + colors.zeroAlphas();
99 } 115 }
100 #undef XFERMODE 116 #undef XFERMODE
101 117
102 // Some xfermodes use math like divide or sqrt that's best done in floats 1 pixe l at a time. 118 // Some xfermodes use math like divide or sqrt that's best done in floats 1 pixe l at a time.
103 #define XFERMODE(Name) \ 119 #define XFERMODE(Name) \
104 struct Name { \ 120 struct Name { \
105 static SkPMFloat Xfer(const SkPMFloat&, const SkPMFloat&); \ 121 static SkPMFloat Xfer(const SkPMFloat&, const SkPMFloat&); \
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 #endif 287 #endif
272 default: break; 288 default: break;
273 } 289 }
274 #endif 290 #endif
275 return nullptr; 291 return nullptr;
276 } 292 }
277 293
278 } // namespace 294 } // namespace
279 295
280 #endif//Sk4pxXfermode_DEFINED 296 #endif//Sk4pxXfermode_DEFINED
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