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