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

Side by Side Diff: src/effects/SkPixelXorXfermode.cpp

Issue 1644903004: Revert of Move SkPixelXorXfermode.h to include/client/android (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 10 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/android/effects/SkPixelXorXfermode.cpp ('k') | 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
(Empty)
1 /*
2 * Copyright 2011 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 "SkPixelXorXfermode.h"
9 #include "SkColorPriv.h"
10 #include "SkReadBuffer.h"
11 #include "SkWriteBuffer.h"
12 #include "SkString.h"
13
14 // we always return an opaque color, 'cause I don't know what to do with
15 // the alpha-component and still return a valid premultiplied color.
16 SkPMColor SkPixelXorXfermode::xferColor(SkPMColor src, SkPMColor dst) const {
17 SkPMColor res = src ^ dst ^ fOpColor;
18
19 res |= (SK_A32_MASK << SK_A32_SHIFT); // force it to be opaque
20 return res;
21 }
22
23 void SkPixelXorXfermode::flatten(SkWriteBuffer& wb) const {
24 wb.writeColor(SkColorSetRGB(SkGetPackedR32(fOpColor),
25 SkGetPackedG32(fOpColor),
26 SkGetPackedB32(fOpColor)));
27 }
28
29 SkFlattenable* SkPixelXorXfermode::CreateProc(SkReadBuffer& buffer) {
30 return Create(buffer.readColor());
31 }
32
33 #ifndef SK_IGNORE_TO_STRING
34 void SkPixelXorXfermode::toString(SkString* str) const {
35 str->append("SkPixelXorXfermode: ");
36 str->appendHex(fOpColor);
37 }
38 #endif
39
40 #if SK_SUPPORT_GPU
41 #include "GrFragmentProcessor.h"
42 #include "GrInvariantOutput.h"
43 #include "GrXferProcessor.h"
44
45 #include "glsl/GrGLSLFragmentProcessor.h"
46 #include "glsl/GrGLSLFragmentShaderBuilder.h"
47 #include "glsl/GrGLSLProgramDataManager.h"
48 #include "glsl/GrGLSLUniformHandler.h"
49 #include "glsl/GrGLSLXferProcessor.h"
50
51 ///////////////////////////////////////////////////////////////////////////////
52 // Fragment Processor
53 ///////////////////////////////////////////////////////////////////////////////
54
55 static void add_pixelxor_code(GrGLSLFragmentBuilder* fragBuilder,
56 const char* srcColor,
57 const char* dstColor,
58 const char* outputColor,
59 const char* opColor) {
60 static const GrGLSLShaderVar gXorArgs[] = {
61 GrGLSLShaderVar("f1", kFloat_GrSLType),
62 GrGLSLShaderVar("f2", kFloat_GrSLType),
63 GrGLSLShaderVar("f3", kFloat_GrSLType),
64 GrGLSLShaderVar("fPowerOf2Divisor", kFloat_GrSLType),
65 };
66 SkString xorFuncName;
67
68 // The xor function checks if the three passed in floats (f1, f2, f3) would
69 // have a bit in the log2(fPowerOf2Divisor)-th position if they were
70 // represented by an int. It then performs an xor of the 3 bits (using
71 // the property that serial xors can be treated as a sum of 0s & 1s mod 2).
72 fragBuilder->emitFunction(kFloat_GrSLType,
73 "xor",
74 SK_ARRAY_COUNT(gXorArgs),
75 gXorArgs,
76 "float bit1 = floor(f1 / fPowerOf2Divisor);"
77 "float bit2 = floor(f2 / fPowerOf2Divisor);"
78 "float bit3 = floor(f3 / fPowerOf2Divisor);"
79 "return mod(bit1 + bit2 + bit3, 2.0);",
80 &xorFuncName);
81
82 fragBuilder->codeAppend("float red = 0.0, green = 0.0, blue = 0.0;");
83
84 if (srcColor) {
85 fragBuilder->codeAppendf("vec3 src = 255.99 * %s.rgb;", srcColor);
86 } else {
87 fragBuilder->codeAppendf("vec3 src = vec3(255.99);");
88 }
89 fragBuilder->codeAppendf("vec3 dst = 255.99 * %s.rgb;", dstColor);
90 fragBuilder->codeAppendf("vec3 op = 255.99 * %s;", opColor);
91
92 fragBuilder->codeAppend("float modValue = 128.0;");
93
94 fragBuilder->codeAppend("for (int i = 0; i < 8; i++) {");
95
96 fragBuilder->codeAppendf("float bit = %s(src.r, dst.r, op.r, modValue);", xo rFuncName.c_str());
97 fragBuilder->codeAppend("red += modValue * bit;");
98 fragBuilder->codeAppend("src.r = mod(src.r, modValue);");
99 fragBuilder->codeAppend("dst.r = mod(dst.r, modValue);");
100 fragBuilder->codeAppend("op.r = mod(op.r, modValue);");
101
102 fragBuilder->codeAppendf("bit = %s(src.g, dst.g, op.g, modValue);", xorFuncN ame.c_str());
103 fragBuilder->codeAppend("green += modValue * bit;");
104 fragBuilder->codeAppend("src.g = mod(src.g, modValue);");
105 fragBuilder->codeAppend("dst.g = mod(dst.g, modValue);");
106 fragBuilder->codeAppend("op.g = mod(op.g, modValue);");
107
108 fragBuilder->codeAppendf("bit = %s(src.b, dst.b, op.b, modValue);", xorFuncN ame.c_str());
109 fragBuilder->codeAppend("blue += modValue * bit;");
110 fragBuilder->codeAppend("src.b = mod(src.b, modValue);");
111 fragBuilder->codeAppend("dst.b = mod(dst.b, modValue);");
112 fragBuilder->codeAppend("op.b = mod(op.b, modValue);");
113
114 fragBuilder->codeAppend("modValue /= 2.0;");
115
116 fragBuilder->codeAppend("}");
117
118 fragBuilder->codeAppendf("%s = vec4(red/255.0, green/255.0, blue/255.0, 1.0) ;", outputColor);
119 }
120
121 class GLPixelXorFP;
122
123 class PixelXorFP : public GrFragmentProcessor {
124 public:
125 static const GrFragmentProcessor* Create(SkPMColor opColor, const GrFragment Processor* dst) {
126 return new PixelXorFP(opColor, dst);
127 }
128
129 ~PixelXorFP() override {};
130
131 const char* name() const override { return "PixelXor"; }
132
133 SkString dumpInfo() const override {
134 SkString str;
135 str.appendf("Color: 0x%08x", fOpColor);
136 return str;
137 }
138
139 SkPMColor opColor() const { return fOpColor; }
140
141 private:
142 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
143
144 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
145
146 bool onIsEqual(const GrFragmentProcessor& fpBase) const override {
147 const PixelXorFP& fp = fpBase.cast<PixelXorFP>();
148 return fOpColor == fp.fOpColor;
149 }
150
151 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
152 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
153 }
154
155 PixelXorFP(SkPMColor opColor, const GrFragmentProcessor* dst)
156 : fOpColor(opColor) {
157 this->initClassID<PixelXorFP>();
158
159 SkASSERT(dst);
160 SkDEBUGCODE(int dstIndex = )this->registerChildProcessor(dst);
161 SkASSERT(0 == dstIndex);
162 }
163
164 SkPMColor fOpColor;
165
166 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
167 typedef GrFragmentProcessor INHERITED;
168 };
169
170 ///////////////////////////////////////////////////////////////////////////////
171
172 class GLPixelXorFP : public GrGLSLFragmentProcessor {
173 public:
174 GLPixelXorFP(const PixelXorFP&) {}
175
176 ~GLPixelXorFP() override {}
177
178 void emitCode(EmitArgs& args) override {
179 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
180 SkString dstColor("dstColor");
181 this->emitChild(0, nullptr, &dstColor, args);
182
183 fOpColorUni = args.fUniformHandler->addUniform(GrGLSLUniformHandler::kFr agment_Visibility,
184 kVec3f_GrSLType, kHigh_Gr SLPrecision,
185 "opColor");
186 const char* kOpColorUni = args.fUniformHandler->getUniformCStr(fOpColorU ni);
187
188 add_pixelxor_code(fragBuilder, args.fInputColor, dstColor.c_str(),
189 args.fOutputColor, kOpColorUni);
190 }
191
192 static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuil der*) { }
193
194 protected:
195 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& pro c) override {
196 const PixelXorFP& pixXor = proc.cast<PixelXorFP>();
197 pdman.set3f(fOpColorUni,
198 SkGetPackedR32(pixXor.opColor())/255.0f,
199 SkGetPackedG32(pixXor.opColor())/255.0f,
200 SkGetPackedB32(pixXor.opColor())/255.0f);
201 }
202
203 private:
204 GrGLSLProgramDataManager::UniformHandle fOpColorUni;
205
206 typedef GrGLSLFragmentProcessor INHERITED;
207 };
208
209 ///////////////////////////////////////////////////////////////////////////////
210
211 GrGLSLFragmentProcessor* PixelXorFP::onCreateGLSLInstance() const {
212 return new GLPixelXorFP(*this);
213 }
214
215 void PixelXorFP::onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBui lder* b) const {
216 GLPixelXorFP::GenKey(*this, caps, b);
217 }
218
219 const GrFragmentProcessor* PixelXorFP::TestCreate(GrProcessorTestData* d) {
220 SkColor color = d->fRandom->nextU();
221
222 SkAutoTUnref<const GrFragmentProcessor> dst(GrProcessorUnitTest::CreateChild FP(d));
223 return new PixelXorFP(SkPreMultiplyColor(color), dst);
224 }
225
226 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(PixelXorFP);
227
228 ///////////////////////////////////////////////////////////////////////////////
229 // Xfer Processor
230 ///////////////////////////////////////////////////////////////////////////////
231
232 class PixelXorXP : public GrXferProcessor {
233 public:
234 PixelXorXP(const DstTexture* dstTexture, bool hasMixedSamples, SkPMColor opC olor)
235 : INHERITED(dstTexture, true, hasMixedSamples)
236 , fOpColor(opColor) {
237 this->initClassID<PixelXorXP>();
238 }
239
240 const char* name() const override { return "PixelXor"; }
241
242 GrGLSLXferProcessor* createGLSLInstance() const override;
243
244 SkPMColor opColor() const { return fOpColor; }
245
246 private:
247 GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations& optimizations,
248 bool doesStencilWrite,
249 GrColor* overrideColor,
250 const GrCaps& caps) const overr ide {
251 return GrXferProcessor::kNone_OptFlags;
252 }
253
254 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
255
256 bool onIsEqual(const GrXferProcessor& xpBase) const override {
257 const PixelXorXP& xp = xpBase.cast<PixelXorXP>();
258
259 return fOpColor == xp.fOpColor;
260 }
261
262 SkPMColor fOpColor;
263
264 typedef GrXferProcessor INHERITED;
265 };
266
267 ///////////////////////////////////////////////////////////////////////////////
268
269 class GLPixelXorXP : public GrGLSLXferProcessor {
270 public:
271 GLPixelXorXP(const PixelXorXP& pixelXorXP) { }
272
273 ~GLPixelXorXP() override {}
274
275 static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuil der*) { }
276
277 private:
278 void emitBlendCodeForDstRead(GrGLSLXPFragmentBuilder* fragBuilder,
279 GrGLSLUniformHandler* uniformHandler,
280 const char* srcColor,
281 const char* srcCoverage,
282 const char* dstColor,
283 const char* outColor,
284 const char* outColorSecondary,
285 const GrXferProcessor& proc) override {
286 fOpColorUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment _Visibility,
287 kVec3f_GrSLType, kHigh_GrSLPrec ision,
288 "opColor");
289 const char* kOpColorUni = uniformHandler->getUniformCStr(fOpColorUni);
290
291 add_pixelxor_code(fragBuilder, srcColor, dstColor, outColor, kOpColorUni );
292
293 // Apply coverage.
294 INHERITED::DefaultCoverageModulation(fragBuilder, srcCoverage, dstColor, outColor,
295 outColorSecondary, proc);
296 }
297
298 void onSetData(const GrGLSLProgramDataManager& pdman,
299 const GrXferProcessor& processor) override {
300 const PixelXorXP& pixelXor = processor.cast<PixelXorXP>();
301 pdman.set3f(fOpColorUni,
302 SkGetPackedR32(pixelXor.opColor())/255.0f,
303 SkGetPackedG32(pixelXor.opColor())/255.0f,
304 SkGetPackedB32(pixelXor.opColor())/255.0f);
305 };
306
307 GrGLSLProgramDataManager::UniformHandle fOpColorUni;
308
309 typedef GrGLSLXferProcessor INHERITED;
310 };
311
312 ///////////////////////////////////////////////////////////////////////////////
313
314 void PixelXorXP::onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBui lder* b) const {
315 GLPixelXorXP::GenKey(*this, caps, b);
316 }
317
318 GrGLSLXferProcessor* PixelXorXP::createGLSLInstance() const { return new GLPixel XorXP(*this); }
319
320 ///////////////////////////////////////////////////////////////////////////////
321
322 class GrPixelXorXPFactory : public GrXPFactory {
323 public:
324 static GrXPFactory* Create(SkPMColor opColor) {
325 return new GrPixelXorXPFactory(opColor);
326 }
327
328 void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
329 GrXPFactory::InvariantBlendedColor* blendedCol or) const override {
330 blendedColor->fWillBlendWithDst = true;
331 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
332 }
333
334 private:
335 GrPixelXorXPFactory(SkPMColor opColor)
336 : fOpColor(opColor) {
337 this->initClassID<GrPixelXorXPFactory>();
338 }
339
340 GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
341 const GrPipelineOptimizations& optimi zations,
342 bool hasMixedSamples,
343 const DstTexture* dstTexture) const o verride {
344 return new PixelXorXP(dstTexture, hasMixedSamples, fOpColor);
345 }
346
347 bool willReadDstColor(const GrCaps& caps,
348 const GrPipelineOptimizations& optimizations,
349 bool hasMixedSamples) const override {
350 return true;
351 }
352
353 bool onIsEqual(const GrXPFactory& xpfBase) const override {
354 const GrPixelXorXPFactory& xpf = xpfBase.cast<GrPixelXorXPFactory>();
355 return fOpColor == xpf.fOpColor;
356 }
357
358 GR_DECLARE_XP_FACTORY_TEST;
359
360 SkPMColor fOpColor;
361
362 typedef GrXPFactory INHERITED;
363 };
364
365 GR_DEFINE_XP_FACTORY_TEST(GrPixelXorXPFactory);
366
367 const GrXPFactory* GrPixelXorXPFactory::TestCreate(GrProcessorTestData* d) {
368 SkColor color = d->fRandom->nextU();
369
370 return GrPixelXorXPFactory::Create(SkPreMultiplyColor(color));
371 }
372
373 ///////////////////////////////////////////////////////////////////////////////
374
375 bool SkPixelXorXfermode::asFragmentProcessor(const GrFragmentProcessor** output,
376 const GrFragmentProcessor* dst) con st {
377 if (output) {
378 *output = PixelXorFP::Create(fOpColor, dst);
379 }
380 return true;
381 }
382
383 bool SkPixelXorXfermode::asXPFactory(GrXPFactory** xpf) const {
384 if (xpf) {
385 *xpf = GrPixelXorXPFactory::Create(fOpColor);
386 }
387 return true;
388 }
389
390 #endif
OLDNEW
« no previous file with comments | « src/android/effects/SkPixelXorXfermode.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698