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