1/*
2 * Copyright 2014 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#ifndef GrFragmentProcessor_DEFINED
9#define GrFragmentProcessor_DEFINED
10
11#include <tuple>
12
13#include "include/private/SkSLSampleUsage.h"
14#include "src/gpu/GrProcessor.h"
15#include "src/gpu/ops/GrOp.h"
16
17class GrGLSLFragmentProcessor;
18class GrPaint;
19class GrPipeline;
20class GrProcessorKeyBuilder;
21class GrShaderCaps;
22class GrSwizzle;
23class GrTextureEffect;
24
25/** Provides custom fragment shader code. Fragment processors receive an input color (half4) and
26 produce an output color. They may reference textures and uniforms.
27 */
28class GrFragmentProcessor : public GrProcessor {
29public:
30 /**
31 * In many instances (e.g. SkShader::asFragmentProcessor() implementations) it is desirable to
32 * only consider the input color's alpha. However, there is a competing desire to have reusable
33 * GrFragmentProcessor subclasses that can be used in other scenarios where the entire input
34 * color is considered. This function exists to filter the input color and pass it to a FP. It
35 * does so by returning a parent FP that multiplies the passed in FPs output by the parent's
36 * input alpha. The passed in FP will not receive an input color.
37 */
38 static std::unique_ptr<GrFragmentProcessor> MulChildByInputAlpha(
39 std::unique_ptr<GrFragmentProcessor> child);
40
41 /**
42 * Like MulChildByInputAlpha(), but reverses the sense of src and dst. In this case, return
43 * the input modulated by the child's alpha. The passed in FP will not receive an input color.
44 *
45 * output = input * child.a
46 */
47 static std::unique_ptr<GrFragmentProcessor> MulInputByChildAlpha(
48 std::unique_ptr<GrFragmentProcessor> child);
49
50 /**
51 * Returns a fragment processor that generates the passed-in color, modulated by the child's
52 * alpha channel. (Pass a null FP to use the alpha from sk_InColor instead of a child FP.)
53 */
54 static std::unique_ptr<GrFragmentProcessor> ModulateAlpha(
55 std::unique_ptr<GrFragmentProcessor> child, const SkPMColor4f& color);
56
57 /**
58 * Returns a fragment processor that generates the passed-in color, modulated by the child's
59 * RGBA color. (Pass a null FP to use the color from sk_InColor instead of a child FP.)
60 */
61 static std::unique_ptr<GrFragmentProcessor> ModulateRGBA(
62 std::unique_ptr<GrFragmentProcessor> child, const SkPMColor4f& color);
63
64 /**
65 * This assumes that the input color to the returned processor will be unpremul and that the
66 * passed processor (which becomes the returned processor's child) produces a premul output.
67 * The result of the returned processor is a premul of its input color modulated by the child
68 * processor's premul output.
69 */
70 static std::unique_ptr<GrFragmentProcessor> MakeInputPremulAndMulByOutput(
71 std::unique_ptr<GrFragmentProcessor>);
72
73 /**
74 * Returns a parent fragment processor that adopts the passed fragment processor as a child.
75 * The parent will ignore its input color and instead feed the passed in color as input to the
76 * child.
77 */
78 static std::unique_ptr<GrFragmentProcessor> OverrideInput(std::unique_ptr<GrFragmentProcessor>,
79 const SkPMColor4f&,
80 bool useUniform = true);
81
82 /**
83 * Returns a fragment processor that premuls the input before calling the passed in fragment
84 * processor.
85 */
86 static std::unique_ptr<GrFragmentProcessor> PremulInput(std::unique_ptr<GrFragmentProcessor>);
87
88 /**
89 * Returns a fragment processor that calls the passed in fragment processor, and then swizzles
90 * the output.
91 */
92 static std::unique_ptr<GrFragmentProcessor> SwizzleOutput(std::unique_ptr<GrFragmentProcessor>,
93 const GrSwizzle&);
94
95 /**
96 * Returns a fragment processor that calls the passed in fragment processor, and then ensures
97 * the output is a valid premul color by clamping RGB to [0, A].
98 */
99 static std::unique_ptr<GrFragmentProcessor> ClampPremulOutput(
100 std::unique_ptr<GrFragmentProcessor>);
101
102 /**
103 * Returns a fragment processor that composes two fragment processors `f` and `g` into f(g(x)).
104 * This is equivalent to running them in series. This is not the same as transfer-mode
105 * composition; there is no blending step.
106 */
107 static std::unique_ptr<GrFragmentProcessor> Compose(std::unique_ptr<GrFragmentProcessor> f,
108 std::unique_ptr<GrFragmentProcessor> g);
109
110 /**
111 * Makes a copy of this fragment processor that draws equivalently to the original.
112 * If the processor has child processors they are cloned as well.
113 */
114 virtual std::unique_ptr<GrFragmentProcessor> clone() const = 0;
115
116 // The FP this was registered with as a child function. This will be null if this is a root.
117 const GrFragmentProcessor* parent() const { return fParent; }
118
119 GrGLSLFragmentProcessor* createGLSLInstance() const;
120
121 void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
122 this->onGetGLSLProcessorKey(caps, b);
123 for (const auto& child : fChildProcessors) {
124 if (child) {
125 child->getGLSLProcessorKey(caps, b);
126 }
127 }
128 }
129
130 int numVaryingCoordsUsed() const { return this->usesVaryingCoordsDirectly() ? 1 : 0; }
131
132 int numChildProcessors() const { return fChildProcessors.count(); }
133 int numNonNullChildProcessors() const;
134
135 GrFragmentProcessor* childProcessor(int index) { return fChildProcessors[index].get(); }
136 const GrFragmentProcessor* childProcessor(int index) const {
137 return fChildProcessors[index].get();
138 }
139
140 SkDEBUGCODE(bool isInstantiated() const;)
141
142 /**
143 * Does this FP require local coordinates to be produced by the primitive processor? This only
144 * returns true if this FP will directly read those local coordinates. FPs that are sampled
145 * explicitly do not require primitive-generated local coordinates (because the sample
146 * coordinates are supplied by the parent FP).
147 *
148 * If the root of an FP tree does not provide explicit coordinates, the geometry processor
149 * provides the original local coordinates to start. This may be implicit as part of vertex
150 * shader-lifted varyings, or by providing the base local coordinate to the fragment shader.
151 */
152 bool usesVaryingCoordsDirectly() const {
153 return SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag) &&
154 !SkToBool(fFlags & kSampledWithExplicitCoords_Flag);
155 }
156
157 /**
158 * Do any of the FPs in this tree require local coordinates to be produced by the primitive
159 * processor? This can return true even if this FP does not refer to sample coordinates, but
160 * true if a descendant FP uses them.
161 */
162 bool usesVaryingCoords() const {
163 return (SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag) ||
164 SkToBool(fFlags & kUsesSampleCoordsIndirectly_Flag)) &&
165 !SkToBool(fFlags & kSampledWithExplicitCoords_Flag);
166 }
167
168 /**
169 * True if this FP refers directly to the sample coordinate parameter of its function
170 * (e.g. uses EmitArgs::fSampleCoord in emitCode()). This also returns true if the
171 * coordinate reference comes from autogenerated code invoking 'sample(matrix)' expressions.
172 *
173 * Unlike usesVaryingCoords(), this can return true whether or not the FP is explicitly
174 * sampled, and does not change based on how the FP is composed. This property is specific to
175 * the FP's function and not the entire program.
176 */
177 bool referencesSampleCoords() const {
178 return SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag);
179 }
180
181 // True if this FP's parent invokes it with 'sample(float2)' or a variable 'sample(matrix)'
182 bool isSampledWithExplicitCoords() const {
183 return SkToBool(fFlags & kSampledWithExplicitCoords_Flag);
184 }
185
186 // True if the transform chain from root to this FP introduces perspective into the local
187 // coordinate expression.
188 bool hasPerspectiveTransform() const {
189 return SkToBool(fFlags & kNetTransformHasPerspective_Flag);
190 }
191
192 // The SampleUsage describing how this FP is invoked by its parent using 'sample(matrix)'
193 // This only reflects the immediate sampling from parent to this FP
194 const SkSL::SampleUsage& sampleUsage() const {
195 return fUsage;
196 }
197
198 /**
199 * A GrDrawOp may premultiply its antialiasing coverage into its GrGeometryProcessor's color
200 * output under the following scenario:
201 * * all the color fragment processors report true to this query,
202 * * all the coverage fragment processors report true to this query,
203 * * the blend mode arithmetic allows for it it.
204 * To be compatible a fragment processor's output must be a modulation of its input color or
205 * alpha with a computed premultiplied color or alpha that is in 0..1 range. The computed color
206 * or alpha that is modulated against the input cannot depend on the input's alpha. The computed
207 * value cannot depend on the input's color channels unless it unpremultiplies the input color
208 * channels by the input alpha.
209 */
210 bool compatibleWithCoverageAsAlpha() const {
211 return SkToBool(fFlags & kCompatibleWithCoverageAsAlpha_OptimizationFlag);
212 }
213
214 /**
215 * If this is true then all opaque input colors to the processor produce opaque output colors.
216 */
217 bool preservesOpaqueInput() const {
218 return SkToBool(fFlags & kPreservesOpaqueInput_OptimizationFlag);
219 }
220
221 /**
222 * Tests whether given a constant input color the processor produces a constant output color
223 * (for all fragments). If true outputColor will contain the constant color produces for
224 * inputColor.
225 */
226 bool hasConstantOutputForConstantInput(SkPMColor4f inputColor, SkPMColor4f* outputColor) const {
227 if (fFlags & kConstantOutputForConstantInput_OptimizationFlag) {
228 *outputColor = this->constantOutputForConstantInput(inputColor);
229 return true;
230 }
231 return false;
232 }
233 bool hasConstantOutputForConstantInput() const {
234 return SkToBool(fFlags & kConstantOutputForConstantInput_OptimizationFlag);
235 }
236
237 /** Returns true if this and other processor conservatively draw identically. It can only return
238 true when the two processor are of the same subclass (i.e. they return the same object from
239 from getFactory()).
240
241 A return value of true from isEqual() should not be used to test whether the processor would
242 generate the same shader code. To test for identical code generation use getGLSLProcessorKey
243 */
244 bool isEqual(const GrFragmentProcessor& that) const;
245
246 void visitProxies(const GrOp::VisitProxyFunc& func) const;
247
248 void visitTextureEffects(const std::function<void(const GrTextureEffect&)>&) const;
249
250 GrTextureEffect* asTextureEffect();
251 const GrTextureEffect* asTextureEffect() const;
252
253#if GR_TEST_UTILS
254 // Generates debug info for this processor tree by recursively calling dumpInfo() on this
255 // processor and its children.
256 SkString dumpTreeInfo() const;
257#endif
258
259 // A pre-order traversal iterator over a hierarchy of FPs. It can also iterate over all the FP
260 // hierarchies rooted in a GrPaint, GrProcessorSet, or GrPipeline. For these collections it
261 // iterates the tree rooted at each color FP and then each coverage FP.
262 //
263 // An iterator is constructed from one of the srcs and used like this:
264 // for (GrFragmentProcessor::Iter iter(pipeline); iter; ++iter) {
265 // GrFragmentProcessor& fp = *iter;
266 // }
267 // The exit test for the loop is using CIter's operator bool().
268 // To use a range-for loop instead see CIterRange below.
269 class CIter;
270
271 // Used to implement a range-for loop using CIter. Src is one of GrFragmentProcessor,
272 // GrPaint, GrProcessorSet, or GrPipeline. Type aliases for these defined below.
273 // Example usage:
274 // for (const auto& fp : GrFragmentProcessor::PaintRange(paint)) {
275 // if (fp.usesLocalCoords()) {
276 // ...
277 // }
278 // }
279 template <typename Src> class CIterRange;
280
281 // We would use template deduction guides for CIter but for:
282 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79501
283 // Instead we use these specialized type aliases to make it prettier
284 // to construct CIters for particular sources of FPs.
285 using FPRange = CIterRange<GrFragmentProcessor>;
286 using PaintRange = CIterRange<GrPaint>;
287
288 // Sentinel type for range-for using CIter.
289 class EndCIter {};
290
291protected:
292 enum OptimizationFlags : uint32_t {
293 kNone_OptimizationFlags,
294 kCompatibleWithCoverageAsAlpha_OptimizationFlag = 0x1,
295 kPreservesOpaqueInput_OptimizationFlag = 0x2,
296 kConstantOutputForConstantInput_OptimizationFlag = 0x4,
297 kAll_OptimizationFlags = kCompatibleWithCoverageAsAlpha_OptimizationFlag |
298 kPreservesOpaqueInput_OptimizationFlag |
299 kConstantOutputForConstantInput_OptimizationFlag
300 };
301 GR_DECL_BITFIELD_OPS_FRIENDS(OptimizationFlags)
302
303 /**
304 * Can be used as a helper to decide which fragment processor OptimizationFlags should be set.
305 * This assumes that the subclass output color will be a modulation of the input color with a
306 * value read from a texture of the passed color type and that the texture contains
307 * premultiplied color or alpha values that are in range.
308 *
309 * Since there are multiple ways in which a sampler may have its coordinates clamped or wrapped,
310 * callers must determine on their own if the sampling uses a decal strategy in any way, in
311 * which case the texture may become transparent regardless of the color type.
312 */
313 static OptimizationFlags ModulateForSamplerOptFlags(SkAlphaType alphaType, bool samplingDecal) {
314 if (samplingDecal) {
315 return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
316 } else {
317 return ModulateForClampedSamplerOptFlags(alphaType);
318 }
319 }
320
321 // As above, but callers should somehow ensure or assert their sampler still uses clamping
322 static OptimizationFlags ModulateForClampedSamplerOptFlags(SkAlphaType alphaType) {
323 if (alphaType == kOpaque_SkAlphaType) {
324 return kCompatibleWithCoverageAsAlpha_OptimizationFlag |
325 kPreservesOpaqueInput_OptimizationFlag;
326 } else {
327 return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
328 }
329 }
330
331 GrFragmentProcessor(ClassID classID, OptimizationFlags optimizationFlags)
332 : INHERITED(classID), fFlags(optimizationFlags) {
333 SkASSERT((optimizationFlags & ~kAll_OptimizationFlags) == 0);
334 }
335
336 OptimizationFlags optimizationFlags() const {
337 return static_cast<OptimizationFlags>(kAll_OptimizationFlags & fFlags);
338 }
339
340 /** Useful when you can't call fp->optimizationFlags() on a base class object from a subclass.*/
341 static OptimizationFlags ProcessorOptimizationFlags(const GrFragmentProcessor* fp) {
342 return fp ? fp->optimizationFlags() : kAll_OptimizationFlags;
343 }
344
345 /**
346 * This allows one subclass to access another subclass's implementation of
347 * constantOutputForConstantInput. It must only be called when
348 * hasConstantOutputForConstantInput() is known to be true.
349 */
350 static SkPMColor4f ConstantOutputForConstantInput(const GrFragmentProcessor* fp,
351 const SkPMColor4f& input) {
352 if (fp) {
353 SkASSERT(fp->hasConstantOutputForConstantInput());
354 return fp->constantOutputForConstantInput(input);
355 } else {
356 return input;
357 }
358 }
359
360 /**
361 * FragmentProcessor subclasses call this from their constructor to register any child
362 * FragmentProcessors they have. This must be called AFTER all texture accesses and coord
363 * transforms have been added.
364 * This is for processors whose shader code will be composed of nested processors whose output
365 * colors will be combined somehow to produce its output color. Registering these child
366 * processors will allow the ProgramBuilder to automatically handle their transformed coords and
367 * texture accesses and mangle their uniform and output color names.
368 *
369 * The SampleUsage parameter describes all of the ways that the child is sampled by the parent.
370 */
371 void registerChild(std::unique_ptr<GrFragmentProcessor> child,
372 SkSL::SampleUsage sampleUsage = SkSL::SampleUsage::PassThrough());
373
374 /**
375 * This method takes an existing fragment processor, clones all of its children, and registers
376 * the clones as children of this fragment processor.
377 */
378 void cloneAndRegisterAllChildProcessors(const GrFragmentProcessor& src);
379
380 // FP implementations must call this function if their matching GrGLSLFragmentProcessor's
381 // emitCode() function uses the EmitArgs::fSampleCoord variable in generated SkSL.
382 void setUsesSampleCoordsDirectly() {
383 fFlags |= kUsesSampleCoordsDirectly_Flag;
384 }
385
386private:
387 virtual SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& /* inputColor */) const {
388 SK_ABORT("Subclass must override this if advertising this optimization.");
389 }
390
391 /** Returns a new instance of the appropriate *GL* implementation class
392 for the given GrFragmentProcessor; caller is responsible for deleting
393 the object. */
394 virtual GrGLSLFragmentProcessor* onCreateGLSLInstance() const = 0;
395
396 /** Implemented using GLFragmentProcessor::GenKey as described in this class's comment. */
397 virtual void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
398
399 /**
400 * Subclass implements this to support isEqual(). It will only be called if it is known that
401 * the two processors are of the same subclass (i.e. they return the same object from
402 * getFactory()).
403 */
404 virtual bool onIsEqual(const GrFragmentProcessor&) const = 0;
405
406 enum PrivateFlags {
407 kFirstPrivateFlag = kAll_OptimizationFlags + 1,
408
409 // Propagate up the FP tree to the root
410 kUsesSampleCoordsIndirectly_Flag = kFirstPrivateFlag,
411
412 // Does not propagate at all
413 kUsesSampleCoordsDirectly_Flag = kFirstPrivateFlag << 1,
414
415 // Propagates down the FP to all its leaves
416 kSampledWithExplicitCoords_Flag = kFirstPrivateFlag << 2,
417 kNetTransformHasPerspective_Flag = kFirstPrivateFlag << 3,
418 };
419 void addAndPushFlagToChildren(PrivateFlags flag);
420
421 SkSTArray<1, std::unique_ptr<GrFragmentProcessor>, true> fChildProcessors;
422 const GrFragmentProcessor* fParent = nullptr;
423 uint32_t fFlags = 0;
424 SkSL::SampleUsage fUsage;
425
426 typedef GrProcessor INHERITED;
427};
428
429//////////////////////////////////////////////////////////////////////////////
430
431GR_MAKE_BITFIELD_OPS(GrFragmentProcessor::OptimizationFlags)
432
433//////////////////////////////////////////////////////////////////////////////
434
435class GrFragmentProcessor::CIter {
436public:
437 explicit CIter(const GrFragmentProcessor& fp) { fFPStack.push_back(&fp); }
438 explicit CIter(const GrPaint&);
439 explicit CIter(const GrPipeline&);
440
441 const GrFragmentProcessor& operator*() const { return *fFPStack.back(); }
442 const GrFragmentProcessor* operator->() const { return fFPStack.back(); }
443
444 CIter& operator++();
445
446 operator bool() const { return !fFPStack.empty(); }
447
448 bool operator!=(const EndCIter&) { return (bool)*this; }
449
450 // Hopefully this does not actually get called because of RVO.
451 CIter(const CIter&) = default;
452
453 // Because each iterator carries a stack we want to avoid copies.
454 CIter& operator=(const CIter&) = delete;
455
456protected:
457 CIter() = delete;
458
459 SkSTArray<4, const GrFragmentProcessor*, true> fFPStack;
460};
461
462//////////////////////////////////////////////////////////////////////////////
463
464template <typename Src> class GrFragmentProcessor::CIterRange {
465public:
466 explicit CIterRange(const Src& t) : fT(t) {}
467 CIter begin() const { return CIter(fT); }
468 EndCIter end() const { return EndCIter(); }
469
470private:
471 const Src& fT;
472};
473
474/**
475 * Some fragment-processor creation methods have preconditions that might not be satisfied by the
476 * calling code. Those methods can return a `GrFPResult` from their factory methods. If creation
477 * succeeds, the new fragment processor is created and `success` is true. If a precondition is not
478 * met, `success` is set to false and the input FP is returned unchanged.
479 */
480using GrFPResult = std::tuple<bool /*success*/, std::unique_ptr<GrFragmentProcessor>>;
481static inline GrFPResult GrFPFailure(std::unique_ptr<GrFragmentProcessor> fp) {
482 return {false, std::move(fp)};
483}
484static inline GrFPResult GrFPSuccess(std::unique_ptr<GrFragmentProcessor> fp) {
485 return {true, std::move(fp)};
486}
487
488#endif
489