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

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

Issue 1202013002: Update some Sk4px APIs. (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: fix none Created 5 years, 6 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/core/Sk4px.h ('k') | src/core/SkBlitRow_D32.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 12
13 // This file is possibly included into multiple .cpp files. 13 // This file is possibly included into multiple .cpp files.
14 // Each gets its own independent instantiation by wrapping in an anonymous names pace. 14 // Each gets its own independent instantiation by wrapping in an anonymous names pace.
15 namespace { 15 namespace {
16 16
17 #define XFERMODE(Name) \ 17 #define XFERMODE(Name) \
18 struct Name { \ 18 struct Name { \
19 static Sk4px Xfer(const Sk4px&, const Sk4px&); \ 19 static Sk4px Xfer(const Sk4px&, const Sk4px&); \
20 static const SkXfermode::Mode kMode = SkXfermode::k##Name##_Mode; \ 20 static const SkXfermode::Mode kMode = SkXfermode::k##Name##_Mode; \
21 }; \ 21 }; \
22 inline Sk4px Name::Xfer(const Sk4px& s, const Sk4px& d) 22 inline Sk4px Name::Xfer(const Sk4px& s, const Sk4px& d)
23 23
24 XFERMODE(Clear) { return Sk4px((SkPMColor)0); } 24 XFERMODE(Clear) { return Sk4px::DupPMColor(0); }
25 XFERMODE(Src) { return s; } 25 XFERMODE(Src) { return s; }
26 XFERMODE(Dst) { return d; } 26 XFERMODE(Dst) { return d; }
27 XFERMODE(SrcIn) { return s.fastMulDiv255Round(d.alphas() ); } 27 XFERMODE(SrcIn) { return s.approxMulDiv255(d.alphas() ); }
28 XFERMODE(SrcOut) { return s.fastMulDiv255Round(d.alphas().inv()); } 28 XFERMODE(SrcOut) { return s.approxMulDiv255(d.alphas().inv()); }
29 XFERMODE(SrcOver) { return s + d.fastMulDiv255Round(s.alphas().inv()); } 29 XFERMODE(SrcOver) { return s + d.approxMulDiv255(s.alphas().inv()); }
30 XFERMODE(DstIn) { return SrcIn ::Xfer(d,s); } 30 XFERMODE(DstIn) { return SrcIn ::Xfer(d,s); }
31 XFERMODE(DstOut) { return SrcOut ::Xfer(d,s); } 31 XFERMODE(DstOut) { return SrcOut ::Xfer(d,s); }
32 XFERMODE(DstOver) { return SrcOver::Xfer(d,s); } 32 XFERMODE(DstOver) { return SrcOver::Xfer(d,s); }
33 33
34 // [ S * Da + (1 - Sa) * D] 34 // [ S * Da + (1 - Sa) * D]
35 XFERMODE(SrcATop) { 35 XFERMODE(SrcATop) { return (s * d.alphas() + d * s.alphas().inv()).div255(); }
36 return Sk4px::Wide(s.mulWiden(d.alphas()) + d.mulWiden(s.alphas().inv()))
37 .div255RoundNarrow();
38 }
39 XFERMODE(DstATop) { return SrcATop::Xfer(d,s); } 36 XFERMODE(DstATop) { return SrcATop::Xfer(d,s); }
40 //[ S * (1 - Da) + (1 - Sa) * D ] 37 //[ S * (1 - Da) + (1 - Sa) * D ]
41 XFERMODE(Xor) { 38 XFERMODE(Xor) { return (s * d.alphas().inv() + d * s.alphas().inv()).div255(); }
42 return Sk4px::Wide(s.mulWiden(d.alphas().inv()) + d.mulWiden(s.alphas().inv( )))
43 .div255RoundNarrow();
44 }
45 // [S + D ] 39 // [S + D ]
46 XFERMODE(Plus) { return s.saturatedAdd(d); } 40 XFERMODE(Plus) { return s.saturatedAdd(d); }
47 // [S * D ] 41 // [S * D ]
48 XFERMODE(Modulate) { return s.fastMulDiv255Round(d); } 42 XFERMODE(Modulate) { return s.approxMulDiv255(d); }
49 // [S + D - S * D] 43 // [S + D - S * D]
50 XFERMODE(Screen) { 44 XFERMODE(Screen) {
51 // Doing the math as S + (1-S)*D or S + (D - S*D) means the add and subtract can be done 45 // Doing the math as S + (1-S)*D or S + (D - S*D) means the add and subtract can be done
52 // in 8-bit space without overflow. S + (1-S)*D is a touch faster because i nv() is cheap. 46 // in 8-bit space without overflow. S + (1-S)*D is a touch faster because i nv() is cheap.
53 return s + d.fastMulDiv255Round(s.inv()); 47 return s + d.approxMulDiv255(s.inv());
54 } 48 }
55 XFERMODE(Multiply) { 49 XFERMODE(Multiply) { return (s * d.alphas().inv() + d * s.alphas().inv() + s*d). div255(); }
56 return Sk4px::Wide(s.mulWiden(d.alphas().inv()) +
57 d.mulWiden(s.alphas().inv()) +
58 s.mulWiden(d))
59 .div255RoundNarrow();
60 }
61 // [ Sa + Da - Sa*Da, Sc + Dc - 2*min(Sc*Da, Dc*Sa) ] (And notice Sa*Da == min( Sa*Da, Da*Sa).) 50 // [ Sa + Da - Sa*Da, Sc + Dc - 2*min(Sc*Da, Dc*Sa) ] (And notice Sa*Da == min( Sa*Da, Da*Sa).)
62 XFERMODE(Difference) { 51 XFERMODE(Difference) {
63 auto m = Sk4px::Wide(Sk16h::Min(s.mulWiden(d.alphas()), d.mulWiden(s.alphas( )))) 52 auto m = Sk4px::Wide::Min(s * d.alphas(), d * s.alphas()).div255();
64 .div255RoundNarrow();
65 // There's no chance of underflow, and if we subtract m before adding s+d, n o overflow. 53 // There's no chance of underflow, and if we subtract m before adding s+d, n o overflow.
66 return (s - m) + (d - m.zeroAlphas()); 54 return (s - m) + (d - m.zeroAlphas());
67 } 55 }
68 // [ Sa + Da - Sa*Da, Sc + Dc - 2*Sc*Dc ] 56 // [ Sa + Da - Sa*Da, Sc + Dc - 2*Sc*Dc ]
69 XFERMODE(Exclusion) { 57 XFERMODE(Exclusion) {
70 auto p = s.fastMulDiv255Round(d); 58 auto p = s.approxMulDiv255(d);
71 // There's no chance of underflow, and if we subtract p before adding src+ds t, no overflow. 59 // There's no chance of underflow, and if we subtract p before adding src+ds t, no overflow.
72 return (s - p) + (d - p.zeroAlphas()); 60 return (s - p) + (d - p.zeroAlphas());
73 } 61 }
74 62
75 #undef XFERMODE 63 #undef XFERMODE
76 64
77 // A reasonable fallback mode for doing AA is to simply apply the transfermode f irst, 65 // A reasonable fallback mode for doing AA is to simply apply the transfermode f irst,
78 // then linearly interpolate the AA. 66 // then linearly interpolate the AA.
79 template <typename Mode> 67 template <typename Mode>
80 static Sk4px xfer_aa(const Sk4px& s, const Sk4px& d, const Sk16b& aa) { 68 static Sk4px xfer_aa(const Sk4px& s, const Sk4px& d, const Sk4px& aa) {
81 Sk4px noAA = Mode::Xfer(s, d); 69 Sk4px bw = Mode::Xfer(s, d);
82 return Sk4px::Wide(noAA.mulWiden(aa) + d.mulWiden(Sk4px(aa).inv())) 70 return (bw * aa + d * aa.inv()).div255();
83 .div255RoundNarrow();
84 } 71 }
85 72
86 // For some transfermodes we specialize AA, either for correctness or performanc e. 73 // For some transfermodes we specialize AA, either for correctness or performanc e.
87 #ifndef SK_NO_SPECIALIZED_AA_XFERMODES 74 #ifndef SK_NO_SPECIALIZED_AA_XFERMODES
88 #define XFERMODE_AA(Name) \ 75 #define XFERMODE_AA(Name) \
89 template <> Sk4px xfer_aa<Name>(const Sk4px& s, const Sk4px& d, const Sk 16b& aa) 76 template <> Sk4px xfer_aa<Name>(const Sk4px& s, const Sk4px& d, const Sk 4px& aa)
90 77
91 // Plus' clamp needs to happen after AA. skia:3852 78 // Plus' clamp needs to happen after AA. skia:3852
92 XFERMODE_AA(Plus) { // [ clamp( (1-AA)D + (AA)(S+D) ) == clamp(D + AA*S) ] 79 XFERMODE_AA(Plus) { // [ clamp( (1-AA)D + (AA)(S+D) ) == clamp(D + AA*S) ]
93 return d.saturatedAdd(s.fastMulDiv255Round(aa)); 80 return d.saturatedAdd(s.approxMulDiv255(aa));
94 } 81 }
95 82
96 #undef XFERMODE_AA 83 #undef XFERMODE_AA
97 #endif 84 #endif
98 85
99 template <typename ProcType> 86 template <typename ProcType>
100 class SkT4pxXfermode : public SkProcCoeffXfermode { 87 class SkT4pxXfermode : public SkProcCoeffXfermode {
101 public: 88 public:
102 static SkProcCoeffXfermode* Create(const ProcCoeff& rec) { 89 static SkProcCoeffXfermode* Create(const ProcCoeff& rec) {
103 return SkNEW_ARGS(SkT4pxXfermode, (rec)); 90 return SkNEW_ARGS(SkT4pxXfermode, (rec));
104 } 91 }
105 92
106 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[ ]) const override { 93 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[ ]) const override {
107 if (NULL == aa) { 94 if (NULL == aa) {
108 Sk4px::MapDstSrc(n, dst, src, [&](const Sk4px& dst4, const Sk4px& sr c4) { 95 Sk4px::MapDstSrc(n, dst, src, [&](const Sk4px& dst4, const Sk4px& sr c4) {
109 return ProcType::Xfer(src4, dst4); 96 return ProcType::Xfer(src4, dst4);
110 }); 97 });
111 } else { 98 } else {
112 Sk4px::MapDstSrcAlpha(n, dst, src, aa, 99 Sk4px::MapDstSrcAlpha(n, dst, src, aa,
113 [&](const Sk4px& dst4, const Sk4px& src4, const Sk16b& alpha ) { 100 [&](const Sk4px& dst4, const Sk4px& src4, const Sk4px& alpha ) {
114 return xfer_aa<ProcType>(src4, dst4, alpha); 101 return xfer_aa<ProcType>(src4, dst4, alpha);
115 }); 102 });
116 } 103 }
117 } 104 }
118 105
119 private: 106 private:
120 SkT4pxXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kM ode) {} 107 SkT4pxXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kM ode) {}
121 108
122 typedef SkProcCoeffXfermode INHERITED; 109 typedef SkProcCoeffXfermode INHERITED;
123 }; 110 };
(...skipping 21 matching lines...) Expand all
145 case SkXfermode::kExclusion_Mode: return SkT4pxXfermode<Exclusion>::Cre ate(rec); 132 case SkXfermode::kExclusion_Mode: return SkT4pxXfermode<Exclusion>::Cre ate(rec);
146 default: break; 133 default: break;
147 } 134 }
148 #endif 135 #endif
149 return nullptr; 136 return nullptr;
150 } 137 }
151 138
152 } // namespace 139 } // namespace
153 140
154 #endif//Sk4pxXfermode_DEFINED 141 #endif//Sk4pxXfermode_DEFINED
OLDNEW
« no previous file with comments | « src/core/Sk4px.h ('k') | src/core/SkBlitRow_D32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698