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

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

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

Powered by Google App Engine
This is Rietveld 408576698