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