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