1 /*
2 * Copyright 2015 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 "GrFragmentProcessor.h"
9 #include "GrCoordTransform.h"
10 #include "GrPipeline.h"
11 #include "GrProcessorAnalysis.h"
12 #include "effects/GrConstColorProcessor.h"
13 #include "effects/GrXfermodeFragmentProcessor.h"
14 #include "glsl/GrGLSLFragmentProcessor.h"
15 #include "glsl/GrGLSLFragmentShaderBuilder.h"
16 #include "glsl/GrGLSLProgramDataManager.h"
17 #include "glsl/GrGLSLUniformHandler.h"
18
~GrFragmentProcessor()19 GrFragmentProcessor::~GrFragmentProcessor() {
20 // If we got here then our ref count must have reached zero, so we will have converted refs
21 // to pending executions for all children.
22 for (int i = 0; i < fChildProcessors.count(); ++i) {
23 fChildProcessors[i]->completedExecution();
24 }
25 }
26
isEqual(const GrFragmentProcessor & that) const27 bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const {
28 if (this->classID() != that.classID() ||
29 !this->hasSameSamplersAndAccesses(that)) {
30 return false;
31 }
32 if (!this->hasSameTransforms(that)) {
33 return false;
34 }
35 if (!this->onIsEqual(that)) {
36 return false;
37 }
38 if (this->numChildProcessors() != that.numChildProcessors()) {
39 return false;
40 }
41 for (int i = 0; i < this->numChildProcessors(); ++i) {
42 if (!this->childProcessor(i).isEqual(that.childProcessor(i))) {
43 return false;
44 }
45 }
46 return true;
47 }
48
createGLSLInstance() const49 GrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const {
50 GrGLSLFragmentProcessor* glFragProc = this->onCreateGLSLInstance();
51 glFragProc->fChildProcessors.push_back_n(fChildProcessors.count());
52 for (int i = 0; i < fChildProcessors.count(); ++i) {
53 glFragProc->fChildProcessors[i] = fChildProcessors[i]->createGLSLInstance();
54 }
55 return glFragProc;
56 }
57
addCoordTransform(const GrCoordTransform * transform)58 void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
59 fCoordTransforms.push_back(transform);
60 fFlags |= kUsesLocalCoords_Flag;
61 SkDEBUGCODE(transform->setInProcessor();)
62 }
63
instantiate(GrResourceProvider * resourceProvider) const64 bool GrFragmentProcessor::instantiate(GrResourceProvider* resourceProvider) const {
65 if (!INHERITED::instantiate(resourceProvider)) {
66 return false;
67 }
68
69 for (int i = 0; i < this->numChildProcessors(); ++i) {
70 if (!this->childProcessor(i).instantiate(resourceProvider)) {
71 return false;
72 }
73 }
74
75 return true;
76 }
77
registerChildProcessor(sk_sp<GrFragmentProcessor> child)78 int GrFragmentProcessor::registerChildProcessor(sk_sp<GrFragmentProcessor> child) {
79 this->combineRequiredFeatures(*child);
80
81 if (child->usesLocalCoords()) {
82 fFlags |= kUsesLocalCoords_Flag;
83 }
84
85 int index = fChildProcessors.count();
86 fChildProcessors.push_back(child.release());
87
88 return index;
89 }
90
notifyRefCntIsZero() const91 void GrFragmentProcessor::notifyRefCntIsZero() const {
92 // See comment above GrProgramElement for a detailed explanation of why we do this.
93 for (int i = 0; i < fChildProcessors.count(); ++i) {
94 fChildProcessors[i]->addPendingExecution();
95 fChildProcessors[i]->unref();
96 }
97 }
98
hasSameTransforms(const GrFragmentProcessor & that) const99 bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const {
100 if (this->numCoordTransforms() != that.numCoordTransforms()) {
101 return false;
102 }
103 int count = this->numCoordTransforms();
104 for (int i = 0; i < count; ++i) {
105 if (!this->coordTransform(i).hasSameEffectAs(that.coordTransform(i))) {
106 return false;
107 }
108 }
109 return true;
110 }
111
MulOutputByInputAlpha(sk_sp<GrFragmentProcessor> fp)112 sk_sp<GrFragmentProcessor> GrFragmentProcessor::MulOutputByInputAlpha(
113 sk_sp<GrFragmentProcessor> fp) {
114 if (!fp) {
115 return nullptr;
116 }
117 return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kDstIn);
118 }
119
120 namespace {
121
122 class PremulInputFragmentProcessor : public GrFragmentProcessor {
123 public:
Make()124 static sk_sp<GrFragmentProcessor> Make() {
125 return sk_sp<GrFragmentProcessor>(new PremulInputFragmentProcessor);
126 }
127
name() const128 const char* name() const override { return "PremultiplyInput"; }
129
130 private:
PremulInputFragmentProcessor()131 PremulInputFragmentProcessor()
132 : INHERITED(kPreservesOpaqueInput_OptimizationFlag |
133 kConstantOutputForConstantInput_OptimizationFlag) {
134 this->initClassID<PremulInputFragmentProcessor>();
135 }
136
onCreateGLSLInstance() const137 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
138 class GLFP : public GrGLSLFragmentProcessor {
139 public:
140 void emitCode(EmitArgs& args) override {
141 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
142
143 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor);
144 fragBuilder->codeAppendf("%s.rgb *= %s.a;",
145 args.fOutputColor, args.fInputColor);
146 }
147 };
148 return new GLFP;
149 }
150
onGetGLSLProcessorKey(const GrShaderCaps &,GrProcessorKeyBuilder *) const151 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
152
onIsEqual(const GrFragmentProcessor &) const153 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
154
constantOutputForConstantInput(GrColor4f input) const155 GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
156 return input.premul();
157 }
158
159 typedef GrFragmentProcessor INHERITED;
160 };
161
162 class UnpremulInputFragmentProcessor : public GrFragmentProcessor {
163 public:
Make()164 static sk_sp<GrFragmentProcessor> Make() {
165 return sk_sp<GrFragmentProcessor>(new UnpremulInputFragmentProcessor);
166 }
167
name() const168 const char* name() const override { return "UnpremultiplyInput"; }
169
170 private:
UnpremulInputFragmentProcessor()171 UnpremulInputFragmentProcessor()
172 : INHERITED(kPreservesOpaqueInput_OptimizationFlag |
173 kConstantOutputForConstantInput_OptimizationFlag) {
174 this->initClassID<UnpremulInputFragmentProcessor>();
175 }
176
onCreateGLSLInstance() const177 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
178 class GLFP : public GrGLSLFragmentProcessor {
179 public:
180 void emitCode(EmitArgs& args) override {
181 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
182
183 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor);
184 fragBuilder->codeAppendf("float invAlpha = %s.a <= 0.0 ? 0.0 : 1.0 / %s.a;",
185 args.fInputColor, args.fInputColor);
186 fragBuilder->codeAppendf("%s.rgb *= invAlpha;", args.fOutputColor);
187 }
188 };
189 return new GLFP;
190 }
191
onGetGLSLProcessorKey(const GrShaderCaps &,GrProcessorKeyBuilder *) const192 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
193
onIsEqual(const GrFragmentProcessor &) const194 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
195
constantOutputForConstantInput(GrColor4f input) const196 GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
197 return input.unpremul();
198 }
199
200 typedef GrFragmentProcessor INHERITED;
201 };
202
203 }
204
PremulInput(sk_sp<GrFragmentProcessor> fp)205 sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulInput(sk_sp<GrFragmentProcessor> fp) {
206 if (!fp) {
207 return nullptr;
208 }
209 sk_sp<GrFragmentProcessor> fpPipeline[] = { PremulInputFragmentProcessor::Make(), fp};
210 return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
211 }
212
PremulOutput(sk_sp<GrFragmentProcessor> fp)213 sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulOutput(sk_sp<GrFragmentProcessor> fp) {
214 if (!fp) {
215 return nullptr;
216 }
217 sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, PremulInputFragmentProcessor::Make() };
218 return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
219 }
220
UnpremulOutput(sk_sp<GrFragmentProcessor> fp)221 sk_sp<GrFragmentProcessor> GrFragmentProcessor::UnpremulOutput(sk_sp<GrFragmentProcessor> fp) {
222 if (!fp) {
223 return nullptr;
224 }
225 sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, UnpremulInputFragmentProcessor::Make() };
226 return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
227 }
228
SwizzleOutput(sk_sp<GrFragmentProcessor> fp,const GrSwizzle & swizzle)229 sk_sp<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(sk_sp<GrFragmentProcessor> fp,
230 const GrSwizzle& swizzle) {
231 class SwizzleFragmentProcessor : public GrFragmentProcessor {
232 public:
233 static sk_sp<GrFragmentProcessor> Make(const GrSwizzle& swizzle) {
234 return sk_sp<GrFragmentProcessor>(new SwizzleFragmentProcessor(swizzle));
235 }
236
237 const char* name() const override { return "Swizzle"; }
238 const GrSwizzle& swizzle() const { return fSwizzle; }
239
240 private:
241 SwizzleFragmentProcessor(const GrSwizzle& swizzle)
242 : INHERITED(kAll_OptimizationFlags)
243 , fSwizzle(swizzle) {
244 this->initClassID<SwizzleFragmentProcessor>();
245 }
246
247 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
248 class GLFP : public GrGLSLFragmentProcessor {
249 public:
250 void emitCode(EmitArgs& args) override {
251 const SwizzleFragmentProcessor& sfp = args.fFp.cast<SwizzleFragmentProcessor>();
252 const GrSwizzle& swizzle = sfp.swizzle();
253 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
254
255 fragBuilder->codeAppendf("%s = %s.%s;",
256 args.fOutputColor, args.fInputColor, swizzle.c_str());
257 }
258 };
259 return new GLFP;
260 }
261
262 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
263 b->add32(fSwizzle.asKey());
264 }
265
266 bool onIsEqual(const GrFragmentProcessor& other) const override {
267 const SwizzleFragmentProcessor& sfp = other.cast<SwizzleFragmentProcessor>();
268 return fSwizzle == sfp.fSwizzle;
269 }
270
271 GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
272 return fSwizzle.applyTo(input);
273 }
274
275 GrSwizzle fSwizzle;
276
277 typedef GrFragmentProcessor INHERITED;
278 };
279
280 if (!fp) {
281 return nullptr;
282 }
283 if (GrSwizzle::RGBA() == swizzle) {
284 return fp;
285 }
286 sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, SwizzleFragmentProcessor::Make(swizzle) };
287 return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
288 }
289
MakeInputPremulAndMulByOutput(sk_sp<GrFragmentProcessor> fp)290 sk_sp<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput(
291 sk_sp<GrFragmentProcessor> fp) {
292
293 class PremulFragmentProcessor : public GrFragmentProcessor {
294 public:
295 static sk_sp<GrFragmentProcessor> Make(sk_sp<GrFragmentProcessor> processor) {
296 return sk_sp<GrFragmentProcessor>(new PremulFragmentProcessor(std::move(processor)));
297 }
298
299 const char* name() const override { return "Premultiply"; }
300
301 private:
302 PremulFragmentProcessor(sk_sp<GrFragmentProcessor> processor)
303 : INHERITED(OptFlags(processor.get())) {
304 this->initClassID<PremulFragmentProcessor>();
305 this->registerChildProcessor(processor);
306 }
307
308 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
309 class GLFP : public GrGLSLFragmentProcessor {
310 public:
311 void emitCode(EmitArgs& args) override {
312 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
313 this->emitChild(0, args);
314 fragBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor,
315 args.fInputColor);
316 fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
317 }
318 };
319 return new GLFP;
320 }
321
322 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
323
324 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
325
326 static OptimizationFlags OptFlags(const GrFragmentProcessor* inner) {
327 OptimizationFlags flags = kNone_OptimizationFlags;
328 if (inner->preservesOpaqueInput()) {
329 flags |= kPreservesOpaqueInput_OptimizationFlag;
330 }
331 if (inner->hasConstantOutputForConstantInput()) {
332 flags |= kConstantOutputForConstantInput_OptimizationFlag;
333 }
334 return flags;
335 }
336
337 GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
338 GrColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0),
339 GrColor4f::OpaqueWhite());
340 return GrColor4f(input.fRGBA[3] * input.fRGBA[0] * childColor.fRGBA[0],
341 input.fRGBA[3] * input.fRGBA[1] * childColor.fRGBA[1],
342 input.fRGBA[3] * input.fRGBA[2] * childColor.fRGBA[2],
343 input.fRGBA[3] * childColor.fRGBA[3]);
344 }
345
346 typedef GrFragmentProcessor INHERITED;
347 };
348 if (!fp) {
349 return nullptr;
350 }
351 return PremulFragmentProcessor::Make(std::move(fp));
352 }
353
354 //////////////////////////////////////////////////////////////////////////////
355
OverrideInput(sk_sp<GrFragmentProcessor> fp,GrColor4f color)356 sk_sp<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(sk_sp<GrFragmentProcessor> fp,
357 GrColor4f color) {
358 class ReplaceInputFragmentProcessor : public GrFragmentProcessor {
359 public:
360 static sk_sp<GrFragmentProcessor> Make(sk_sp<GrFragmentProcessor> child, GrColor4f color) {
361 return sk_sp<GrFragmentProcessor>(new ReplaceInputFragmentProcessor(std::move(child),
362 color));
363 }
364
365 const char* name() const override { return "Replace Color"; }
366
367 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
368 class GLFP : public GrGLSLFragmentProcessor {
369 public:
370 GLFP() : fHaveSetColor(false) {}
371 void emitCode(EmitArgs& args) override {
372 const char* colorName;
373 fColorUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
374 kVec4f_GrSLType,
375 kDefault_GrSLPrecision,
376 "Color", &colorName);
377 this->emitChild(0, colorName, args);
378 }
379
380 private:
381 void onSetData(const GrGLSLProgramDataManager& pdman,
382 const GrFragmentProcessor& fp) override {
383 GrColor4f color = fp.cast<ReplaceInputFragmentProcessor>().fColor;
384 if (!fHaveSetColor || color != fPreviousColor) {
385 pdman.set4fv(fColorUni, 1, color.fRGBA);
386 fPreviousColor = color;
387 fHaveSetColor = true;
388 }
389 }
390
391 GrGLSLProgramDataManager::UniformHandle fColorUni;
392 bool fHaveSetColor;
393 GrColor4f fPreviousColor;
394 };
395
396 return new GLFP;
397 }
398
399 private:
400 ReplaceInputFragmentProcessor(sk_sp<GrFragmentProcessor> child, GrColor4f color)
401 : INHERITED(OptFlags(child.get(), color)), fColor(color) {
402 this->initClassID<ReplaceInputFragmentProcessor>();
403 this->registerChildProcessor(std::move(child));
404 }
405
406 static OptimizationFlags OptFlags(const GrFragmentProcessor* child, GrColor4f color) {
407 OptimizationFlags childFlags = child->optimizationFlags();
408 OptimizationFlags flags = kNone_OptimizationFlags;
409 if (childFlags & kConstantOutputForConstantInput_OptimizationFlag) {
410 flags |= kConstantOutputForConstantInput_OptimizationFlag;
411 }
412 if ((childFlags & kPreservesOpaqueInput_OptimizationFlag) && color.isOpaque()) {
413 flags |= kPreservesOpaqueInput_OptimizationFlag;
414 }
415 return flags;
416 }
417
418 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override
419 {}
420
421 bool onIsEqual(const GrFragmentProcessor& that) const override {
422 return fColor == that.cast<ReplaceInputFragmentProcessor>().fColor;
423 }
424
425 GrColor4f constantOutputForConstantInput(GrColor4f) const override {
426 return ConstantOutputForConstantInput(this->childProcessor(0), fColor);
427 }
428
429 GrColor4f fColor;
430
431 typedef GrFragmentProcessor INHERITED;
432 };
433
434 if (!fp) {
435 return nullptr;
436 }
437 return ReplaceInputFragmentProcessor::Make(std::move(fp), color);
438 }
439
RunInSeries(sk_sp<GrFragmentProcessor> * series,int cnt)440 sk_sp<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(sk_sp<GrFragmentProcessor>* series,
441 int cnt) {
442 class SeriesFragmentProcessor : public GrFragmentProcessor {
443 public:
444 static sk_sp<GrFragmentProcessor> Make(sk_sp<GrFragmentProcessor>* children, int cnt) {
445 return sk_sp<GrFragmentProcessor>(new SeriesFragmentProcessor(children, cnt));
446 }
447
448 const char* name() const override { return "Series"; }
449
450 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
451 class GLFP : public GrGLSLFragmentProcessor {
452 public:
453 void emitCode(EmitArgs& args) override {
454 // First guy's input might be nil.
455 SkString temp("out0");
456 this->emitChild(0, args.fInputColor, &temp, args);
457 SkString input = temp;
458 for (int i = 1; i < this->numChildProcessors() - 1; ++i) {
459 temp.printf("out%d", i);
460 this->emitChild(i, input.c_str(), &temp, args);
461 input = temp;
462 }
463 // Last guy writes to our output variable.
464 this->emitChild(this->numChildProcessors() - 1, input.c_str(), args);
465 }
466 };
467 return new GLFP;
468 }
469 private:
470 SeriesFragmentProcessor(sk_sp<GrFragmentProcessor>* children, int cnt)
471 : INHERITED(OptFlags(children, cnt)) {
472 SkASSERT(cnt > 1);
473 this->initClassID<SeriesFragmentProcessor>();
474 for (int i = 0; i < cnt; ++i) {
475 this->registerChildProcessor(std::move(children[i]));
476 }
477 }
478
479 static OptimizationFlags OptFlags(sk_sp<GrFragmentProcessor>* children, int cnt) {
480 OptimizationFlags flags = kAll_OptimizationFlags;
481 for (int i = 0; i < cnt && flags != kNone_OptimizationFlags; ++i) {
482 flags &= children[i]->optimizationFlags();
483 }
484 return flags;
485 }
486 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
487
488 bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
489
490 GrColor4f constantOutputForConstantInput(GrColor4f color) const override {
491 int childCnt = this->numChildProcessors();
492 for (int i = 0; i < childCnt; ++i) {
493 color = ConstantOutputForConstantInput(this->childProcessor(i), color);
494 }
495 return color;
496 }
497
498 typedef GrFragmentProcessor INHERITED;
499 };
500
501 if (!cnt) {
502 return nullptr;
503 }
504 if (1 == cnt) {
505 return series[0];
506 }
507 // Run the through the series, do the invariant output processing, and look for eliminations.
508 GrColorFragmentProcessorAnalysis info;
509 info.analyzeProcessors(sk_sp_address_as_pointer_address(series), cnt);
510 SkTArray<sk_sp<GrFragmentProcessor>> replacementSeries;
511 GrColor4f knownColor;
512 int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
513 if (leadingFPsToEliminate) {
514 sk_sp<GrFragmentProcessor> colorFP(
515 GrConstColorProcessor::Make(knownColor, GrConstColorProcessor::kIgnore_InputMode));
516 if (leadingFPsToEliminate == cnt) {
517 return colorFP;
518 }
519 cnt = cnt - leadingFPsToEliminate + 1;
520 replacementSeries.reserve(cnt);
521 replacementSeries.emplace_back(std::move(colorFP));
522 for (int i = 0; i < cnt - 1; ++i) {
523 replacementSeries.emplace_back(std::move(series[leadingFPsToEliminate + i]));
524 }
525 series = replacementSeries.begin();
526 }
527 return SeriesFragmentProcessor::Make(series, cnt);
528 }
529
530 //////////////////////////////////////////////////////////////////////////////
531
Iter(const GrPipeline & pipeline)532 GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) {
533 for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) {
534 fFPStack.push_back(&pipeline.getFragmentProcessor(i));
535 }
536 }
537
next()538 const GrFragmentProcessor* GrFragmentProcessor::Iter::next() {
539 if (fFPStack.empty()) {
540 return nullptr;
541 }
542 const GrFragmentProcessor* back = fFPStack.back();
543 fFPStack.pop_back();
544 for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
545 fFPStack.push_back(&back->childProcessor(i));
546 }
547 return back;
548 }
549
550