xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrFragmentProcessor.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2014 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef GrFragmentProcessor_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define GrFragmentProcessor_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkAlphaType.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkColorData.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkSLSampleUsage.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkMacros.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProcessor.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h"
23*c8dee2aaSAndroid Build Coastguard Worker 
24*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
25*c8dee2aaSAndroid Build Coastguard Worker #include <functional>
26*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
27*c8dee2aaSAndroid Build Coastguard Worker #include <string_view>
28*c8dee2aaSAndroid Build Coastguard Worker #include <tuple>
29*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
30*c8dee2aaSAndroid Build Coastguard Worker 
31*c8dee2aaSAndroid Build Coastguard Worker class GrGLSLFPFragmentBuilder;
32*c8dee2aaSAndroid Build Coastguard Worker class GrGLSLProgramDataManager;
33*c8dee2aaSAndroid Build Coastguard Worker struct GrShaderCaps;
34*c8dee2aaSAndroid Build Coastguard Worker class GrTextureEffect;
35*c8dee2aaSAndroid Build Coastguard Worker struct SkPoint;
36*c8dee2aaSAndroid Build Coastguard Worker struct SkRect;
37*c8dee2aaSAndroid Build Coastguard Worker 
38*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu {
39*c8dee2aaSAndroid Build Coastguard Worker class KeyBuilder;
40*c8dee2aaSAndroid Build Coastguard Worker class Swizzle;
41*c8dee2aaSAndroid Build Coastguard Worker }
42*c8dee2aaSAndroid Build Coastguard Worker 
43*c8dee2aaSAndroid Build Coastguard Worker /**
44*c8dee2aaSAndroid Build Coastguard Worker  * Some fragment-processor creation methods have preconditions that might not be satisfied by the
45*c8dee2aaSAndroid Build Coastguard Worker  * calling code. Those methods can return a `GrFPResult` from their factory methods. If creation
46*c8dee2aaSAndroid Build Coastguard Worker  * succeeds, the new fragment processor is created and `success` is true. If a precondition is not
47*c8dee2aaSAndroid Build Coastguard Worker  * met, `success` is set to false and the input FP is returned unchanged.
48*c8dee2aaSAndroid Build Coastguard Worker  */
49*c8dee2aaSAndroid Build Coastguard Worker class GrFragmentProcessor;  // IWYU pragma: keep
50*c8dee2aaSAndroid Build Coastguard Worker using GrFPResult = std::tuple<bool /*success*/, std::unique_ptr<GrFragmentProcessor>>;
51*c8dee2aaSAndroid Build Coastguard Worker 
52*c8dee2aaSAndroid Build Coastguard Worker /** Provides custom fragment shader code. Fragment processors receive an input position and
53*c8dee2aaSAndroid Build Coastguard Worker     produce an output color. They may contain uniforms and may have children fragment processors
54*c8dee2aaSAndroid Build Coastguard Worker     that are sampled.
55*c8dee2aaSAndroid Build Coastguard Worker  */
56*c8dee2aaSAndroid Build Coastguard Worker class GrFragmentProcessor : public GrProcessor {
57*c8dee2aaSAndroid Build Coastguard Worker public:
58*c8dee2aaSAndroid Build Coastguard Worker     /**
59*c8dee2aaSAndroid Build Coastguard Worker      * Every GrFragmentProcessor must be capable of creating a subclass of ProgramImpl. The
60*c8dee2aaSAndroid Build Coastguard Worker      * ProgramImpl emits the fragment shader code that implements the GrFragmentProcessor, is
61*c8dee2aaSAndroid Build Coastguard Worker      * attached to the generated backend API pipeline/program and used to extract uniform data from
62*c8dee2aaSAndroid Build Coastguard Worker      * GrFragmentProcessor instances.
63*c8dee2aaSAndroid Build Coastguard Worker      */
64*c8dee2aaSAndroid Build Coastguard Worker     class ProgramImpl;
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker     /** Always returns 'color'. */
67*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> MakeColor(SkPMColor4f color);
68*c8dee2aaSAndroid Build Coastguard Worker 
69*c8dee2aaSAndroid Build Coastguard Worker     /**
70*c8dee2aaSAndroid Build Coastguard Worker      *  Returns the input color, modulated by the child's alpha.
71*c8dee2aaSAndroid Build Coastguard Worker      *
72*c8dee2aaSAndroid Build Coastguard Worker      *  output = input * child.a
73*c8dee2aaSAndroid Build Coastguard Worker      */
74*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> MulInputByChildAlpha(
75*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<GrFragmentProcessor> child);
76*c8dee2aaSAndroid Build Coastguard Worker 
77*c8dee2aaSAndroid Build Coastguard Worker     /**
78*c8dee2aaSAndroid Build Coastguard Worker      *  Invokes child with an opaque version of the input color, then applies the input alpha to
79*c8dee2aaSAndroid Build Coastguard Worker      *  the result. Used to incorporate paint alpha to the evaluation of an SkShader tree FP.
80*c8dee2aaSAndroid Build Coastguard Worker      */
81*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> ApplyPaintAlpha(
82*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<GrFragmentProcessor> child);
83*c8dee2aaSAndroid Build Coastguard Worker 
84*c8dee2aaSAndroid Build Coastguard Worker     /**
85*c8dee2aaSAndroid Build Coastguard Worker      *  Returns a fragment processor that generates the passed-in color, modulated by the child's
86*c8dee2aaSAndroid Build Coastguard Worker      *  RGBA color. The child's input color will be the parent's fInputColor. (Pass a null FP to use
87*c8dee2aaSAndroid Build Coastguard Worker      *  the color from fInputColor instead of a child FP.)
88*c8dee2aaSAndroid Build Coastguard Worker      */
89*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> ModulateRGBA(
90*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<GrFragmentProcessor> child, const SkPMColor4f& color);
91*c8dee2aaSAndroid Build Coastguard Worker 
92*c8dee2aaSAndroid Build Coastguard Worker     /**
93*c8dee2aaSAndroid Build Coastguard Worker      *  Returns a parent fragment processor that adopts the passed fragment processor as a child.
94*c8dee2aaSAndroid Build Coastguard Worker      *  The parent will ignore its input color and instead feed the passed in color as input to the
95*c8dee2aaSAndroid Build Coastguard Worker      *  child.
96*c8dee2aaSAndroid Build Coastguard Worker      */
97*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> OverrideInput(std::unique_ptr<GrFragmentProcessor>,
98*c8dee2aaSAndroid Build Coastguard Worker                                                               const SkPMColor4f&);
99*c8dee2aaSAndroid Build Coastguard Worker 
100*c8dee2aaSAndroid Build Coastguard Worker     /**
101*c8dee2aaSAndroid Build Coastguard Worker      *  Returns a parent fragment processor that adopts the passed fragment processor as a child.
102*c8dee2aaSAndroid Build Coastguard Worker      *  The parent will simply return the child's color, but disable the coverage-as-alpha
103*c8dee2aaSAndroid Build Coastguard Worker      *  optimization.
104*c8dee2aaSAndroid Build Coastguard Worker      */
105*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> DisableCoverageAsAlpha(
106*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<GrFragmentProcessor>);
107*c8dee2aaSAndroid Build Coastguard Worker 
108*c8dee2aaSAndroid Build Coastguard Worker     /**
109*c8dee2aaSAndroid Build Coastguard Worker      *  Returns a fragment processor which returns `args.fDestColor`. This is only meaningful in
110*c8dee2aaSAndroid Build Coastguard Worker      *  contexts like blenders, which use a source and dest color.)
111*c8dee2aaSAndroid Build Coastguard Worker      */
112*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> DestColor();
113*c8dee2aaSAndroid Build Coastguard Worker 
114*c8dee2aaSAndroid Build Coastguard Worker     /**
115*c8dee2aaSAndroid Build Coastguard Worker      *  Returns a fragment processor that calls the passed in fragment processor, and then swizzles
116*c8dee2aaSAndroid Build Coastguard Worker      *  the output.
117*c8dee2aaSAndroid Build Coastguard Worker      */
118*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> SwizzleOutput(std::unique_ptr<GrFragmentProcessor>,
119*c8dee2aaSAndroid Build Coastguard Worker                                                               const skgpu::Swizzle&);
120*c8dee2aaSAndroid Build Coastguard Worker 
121*c8dee2aaSAndroid Build Coastguard Worker     /**
122*c8dee2aaSAndroid Build Coastguard Worker      *  Returns a fragment processor that calls the passed in fragment processor, and then clamps
123*c8dee2aaSAndroid Build Coastguard Worker      *  the output to [0, 1].
124*c8dee2aaSAndroid Build Coastguard Worker      */
125*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> ClampOutput(std::unique_ptr<GrFragmentProcessor>);
126*c8dee2aaSAndroid Build Coastguard Worker 
127*c8dee2aaSAndroid Build Coastguard Worker     /**
128*c8dee2aaSAndroid Build Coastguard Worker      * Returns a fragment processor that composes two fragment processors `f` and `g` into f(g(x)).
129*c8dee2aaSAndroid Build Coastguard Worker      * This is equivalent to running them in series (`g`, then `f`). This is not the same as
130*c8dee2aaSAndroid Build Coastguard Worker      * transfer-mode composition; there is no blending step.
131*c8dee2aaSAndroid Build Coastguard Worker      */
132*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> Compose(std::unique_ptr<GrFragmentProcessor> f,
133*c8dee2aaSAndroid Build Coastguard Worker                                                         std::unique_ptr<GrFragmentProcessor> g);
134*c8dee2aaSAndroid Build Coastguard Worker 
135*c8dee2aaSAndroid Build Coastguard Worker     /*
136*c8dee2aaSAndroid Build Coastguard Worker      * Returns a fragment processor that calls the passed in fragment processor, then runs the
137*c8dee2aaSAndroid Build Coastguard Worker      * resulting color through the supplied color matrix.
138*c8dee2aaSAndroid Build Coastguard Worker      */
139*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> ColorMatrix(
140*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<GrFragmentProcessor> child,
141*c8dee2aaSAndroid Build Coastguard Worker             const float matrix[20],
142*c8dee2aaSAndroid Build Coastguard Worker             bool unpremulInput,
143*c8dee2aaSAndroid Build Coastguard Worker             bool clampRGBOutput,
144*c8dee2aaSAndroid Build Coastguard Worker             bool premulOutput);
145*c8dee2aaSAndroid Build Coastguard Worker 
146*c8dee2aaSAndroid Build Coastguard Worker     /**
147*c8dee2aaSAndroid Build Coastguard Worker      * Returns a fragment processor that reads back the color on the surface being painted; that is,
148*c8dee2aaSAndroid Build Coastguard Worker      * sampling this will return the color of the pixel that is currently being painted over.
149*c8dee2aaSAndroid Build Coastguard Worker      */
150*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> SurfaceColor();
151*c8dee2aaSAndroid Build Coastguard Worker 
152*c8dee2aaSAndroid Build Coastguard Worker     /**
153*c8dee2aaSAndroid Build Coastguard Worker      * Returns a fragment processor that calls the passed in fragment processor, but evaluates it
154*c8dee2aaSAndroid Build Coastguard Worker      * in device-space (rather than local space).
155*c8dee2aaSAndroid Build Coastguard Worker      */
156*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> DeviceSpace(std::unique_ptr<GrFragmentProcessor>);
157*c8dee2aaSAndroid Build Coastguard Worker 
158*c8dee2aaSAndroid Build Coastguard Worker     /**
159*c8dee2aaSAndroid Build Coastguard Worker      * "Shape" FPs, often used for clipping. Each one evaluates a particular kind of shape (rect,
160*c8dee2aaSAndroid Build Coastguard Worker      * circle, ellipse), and modulates the coverage of that shape against the results of the input
161*c8dee2aaSAndroid Build Coastguard Worker      * FP. GrClipEdgeType is used to select inverse/normal fill, and AA or non-AA edges.
162*c8dee2aaSAndroid Build Coastguard Worker      */
163*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> Rect(std::unique_ptr<GrFragmentProcessor>,
164*c8dee2aaSAndroid Build Coastguard Worker                                                      GrClipEdgeType,
165*c8dee2aaSAndroid Build Coastguard Worker                                                      SkRect);
166*c8dee2aaSAndroid Build Coastguard Worker 
167*c8dee2aaSAndroid Build Coastguard Worker     static GrFPResult Circle(std::unique_ptr<GrFragmentProcessor>,
168*c8dee2aaSAndroid Build Coastguard Worker                              GrClipEdgeType,
169*c8dee2aaSAndroid Build Coastguard Worker                              SkPoint center,
170*c8dee2aaSAndroid Build Coastguard Worker                              float radius);
171*c8dee2aaSAndroid Build Coastguard Worker 
172*c8dee2aaSAndroid Build Coastguard Worker     static GrFPResult Ellipse(std::unique_ptr<GrFragmentProcessor>,
173*c8dee2aaSAndroid Build Coastguard Worker                               GrClipEdgeType,
174*c8dee2aaSAndroid Build Coastguard Worker                               SkPoint center,
175*c8dee2aaSAndroid Build Coastguard Worker                               SkPoint radii,
176*c8dee2aaSAndroid Build Coastguard Worker                               const GrShaderCaps&);
177*c8dee2aaSAndroid Build Coastguard Worker 
178*c8dee2aaSAndroid Build Coastguard Worker     /**
179*c8dee2aaSAndroid Build Coastguard Worker      * Returns a fragment processor that calls the passed in fragment processor, but ensures the
180*c8dee2aaSAndroid Build Coastguard Worker      * entire program is compiled with high-precision types.
181*c8dee2aaSAndroid Build Coastguard Worker      */
182*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<GrFragmentProcessor> HighPrecision(std::unique_ptr<GrFragmentProcessor>);
183*c8dee2aaSAndroid Build Coastguard Worker 
184*c8dee2aaSAndroid Build Coastguard Worker     /**
185*c8dee2aaSAndroid Build Coastguard Worker      * Makes a copy of this fragment processor that draws equivalently to the original.
186*c8dee2aaSAndroid Build Coastguard Worker      * If the processor has child processors they are cloned as well.
187*c8dee2aaSAndroid Build Coastguard Worker      */
188*c8dee2aaSAndroid Build Coastguard Worker     virtual std::unique_ptr<GrFragmentProcessor> clone() const = 0;
189*c8dee2aaSAndroid Build Coastguard Worker 
190*c8dee2aaSAndroid Build Coastguard Worker     // The FP this was registered with as a child function. This will be null if this is a root.
parent()191*c8dee2aaSAndroid Build Coastguard Worker     const GrFragmentProcessor* parent() const { return fParent; }
192*c8dee2aaSAndroid Build Coastguard Worker 
193*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<ProgramImpl> makeProgramImpl() const;
194*c8dee2aaSAndroid Build Coastguard Worker 
addToKey(const GrShaderCaps & caps,skgpu::KeyBuilder * b)195*c8dee2aaSAndroid Build Coastguard Worker     void addToKey(const GrShaderCaps& caps, skgpu::KeyBuilder* b) const {
196*c8dee2aaSAndroid Build Coastguard Worker         this->onAddToKey(caps, b);
197*c8dee2aaSAndroid Build Coastguard Worker         for (const auto& child : fChildProcessors) {
198*c8dee2aaSAndroid Build Coastguard Worker             if (child) {
199*c8dee2aaSAndroid Build Coastguard Worker                 child->addToKey(caps, b);
200*c8dee2aaSAndroid Build Coastguard Worker             }
201*c8dee2aaSAndroid Build Coastguard Worker         }
202*c8dee2aaSAndroid Build Coastguard Worker     }
203*c8dee2aaSAndroid Build Coastguard Worker 
numChildProcessors()204*c8dee2aaSAndroid Build Coastguard Worker     int numChildProcessors() const { return fChildProcessors.size(); }
205*c8dee2aaSAndroid Build Coastguard Worker     int numNonNullChildProcessors() const;
206*c8dee2aaSAndroid Build Coastguard Worker 
childProcessor(int index)207*c8dee2aaSAndroid Build Coastguard Worker     GrFragmentProcessor* childProcessor(int index) { return fChildProcessors[index].get(); }
childProcessor(int index)208*c8dee2aaSAndroid Build Coastguard Worker     const GrFragmentProcessor* childProcessor(int index) const {
209*c8dee2aaSAndroid Build Coastguard Worker         return fChildProcessors[index].get();
210*c8dee2aaSAndroid Build Coastguard Worker     }
211*c8dee2aaSAndroid Build Coastguard Worker 
SkDEBUGCODE(bool isInstantiated ()const;)212*c8dee2aaSAndroid Build Coastguard Worker     SkDEBUGCODE(bool isInstantiated() const;)
213*c8dee2aaSAndroid Build Coastguard Worker 
214*c8dee2aaSAndroid Build Coastguard Worker     /** Do any of the FPs in this tree read back the color from the destination surface? */
215*c8dee2aaSAndroid Build Coastguard Worker     bool willReadDstColor() const {
216*c8dee2aaSAndroid Build Coastguard Worker         return SkToBool(fFlags & kWillReadDstColor_Flag);
217*c8dee2aaSAndroid Build Coastguard Worker     }
218*c8dee2aaSAndroid Build Coastguard Worker 
219*c8dee2aaSAndroid Build Coastguard Worker     /** Does the SkSL for this FP take two colors as its input arguments? */
isBlendFunction()220*c8dee2aaSAndroid Build Coastguard Worker     bool isBlendFunction() const {
221*c8dee2aaSAndroid Build Coastguard Worker         return SkToBool(fFlags & kIsBlendFunction_Flag);
222*c8dee2aaSAndroid Build Coastguard Worker     }
223*c8dee2aaSAndroid Build Coastguard Worker 
224*c8dee2aaSAndroid Build Coastguard Worker     /**
225*c8dee2aaSAndroid Build Coastguard Worker      * True if this FP refers directly to the sample coordinate parameter of its function
226*c8dee2aaSAndroid Build Coastguard Worker      * (e.g. uses EmitArgs::fSampleCoord in emitCode()). This is decided at FP-tree construction
227*c8dee2aaSAndroid Build Coastguard Worker      * time and is not affected by lifting coords to varyings.
228*c8dee2aaSAndroid Build Coastguard Worker      */
usesSampleCoordsDirectly()229*c8dee2aaSAndroid Build Coastguard Worker     bool usesSampleCoordsDirectly() const {
230*c8dee2aaSAndroid Build Coastguard Worker         return SkToBool(fFlags & kUsesSampleCoordsDirectly_Flag);
231*c8dee2aaSAndroid Build Coastguard Worker     }
232*c8dee2aaSAndroid Build Coastguard Worker 
233*c8dee2aaSAndroid Build Coastguard Worker     /**
234*c8dee2aaSAndroid Build Coastguard Worker      * True if this FP uses its input coordinates or if any descendant FP uses them through a chain
235*c8dee2aaSAndroid Build Coastguard Worker      * of non-explicit sample usages. (e.g. uses EmitArgs::fSampleCoord in emitCode()). This is
236*c8dee2aaSAndroid Build Coastguard Worker      * decided at FP-tree construction time and is not affected by lifting coords to varyings.
237*c8dee2aaSAndroid Build Coastguard Worker      */
usesSampleCoords()238*c8dee2aaSAndroid Build Coastguard Worker     bool usesSampleCoords() const {
239*c8dee2aaSAndroid Build Coastguard Worker         return SkToBool(fFlags & (kUsesSampleCoordsDirectly_Flag |
240*c8dee2aaSAndroid Build Coastguard Worker                                   kUsesSampleCoordsIndirectly_Flag));
241*c8dee2aaSAndroid Build Coastguard Worker     }
242*c8dee2aaSAndroid Build Coastguard Worker 
243*c8dee2aaSAndroid Build Coastguard Worker     // The SampleUsage describing how this FP is invoked by its parent. This only reflects the
244*c8dee2aaSAndroid Build Coastguard Worker     // immediate sampling from parent to this FP.
sampleUsage()245*c8dee2aaSAndroid Build Coastguard Worker     const SkSL::SampleUsage& sampleUsage() const {
246*c8dee2aaSAndroid Build Coastguard Worker         return fUsage;
247*c8dee2aaSAndroid Build Coastguard Worker     }
248*c8dee2aaSAndroid Build Coastguard Worker 
249*c8dee2aaSAndroid Build Coastguard Worker     /**
250*c8dee2aaSAndroid Build Coastguard Worker      * A GrDrawOp may premultiply its antialiasing coverage into its GrGeometryProcessor's color
251*c8dee2aaSAndroid Build Coastguard Worker      * output under the following scenario:
252*c8dee2aaSAndroid Build Coastguard Worker      *   * all the color fragment processors report true to this query,
253*c8dee2aaSAndroid Build Coastguard Worker      *   * all the coverage fragment processors report true to this query,
254*c8dee2aaSAndroid Build Coastguard Worker      *   * the blend mode arithmetic allows for it it.
255*c8dee2aaSAndroid Build Coastguard Worker      * To be compatible a fragment processor's output must be a modulation of its input color or
256*c8dee2aaSAndroid Build Coastguard Worker      * alpha with a computed premultiplied color or alpha that is in 0..1 range. The computed color
257*c8dee2aaSAndroid Build Coastguard Worker      * or alpha that is modulated against the input cannot depend on the input's alpha. The computed
258*c8dee2aaSAndroid Build Coastguard Worker      * value cannot depend on the input's color channels unless it unpremultiplies the input color
259*c8dee2aaSAndroid Build Coastguard Worker      * channels by the input alpha.
260*c8dee2aaSAndroid Build Coastguard Worker      */
compatibleWithCoverageAsAlpha()261*c8dee2aaSAndroid Build Coastguard Worker     bool compatibleWithCoverageAsAlpha() const {
262*c8dee2aaSAndroid Build Coastguard Worker         return SkToBool(fFlags & kCompatibleWithCoverageAsAlpha_OptimizationFlag);
263*c8dee2aaSAndroid Build Coastguard Worker     }
264*c8dee2aaSAndroid Build Coastguard Worker 
265*c8dee2aaSAndroid Build Coastguard Worker     /**
266*c8dee2aaSAndroid Build Coastguard Worker      * If this is true then all opaque input colors to the processor produce opaque output colors.
267*c8dee2aaSAndroid Build Coastguard Worker      */
preservesOpaqueInput()268*c8dee2aaSAndroid Build Coastguard Worker     bool preservesOpaqueInput() const {
269*c8dee2aaSAndroid Build Coastguard Worker         return SkToBool(fFlags & kPreservesOpaqueInput_OptimizationFlag);
270*c8dee2aaSAndroid Build Coastguard Worker     }
271*c8dee2aaSAndroid Build Coastguard Worker 
272*c8dee2aaSAndroid Build Coastguard Worker     /**
273*c8dee2aaSAndroid Build Coastguard Worker      * Tests whether given a constant input color the processor produces a constant output color
274*c8dee2aaSAndroid Build Coastguard Worker      * (for all fragments). If true outputColor will contain the constant color produces for
275*c8dee2aaSAndroid Build Coastguard Worker      * inputColor.
276*c8dee2aaSAndroid Build Coastguard Worker      */
hasConstantOutputForConstantInput(SkPMColor4f inputColor,SkPMColor4f * outputColor)277*c8dee2aaSAndroid Build Coastguard Worker     bool hasConstantOutputForConstantInput(SkPMColor4f inputColor, SkPMColor4f* outputColor) const {
278*c8dee2aaSAndroid Build Coastguard Worker         if (fFlags & kConstantOutputForConstantInput_OptimizationFlag) {
279*c8dee2aaSAndroid Build Coastguard Worker             *outputColor = this->constantOutputForConstantInput(inputColor);
280*c8dee2aaSAndroid Build Coastguard Worker             return true;
281*c8dee2aaSAndroid Build Coastguard Worker         }
282*c8dee2aaSAndroid Build Coastguard Worker         return false;
283*c8dee2aaSAndroid Build Coastguard Worker     }
hasConstantOutputForConstantInput()284*c8dee2aaSAndroid Build Coastguard Worker     bool hasConstantOutputForConstantInput() const {
285*c8dee2aaSAndroid Build Coastguard Worker         return SkToBool(fFlags & kConstantOutputForConstantInput_OptimizationFlag);
286*c8dee2aaSAndroid Build Coastguard Worker     }
287*c8dee2aaSAndroid Build Coastguard Worker 
clearConstantOutputForConstantInputFlag()288*c8dee2aaSAndroid Build Coastguard Worker     void clearConstantOutputForConstantInputFlag() {
289*c8dee2aaSAndroid Build Coastguard Worker         fFlags &= ~kConstantOutputForConstantInput_OptimizationFlag;
290*c8dee2aaSAndroid Build Coastguard Worker     }
291*c8dee2aaSAndroid Build Coastguard Worker 
292*c8dee2aaSAndroid Build Coastguard Worker     /** Returns true if this and other processor conservatively draw identically. It can only return
293*c8dee2aaSAndroid Build Coastguard Worker         true when the two processor are of the same subclass (i.e. they return the same object from
294*c8dee2aaSAndroid Build Coastguard Worker         from getFactory()).
295*c8dee2aaSAndroid Build Coastguard Worker 
296*c8dee2aaSAndroid Build Coastguard Worker         A return value of true from isEqual() should not be used to test whether the processor would
297*c8dee2aaSAndroid Build Coastguard Worker         generate the same shader code. To test for identical code generation use addToKey.
298*c8dee2aaSAndroid Build Coastguard Worker      */
299*c8dee2aaSAndroid Build Coastguard Worker     bool isEqual(const GrFragmentProcessor& that) const;
300*c8dee2aaSAndroid Build Coastguard Worker 
301*c8dee2aaSAndroid Build Coastguard Worker     void visitProxies(const GrVisitProxyFunc&) const;
302*c8dee2aaSAndroid Build Coastguard Worker 
303*c8dee2aaSAndroid Build Coastguard Worker     void visitTextureEffects(const std::function<void(const GrTextureEffect&)>&) const;
304*c8dee2aaSAndroid Build Coastguard Worker 
305*c8dee2aaSAndroid Build Coastguard Worker     void visitWithImpls(const std::function<void(const GrFragmentProcessor&, ProgramImpl&)>&,
306*c8dee2aaSAndroid Build Coastguard Worker                         ProgramImpl&) const;
307*c8dee2aaSAndroid Build Coastguard Worker 
308*c8dee2aaSAndroid Build Coastguard Worker     GrTextureEffect* asTextureEffect();
309*c8dee2aaSAndroid Build Coastguard Worker     const GrTextureEffect* asTextureEffect() const;
310*c8dee2aaSAndroid Build Coastguard Worker 
311*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
312*c8dee2aaSAndroid Build Coastguard Worker     // Generates debug info for this processor tree by recursively calling dumpInfo() on this
313*c8dee2aaSAndroid Build Coastguard Worker     // processor and its children.
314*c8dee2aaSAndroid Build Coastguard Worker     SkString dumpTreeInfo() const;
315*c8dee2aaSAndroid Build Coastguard Worker #endif
316*c8dee2aaSAndroid Build Coastguard Worker 
317*c8dee2aaSAndroid Build Coastguard Worker protected:
318*c8dee2aaSAndroid Build Coastguard Worker     enum OptimizationFlags : uint32_t {
319*c8dee2aaSAndroid Build Coastguard Worker         kNone_OptimizationFlags,
320*c8dee2aaSAndroid Build Coastguard Worker         kCompatibleWithCoverageAsAlpha_OptimizationFlag = 0x1,
321*c8dee2aaSAndroid Build Coastguard Worker         kPreservesOpaqueInput_OptimizationFlag = 0x2,
322*c8dee2aaSAndroid Build Coastguard Worker         kConstantOutputForConstantInput_OptimizationFlag = 0x4,
323*c8dee2aaSAndroid Build Coastguard Worker         kAll_OptimizationFlags = kCompatibleWithCoverageAsAlpha_OptimizationFlag |
324*c8dee2aaSAndroid Build Coastguard Worker                                  kPreservesOpaqueInput_OptimizationFlag |
325*c8dee2aaSAndroid Build Coastguard Worker                                  kConstantOutputForConstantInput_OptimizationFlag
326*c8dee2aaSAndroid Build Coastguard Worker     };
SK_DECL_BITFIELD_OPS_FRIENDS(OptimizationFlags)327*c8dee2aaSAndroid Build Coastguard Worker     SK_DECL_BITFIELD_OPS_FRIENDS(OptimizationFlags)
328*c8dee2aaSAndroid Build Coastguard Worker 
329*c8dee2aaSAndroid Build Coastguard Worker     /**
330*c8dee2aaSAndroid Build Coastguard Worker      * Can be used as a helper to decide which fragment processor OptimizationFlags should be set.
331*c8dee2aaSAndroid Build Coastguard Worker      * This assumes that the subclass output color will be a modulation of the input color with a
332*c8dee2aaSAndroid Build Coastguard Worker      * value read from a texture of the passed color type and that the texture contains
333*c8dee2aaSAndroid Build Coastguard Worker      * premultiplied color or alpha values that are in range.
334*c8dee2aaSAndroid Build Coastguard Worker      *
335*c8dee2aaSAndroid Build Coastguard Worker      * Since there are multiple ways in which a sampler may have its coordinates clamped or wrapped,
336*c8dee2aaSAndroid Build Coastguard Worker      * callers must determine on their own if the sampling uses a decal strategy in any way, in
337*c8dee2aaSAndroid Build Coastguard Worker      * which case the texture may become transparent regardless of the color type.
338*c8dee2aaSAndroid Build Coastguard Worker      */
339*c8dee2aaSAndroid Build Coastguard Worker     static OptimizationFlags ModulateForSamplerOptFlags(SkAlphaType alphaType, bool samplingDecal) {
340*c8dee2aaSAndroid Build Coastguard Worker         if (samplingDecal) {
341*c8dee2aaSAndroid Build Coastguard Worker             return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
342*c8dee2aaSAndroid Build Coastguard Worker         } else {
343*c8dee2aaSAndroid Build Coastguard Worker             return ModulateForClampedSamplerOptFlags(alphaType);
344*c8dee2aaSAndroid Build Coastguard Worker         }
345*c8dee2aaSAndroid Build Coastguard Worker     }
346*c8dee2aaSAndroid Build Coastguard Worker 
347*c8dee2aaSAndroid Build Coastguard Worker     // As above, but callers should somehow ensure or assert their sampler still uses clamping
ModulateForClampedSamplerOptFlags(SkAlphaType alphaType)348*c8dee2aaSAndroid Build Coastguard Worker     static OptimizationFlags ModulateForClampedSamplerOptFlags(SkAlphaType alphaType) {
349*c8dee2aaSAndroid Build Coastguard Worker         if (alphaType == kOpaque_SkAlphaType) {
350*c8dee2aaSAndroid Build Coastguard Worker             return kCompatibleWithCoverageAsAlpha_OptimizationFlag |
351*c8dee2aaSAndroid Build Coastguard Worker                    kPreservesOpaqueInput_OptimizationFlag;
352*c8dee2aaSAndroid Build Coastguard Worker         } else {
353*c8dee2aaSAndroid Build Coastguard Worker             return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
354*c8dee2aaSAndroid Build Coastguard Worker         }
355*c8dee2aaSAndroid Build Coastguard Worker     }
356*c8dee2aaSAndroid Build Coastguard Worker 
GrFragmentProcessor(ClassID classID,OptimizationFlags optimizationFlags)357*c8dee2aaSAndroid Build Coastguard Worker     GrFragmentProcessor(ClassID classID, OptimizationFlags optimizationFlags)
358*c8dee2aaSAndroid Build Coastguard Worker             : INHERITED(classID), fFlags(optimizationFlags) {
359*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT((optimizationFlags & ~kAll_OptimizationFlags) == 0);
360*c8dee2aaSAndroid Build Coastguard Worker     }
361*c8dee2aaSAndroid Build Coastguard Worker 
GrFragmentProcessor(const GrFragmentProcessor & src)362*c8dee2aaSAndroid Build Coastguard Worker     explicit GrFragmentProcessor(const GrFragmentProcessor& src)
363*c8dee2aaSAndroid Build Coastguard Worker             : INHERITED(src.classID()), fFlags(src.fFlags) {
364*c8dee2aaSAndroid Build Coastguard Worker         this->cloneAndRegisterAllChildProcessors(src);
365*c8dee2aaSAndroid Build Coastguard Worker     }
366*c8dee2aaSAndroid Build Coastguard Worker 
optimizationFlags()367*c8dee2aaSAndroid Build Coastguard Worker     OptimizationFlags optimizationFlags() const {
368*c8dee2aaSAndroid Build Coastguard Worker         return static_cast<OptimizationFlags>(kAll_OptimizationFlags & fFlags);
369*c8dee2aaSAndroid Build Coastguard Worker     }
370*c8dee2aaSAndroid Build Coastguard Worker 
371*c8dee2aaSAndroid Build Coastguard Worker     /** Useful when you can't call fp->optimizationFlags() on a base class object from a subclass.*/
ProcessorOptimizationFlags(const GrFragmentProcessor * fp)372*c8dee2aaSAndroid Build Coastguard Worker     static OptimizationFlags ProcessorOptimizationFlags(const GrFragmentProcessor* fp) {
373*c8dee2aaSAndroid Build Coastguard Worker         return fp ? fp->optimizationFlags() : kAll_OptimizationFlags;
374*c8dee2aaSAndroid Build Coastguard Worker     }
375*c8dee2aaSAndroid Build Coastguard Worker 
376*c8dee2aaSAndroid Build Coastguard Worker     /**
377*c8dee2aaSAndroid Build Coastguard Worker      * This allows one subclass to access another subclass's implementation of
378*c8dee2aaSAndroid Build Coastguard Worker      * constantOutputForConstantInput. It must only be called when
379*c8dee2aaSAndroid Build Coastguard Worker      * hasConstantOutputForConstantInput() is known to be true.
380*c8dee2aaSAndroid Build Coastguard Worker      */
ConstantOutputForConstantInput(const GrFragmentProcessor * fp,const SkPMColor4f & input)381*c8dee2aaSAndroid Build Coastguard Worker     static SkPMColor4f ConstantOutputForConstantInput(const GrFragmentProcessor* fp,
382*c8dee2aaSAndroid Build Coastguard Worker                                                       const SkPMColor4f& input) {
383*c8dee2aaSAndroid Build Coastguard Worker         if (fp) {
384*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(fp->hasConstantOutputForConstantInput());
385*c8dee2aaSAndroid Build Coastguard Worker             return fp->constantOutputForConstantInput(input);
386*c8dee2aaSAndroid Build Coastguard Worker         } else {
387*c8dee2aaSAndroid Build Coastguard Worker             return input;
388*c8dee2aaSAndroid Build Coastguard Worker         }
389*c8dee2aaSAndroid Build Coastguard Worker     }
390*c8dee2aaSAndroid Build Coastguard Worker 
391*c8dee2aaSAndroid Build Coastguard Worker     /**
392*c8dee2aaSAndroid Build Coastguard Worker      * FragmentProcessor subclasses call this from their constructor to register any child
393*c8dee2aaSAndroid Build Coastguard Worker      * FragmentProcessors they have. This must be called AFTER all texture accesses and coord
394*c8dee2aaSAndroid Build Coastguard Worker      * transforms have been added.
395*c8dee2aaSAndroid Build Coastguard Worker      * This is for processors whose shader code will be composed of nested processors whose output
396*c8dee2aaSAndroid Build Coastguard Worker      * colors will be combined somehow to produce its output color. Registering these child
397*c8dee2aaSAndroid Build Coastguard Worker      * processors will allow the ProgramBuilder to automatically handle their transformed coords and
398*c8dee2aaSAndroid Build Coastguard Worker      * texture accesses and mangle their uniform and output color names.
399*c8dee2aaSAndroid Build Coastguard Worker      *
400*c8dee2aaSAndroid Build Coastguard Worker      * The SampleUsage parameter describes all of the ways that the child is sampled by the parent.
401*c8dee2aaSAndroid Build Coastguard Worker      */
402*c8dee2aaSAndroid Build Coastguard Worker     void registerChild(std::unique_ptr<GrFragmentProcessor> child,
403*c8dee2aaSAndroid Build Coastguard Worker                        SkSL::SampleUsage sampleUsage = SkSL::SampleUsage::PassThrough());
404*c8dee2aaSAndroid Build Coastguard Worker 
405*c8dee2aaSAndroid Build Coastguard Worker     /**
406*c8dee2aaSAndroid Build Coastguard Worker      * This method takes an existing fragment processor, clones all of its children, and registers
407*c8dee2aaSAndroid Build Coastguard Worker      * the clones as children of this fragment processor.
408*c8dee2aaSAndroid Build Coastguard Worker      */
409*c8dee2aaSAndroid Build Coastguard Worker     void cloneAndRegisterAllChildProcessors(const GrFragmentProcessor& src);
410*c8dee2aaSAndroid Build Coastguard Worker 
411*c8dee2aaSAndroid Build Coastguard Worker     // FP implementations must call this function if their matching ProgramImpl's emitCode()
412*c8dee2aaSAndroid Build Coastguard Worker     // function uses the EmitArgs::fSampleCoord variable in generated SkSL.
setUsesSampleCoordsDirectly()413*c8dee2aaSAndroid Build Coastguard Worker     void setUsesSampleCoordsDirectly() {
414*c8dee2aaSAndroid Build Coastguard Worker         fFlags |= kUsesSampleCoordsDirectly_Flag;
415*c8dee2aaSAndroid Build Coastguard Worker     }
416*c8dee2aaSAndroid Build Coastguard Worker 
417*c8dee2aaSAndroid Build Coastguard Worker     // FP implementations must set this flag if their ProgramImpl's emitCode() function calls
418*c8dee2aaSAndroid Build Coastguard Worker     // dstColor() to read back the framebuffer.
setWillReadDstColor()419*c8dee2aaSAndroid Build Coastguard Worker     void setWillReadDstColor() {
420*c8dee2aaSAndroid Build Coastguard Worker         fFlags |= kWillReadDstColor_Flag;
421*c8dee2aaSAndroid Build Coastguard Worker     }
422*c8dee2aaSAndroid Build Coastguard Worker 
423*c8dee2aaSAndroid Build Coastguard Worker     // FP implementations must set this flag if their ProgramImpl's emitCode() function emits a
424*c8dee2aaSAndroid Build Coastguard Worker     // blend function (taking two color inputs instead of just one).
setIsBlendFunction()425*c8dee2aaSAndroid Build Coastguard Worker     void setIsBlendFunction() {
426*c8dee2aaSAndroid Build Coastguard Worker         fFlags |= kIsBlendFunction_Flag;
427*c8dee2aaSAndroid Build Coastguard Worker     }
428*c8dee2aaSAndroid Build Coastguard Worker 
mergeOptimizationFlags(OptimizationFlags flags)429*c8dee2aaSAndroid Build Coastguard Worker     void mergeOptimizationFlags(OptimizationFlags flags) {
430*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT((flags & ~kAll_OptimizationFlags) == 0);
431*c8dee2aaSAndroid Build Coastguard Worker         fFlags &= (flags | ~kAll_OptimizationFlags);
432*c8dee2aaSAndroid Build Coastguard Worker     }
433*c8dee2aaSAndroid Build Coastguard Worker 
434*c8dee2aaSAndroid Build Coastguard Worker private:
constantOutputForConstantInput(const SkPMColor4f &)435*c8dee2aaSAndroid Build Coastguard Worker     virtual SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& /* inputColor */) const {
436*c8dee2aaSAndroid Build Coastguard Worker         SK_ABORT("Subclass must override this if advertising this optimization.");
437*c8dee2aaSAndroid Build Coastguard Worker     }
438*c8dee2aaSAndroid Build Coastguard Worker 
439*c8dee2aaSAndroid Build Coastguard Worker     /**
440*c8dee2aaSAndroid Build Coastguard Worker      * Returns a new instance of the appropriate ProgramImpl subclass for the given
441*c8dee2aaSAndroid Build Coastguard Worker      * GrFragmentProcessor. It will emit the appropriate code and live with the cached program
442*c8dee2aaSAndroid Build Coastguard Worker      * to setup uniform data for each draw that uses the program.
443*c8dee2aaSAndroid Build Coastguard Worker      */
444*c8dee2aaSAndroid Build Coastguard Worker     virtual std::unique_ptr<ProgramImpl> onMakeProgramImpl() const = 0;
445*c8dee2aaSAndroid Build Coastguard Worker 
446*c8dee2aaSAndroid Build Coastguard Worker     virtual void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const = 0;
447*c8dee2aaSAndroid Build Coastguard Worker 
448*c8dee2aaSAndroid Build Coastguard Worker     /**
449*c8dee2aaSAndroid Build Coastguard Worker      * Subclass implements this to support isEqual(). It will only be called if it is known that
450*c8dee2aaSAndroid Build Coastguard Worker      * the two processors are of the same subclass (i.e. have the same ClassID).
451*c8dee2aaSAndroid Build Coastguard Worker      */
452*c8dee2aaSAndroid Build Coastguard Worker     virtual bool onIsEqual(const GrFragmentProcessor&) const = 0;
453*c8dee2aaSAndroid Build Coastguard Worker 
454*c8dee2aaSAndroid Build Coastguard Worker     enum PrivateFlags {
455*c8dee2aaSAndroid Build Coastguard Worker         kFirstPrivateFlag = kAll_OptimizationFlags + 1,
456*c8dee2aaSAndroid Build Coastguard Worker 
457*c8dee2aaSAndroid Build Coastguard Worker         // Propagates up the FP tree to either root or first explicit sample usage.
458*c8dee2aaSAndroid Build Coastguard Worker         kUsesSampleCoordsIndirectly_Flag = kFirstPrivateFlag,
459*c8dee2aaSAndroid Build Coastguard Worker 
460*c8dee2aaSAndroid Build Coastguard Worker         // Does not propagate at all. It means this FP uses its input sample coords in some way.
461*c8dee2aaSAndroid Build Coastguard Worker         // Note passthrough and matrix sampling of children don't count as a usage of the coords.
462*c8dee2aaSAndroid Build Coastguard Worker         // Because indirect sampling stops at an explicit sample usage it is imperative that a FP
463*c8dee2aaSAndroid Build Coastguard Worker         // that calculates explicit coords for its children using its own sample coords sets this.
464*c8dee2aaSAndroid Build Coastguard Worker         kUsesSampleCoordsDirectly_Flag = kFirstPrivateFlag << 1,
465*c8dee2aaSAndroid Build Coastguard Worker 
466*c8dee2aaSAndroid Build Coastguard Worker         // Does not propagate at all.
467*c8dee2aaSAndroid Build Coastguard Worker         kIsBlendFunction_Flag = kFirstPrivateFlag << 2,
468*c8dee2aaSAndroid Build Coastguard Worker 
469*c8dee2aaSAndroid Build Coastguard Worker         // Propagates up the FP tree to the root.
470*c8dee2aaSAndroid Build Coastguard Worker         kWillReadDstColor_Flag = kFirstPrivateFlag << 3,
471*c8dee2aaSAndroid Build Coastguard Worker     };
472*c8dee2aaSAndroid Build Coastguard Worker 
473*c8dee2aaSAndroid Build Coastguard Worker     skia_private::STArray<1, std::unique_ptr<GrFragmentProcessor>, true> fChildProcessors;
474*c8dee2aaSAndroid Build Coastguard Worker     const GrFragmentProcessor* fParent = nullptr;
475*c8dee2aaSAndroid Build Coastguard Worker     uint32_t fFlags = 0;
476*c8dee2aaSAndroid Build Coastguard Worker     SkSL::SampleUsage fUsage;
477*c8dee2aaSAndroid Build Coastguard Worker 
478*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = GrProcessor;
479*c8dee2aaSAndroid Build Coastguard Worker };
480*c8dee2aaSAndroid Build Coastguard Worker 
481*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
482*c8dee2aaSAndroid Build Coastguard Worker 
483*c8dee2aaSAndroid Build Coastguard Worker class GrFragmentProcessor::ProgramImpl {
484*c8dee2aaSAndroid Build Coastguard Worker public:
485*c8dee2aaSAndroid Build Coastguard Worker     ProgramImpl() = default;
486*c8dee2aaSAndroid Build Coastguard Worker 
487*c8dee2aaSAndroid Build Coastguard Worker     virtual ~ProgramImpl() = default;
488*c8dee2aaSAndroid Build Coastguard Worker 
489*c8dee2aaSAndroid Build Coastguard Worker     using UniformHandle = GrGLSLUniformHandler::UniformHandle;
490*c8dee2aaSAndroid Build Coastguard Worker     using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
491*c8dee2aaSAndroid Build Coastguard Worker 
492*c8dee2aaSAndroid Build Coastguard Worker     /** Called when the program stage should insert its code into the shaders. The code in each
493*c8dee2aaSAndroid Build Coastguard Worker         shader will be in its own block ({}) and so locally scoped names will not collide across
494*c8dee2aaSAndroid Build Coastguard Worker         stages.
495*c8dee2aaSAndroid Build Coastguard Worker 
496*c8dee2aaSAndroid Build Coastguard Worker         @param fragBuilder       Interface used to emit code in the shaders.
497*c8dee2aaSAndroid Build Coastguard Worker         @param uniformHandler    Interface used for accessing information about our uniforms
498*c8dee2aaSAndroid Build Coastguard Worker         @param caps              The capabilities of the GPU which will render this FP
499*c8dee2aaSAndroid Build Coastguard Worker         @param fp                The processor that generated this program stage.
500*c8dee2aaSAndroid Build Coastguard Worker         @param inputColor        A half4 that holds the input color to the stage in the FS (or the
501*c8dee2aaSAndroid Build Coastguard Worker                                  source color, for blend processors). nullptr inputs are converted
502*c8dee2aaSAndroid Build Coastguard Worker                                  to "half4(1.0)" (solid white) during construction.
503*c8dee2aaSAndroid Build Coastguard Worker                                  TODO: Better system for communicating optimization info
504*c8dee2aaSAndroid Build Coastguard Worker                                  (e.g. input color is solid white, trans black, known to be opaque,
505*c8dee2aaSAndroid Build Coastguard Worker                                  etc.) that allows the processor to communicate back similar known
506*c8dee2aaSAndroid Build Coastguard Worker                                  info about its output.
507*c8dee2aaSAndroid Build Coastguard Worker         @param destColor         A half4 that holds the dest color to the stage. Only meaningful
508*c8dee2aaSAndroid Build Coastguard Worker                                  when the "is blend processor" FP flag is set.
509*c8dee2aaSAndroid Build Coastguard Worker         @param sampleCoord       The name of a local coord reference to a float2 variable. Only
510*c8dee2aaSAndroid Build Coastguard Worker                                  meaningful when the "references sample coords" FP flag is set.
511*c8dee2aaSAndroid Build Coastguard Worker      */
512*c8dee2aaSAndroid Build Coastguard Worker     struct EmitArgs {
EmitArgsEmitArgs513*c8dee2aaSAndroid Build Coastguard Worker         EmitArgs(GrGLSLFPFragmentBuilder* fragBuilder,
514*c8dee2aaSAndroid Build Coastguard Worker                  GrGLSLUniformHandler* uniformHandler,
515*c8dee2aaSAndroid Build Coastguard Worker                  const GrShaderCaps* caps,
516*c8dee2aaSAndroid Build Coastguard Worker                  const GrFragmentProcessor& fp,
517*c8dee2aaSAndroid Build Coastguard Worker                  const char* inputColor,
518*c8dee2aaSAndroid Build Coastguard Worker                  const char* destColor,
519*c8dee2aaSAndroid Build Coastguard Worker                  const char* sampleCoord)
520*c8dee2aaSAndroid Build Coastguard Worker                 : fFragBuilder(fragBuilder)
521*c8dee2aaSAndroid Build Coastguard Worker                 , fUniformHandler(uniformHandler)
522*c8dee2aaSAndroid Build Coastguard Worker                 , fShaderCaps(caps)
523*c8dee2aaSAndroid Build Coastguard Worker                 , fFp(fp)
524*c8dee2aaSAndroid Build Coastguard Worker                 , fInputColor(inputColor ? inputColor : "half4(1.0)")
525*c8dee2aaSAndroid Build Coastguard Worker                 , fDestColor(destColor)
526*c8dee2aaSAndroid Build Coastguard Worker                 , fSampleCoord(sampleCoord) {}
527*c8dee2aaSAndroid Build Coastguard Worker         GrGLSLFPFragmentBuilder* fFragBuilder;
528*c8dee2aaSAndroid Build Coastguard Worker         GrGLSLUniformHandler* fUniformHandler;
529*c8dee2aaSAndroid Build Coastguard Worker         const GrShaderCaps* fShaderCaps;
530*c8dee2aaSAndroid Build Coastguard Worker         const GrFragmentProcessor& fFp;
531*c8dee2aaSAndroid Build Coastguard Worker         const char* fInputColor;
532*c8dee2aaSAndroid Build Coastguard Worker         const char* fDestColor;
533*c8dee2aaSAndroid Build Coastguard Worker         const char* fSampleCoord;
534*c8dee2aaSAndroid Build Coastguard Worker     };
535*c8dee2aaSAndroid Build Coastguard Worker 
536*c8dee2aaSAndroid Build Coastguard Worker     virtual void emitCode(EmitArgs&) = 0;
537*c8dee2aaSAndroid Build Coastguard Worker 
538*c8dee2aaSAndroid Build Coastguard Worker     // This does not recurse to any attached child processors. Recursing the entire processor tree
539*c8dee2aaSAndroid Build Coastguard Worker     // is the responsibility of the caller.
540*c8dee2aaSAndroid Build Coastguard Worker     void setData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor);
541*c8dee2aaSAndroid Build Coastguard Worker 
numChildProcessors()542*c8dee2aaSAndroid Build Coastguard Worker     int numChildProcessors() const { return fChildProcessors.size(); }
543*c8dee2aaSAndroid Build Coastguard Worker 
childProcessor(int index)544*c8dee2aaSAndroid Build Coastguard Worker     ProgramImpl* childProcessor(int index) const { return fChildProcessors[index].get(); }
545*c8dee2aaSAndroid Build Coastguard Worker 
setFunctionName(SkString name)546*c8dee2aaSAndroid Build Coastguard Worker     void setFunctionName(SkString name) {
547*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(fFunctionName.isEmpty());
548*c8dee2aaSAndroid Build Coastguard Worker         fFunctionName = std::move(name);
549*c8dee2aaSAndroid Build Coastguard Worker     }
550*c8dee2aaSAndroid Build Coastguard Worker 
functionName()551*c8dee2aaSAndroid Build Coastguard Worker     const char* functionName() const {
552*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!fFunctionName.isEmpty());
553*c8dee2aaSAndroid Build Coastguard Worker         return fFunctionName.c_str();
554*c8dee2aaSAndroid Build Coastguard Worker     }
555*c8dee2aaSAndroid Build Coastguard Worker 
556*c8dee2aaSAndroid Build Coastguard Worker     // Invoke the child with the default input and destination colors (solid white)
557*c8dee2aaSAndroid Build Coastguard Worker     inline SkString invokeChild(int childIndex,
558*c8dee2aaSAndroid Build Coastguard Worker                                 EmitArgs& parentArgs,
559*c8dee2aaSAndroid Build Coastguard Worker                                 std::string_view skslCoords = {}) {
560*c8dee2aaSAndroid Build Coastguard Worker         return this->invokeChild(childIndex,
561*c8dee2aaSAndroid Build Coastguard Worker                                  /*inputColor=*/nullptr,
562*c8dee2aaSAndroid Build Coastguard Worker                                  /*destColor=*/nullptr,
563*c8dee2aaSAndroid Build Coastguard Worker                                  parentArgs,
564*c8dee2aaSAndroid Build Coastguard Worker                                  skslCoords);
565*c8dee2aaSAndroid Build Coastguard Worker     }
566*c8dee2aaSAndroid Build Coastguard Worker 
invokeChildWithMatrix(int childIndex,EmitArgs & parentArgs)567*c8dee2aaSAndroid Build Coastguard Worker     inline SkString invokeChildWithMatrix(int childIndex, EmitArgs& parentArgs) {
568*c8dee2aaSAndroid Build Coastguard Worker         return this->invokeChildWithMatrix(childIndex,
569*c8dee2aaSAndroid Build Coastguard Worker                                            /*inputColor=*/nullptr,
570*c8dee2aaSAndroid Build Coastguard Worker                                            /*destColor=*/nullptr,
571*c8dee2aaSAndroid Build Coastguard Worker                                            parentArgs);
572*c8dee2aaSAndroid Build Coastguard Worker     }
573*c8dee2aaSAndroid Build Coastguard Worker 
574*c8dee2aaSAndroid Build Coastguard Worker     // Invoke the child with the default destination color (solid white)
575*c8dee2aaSAndroid Build Coastguard Worker     inline SkString invokeChild(int childIndex,
576*c8dee2aaSAndroid Build Coastguard Worker                                 const char* inputColor,
577*c8dee2aaSAndroid Build Coastguard Worker                                 EmitArgs& parentArgs,
578*c8dee2aaSAndroid Build Coastguard Worker                                 std::string_view skslCoords = {}) {
579*c8dee2aaSAndroid Build Coastguard Worker         return this->invokeChild(childIndex,
580*c8dee2aaSAndroid Build Coastguard Worker                                  inputColor,
581*c8dee2aaSAndroid Build Coastguard Worker                                  /*destColor=*/nullptr,
582*c8dee2aaSAndroid Build Coastguard Worker                                  parentArgs,
583*c8dee2aaSAndroid Build Coastguard Worker                                  skslCoords);
584*c8dee2aaSAndroid Build Coastguard Worker     }
585*c8dee2aaSAndroid Build Coastguard Worker 
invokeChildWithMatrix(int childIndex,const char * inputColor,EmitArgs & parentArgs)586*c8dee2aaSAndroid Build Coastguard Worker     inline SkString invokeChildWithMatrix(int childIndex,
587*c8dee2aaSAndroid Build Coastguard Worker                                           const char* inputColor,
588*c8dee2aaSAndroid Build Coastguard Worker                                           EmitArgs& parentArgs) {
589*c8dee2aaSAndroid Build Coastguard Worker         return this->invokeChildWithMatrix(childIndex,
590*c8dee2aaSAndroid Build Coastguard Worker                                            inputColor,
591*c8dee2aaSAndroid Build Coastguard Worker                                            /*destColor=*/nullptr,
592*c8dee2aaSAndroid Build Coastguard Worker                                            parentArgs);
593*c8dee2aaSAndroid Build Coastguard Worker     }
594*c8dee2aaSAndroid Build Coastguard Worker 
595*c8dee2aaSAndroid Build Coastguard Worker     /** Invokes a child proc in its own scope. Pass in the parent's EmitArgs and invokeChild will
596*c8dee2aaSAndroid Build Coastguard Worker      *  automatically extract the coords and samplers of that child and pass them on to the child's
597*c8dee2aaSAndroid Build Coastguard Worker      *  emitCode(). Also, any uniforms or functions emitted by the child will have their names
598*c8dee2aaSAndroid Build Coastguard Worker      *  mangled to prevent redefinitions. The returned string contains the output color (as a call
599*c8dee2aaSAndroid Build Coastguard Worker      *  to the child's helper function). It is legal to pass nullptr as inputColor, since all
600*c8dee2aaSAndroid Build Coastguard Worker      *  fragment processors are required to work without an input color.
601*c8dee2aaSAndroid Build Coastguard Worker      *
602*c8dee2aaSAndroid Build Coastguard Worker      *  When skslCoords is empty, the child is invoked at the sample coordinates from parentArgs.
603*c8dee2aaSAndroid Build Coastguard Worker      *  When skslCoords is not empty, is must be an SkSL expression that evaluates to a float2.
604*c8dee2aaSAndroid Build Coastguard Worker      *  That expression is passed to the child's processor function as the "_coords" argument.
605*c8dee2aaSAndroid Build Coastguard Worker      */
606*c8dee2aaSAndroid Build Coastguard Worker     SkString invokeChild(int childIndex,
607*c8dee2aaSAndroid Build Coastguard Worker                          const char* inputColor,
608*c8dee2aaSAndroid Build Coastguard Worker                          const char* destColor,
609*c8dee2aaSAndroid Build Coastguard Worker                          EmitArgs& parentArgs,
610*c8dee2aaSAndroid Build Coastguard Worker                          std::string_view skslCoords = {});
611*c8dee2aaSAndroid Build Coastguard Worker 
612*c8dee2aaSAndroid Build Coastguard Worker     /**
613*c8dee2aaSAndroid Build Coastguard Worker      * As invokeChild, but transforms the coordinates according to the matrix expression attached
614*c8dee2aaSAndroid Build Coastguard Worker      * to the child's SampleUsage object. This is only valid if the child is sampled with a
615*c8dee2aaSAndroid Build Coastguard Worker      * const-uniform matrix.
616*c8dee2aaSAndroid Build Coastguard Worker      */
617*c8dee2aaSAndroid Build Coastguard Worker     SkString invokeChildWithMatrix(int childIndex,
618*c8dee2aaSAndroid Build Coastguard Worker                                    const char* inputColor,
619*c8dee2aaSAndroid Build Coastguard Worker                                    const char* destColor,
620*c8dee2aaSAndroid Build Coastguard Worker                                    EmitArgs& parentArgs);
621*c8dee2aaSAndroid Build Coastguard Worker 
622*c8dee2aaSAndroid Build Coastguard Worker     /**
623*c8dee2aaSAndroid Build Coastguard Worker      * Pre-order traversal of a GLSLFP hierarchy, or of multiple trees with roots in an array of
624*c8dee2aaSAndroid Build Coastguard Worker      * GLSLFPS. If initialized with an array color followed by coverage processors installed in a
625*c8dee2aaSAndroid Build Coastguard Worker      * program thenthe iteration order will agree with a GrFragmentProcessor::Iter initialized with
626*c8dee2aaSAndroid Build Coastguard Worker      * a GrPipeline that produces the same program key.
627*c8dee2aaSAndroid Build Coastguard Worker      */
628*c8dee2aaSAndroid Build Coastguard Worker     class Iter {
629*c8dee2aaSAndroid Build Coastguard Worker     public:
630*c8dee2aaSAndroid Build Coastguard Worker         Iter(std::unique_ptr<ProgramImpl> fps[], int cnt);
Iter(ProgramImpl & fp)631*c8dee2aaSAndroid Build Coastguard Worker         Iter(ProgramImpl& fp) { fFPStack.push_back(&fp); }
632*c8dee2aaSAndroid Build Coastguard Worker 
633*c8dee2aaSAndroid Build Coastguard Worker         ProgramImpl& operator*() const;
634*c8dee2aaSAndroid Build Coastguard Worker         ProgramImpl* operator->() const;
635*c8dee2aaSAndroid Build Coastguard Worker         Iter& operator++();
636*c8dee2aaSAndroid Build Coastguard Worker         explicit operator bool() const { return !fFPStack.empty(); }
637*c8dee2aaSAndroid Build Coastguard Worker 
638*c8dee2aaSAndroid Build Coastguard Worker         // Because each iterator carries a stack we want to avoid copies.
639*c8dee2aaSAndroid Build Coastguard Worker         Iter(const Iter&) = delete;
640*c8dee2aaSAndroid Build Coastguard Worker         Iter& operator=(const Iter&) = delete;
641*c8dee2aaSAndroid Build Coastguard Worker 
642*c8dee2aaSAndroid Build Coastguard Worker     private:
643*c8dee2aaSAndroid Build Coastguard Worker         skia_private::STArray<4, ProgramImpl*, true> fFPStack;
644*c8dee2aaSAndroid Build Coastguard Worker     };
645*c8dee2aaSAndroid Build Coastguard Worker 
646*c8dee2aaSAndroid Build Coastguard Worker private:
647*c8dee2aaSAndroid Build Coastguard Worker     /**
648*c8dee2aaSAndroid Build Coastguard Worker      * A ProgramImpl instance can be reused with any GrFragmentProcessor that produces the same
649*c8dee2aaSAndroid Build Coastguard Worker      * the same key; this function reads data from a GrFragmentProcessor and uploads any
650*c8dee2aaSAndroid Build Coastguard Worker      * uniform variables required by the shaders created in emitCode(). The GrFragmentProcessor
651*c8dee2aaSAndroid Build Coastguard Worker      * parameter is guaranteed to be of the same type that created this ProgramImpl and
652*c8dee2aaSAndroid Build Coastguard Worker      * to have an identical key as the one that created this ProgramImpl.
653*c8dee2aaSAndroid Build Coastguard Worker      */
onSetData(const GrGLSLProgramDataManager &,const GrFragmentProcessor &)654*c8dee2aaSAndroid Build Coastguard Worker     virtual void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) {}
655*c8dee2aaSAndroid Build Coastguard Worker 
656*c8dee2aaSAndroid Build Coastguard Worker     // The (mangled) name of our entry-point function
657*c8dee2aaSAndroid Build Coastguard Worker     SkString fFunctionName;
658*c8dee2aaSAndroid Build Coastguard Worker 
659*c8dee2aaSAndroid Build Coastguard Worker     skia_private::TArray<std::unique_ptr<ProgramImpl>, true> fChildProcessors;
660*c8dee2aaSAndroid Build Coastguard Worker 
661*c8dee2aaSAndroid Build Coastguard Worker     friend class GrFragmentProcessor;
662*c8dee2aaSAndroid Build Coastguard Worker };
663*c8dee2aaSAndroid Build Coastguard Worker 
664*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
665*c8dee2aaSAndroid Build Coastguard Worker 
SK_MAKE_BITFIELD_OPS(GrFragmentProcessor::OptimizationFlags)666*c8dee2aaSAndroid Build Coastguard Worker SK_MAKE_BITFIELD_OPS(GrFragmentProcessor::OptimizationFlags)
667*c8dee2aaSAndroid Build Coastguard Worker 
668*c8dee2aaSAndroid Build Coastguard Worker static inline GrFPResult GrFPFailure(std::unique_ptr<GrFragmentProcessor> fp) {
669*c8dee2aaSAndroid Build Coastguard Worker     return {false, std::move(fp)};
670*c8dee2aaSAndroid Build Coastguard Worker }
GrFPSuccess(std::unique_ptr<GrFragmentProcessor> fp)671*c8dee2aaSAndroid Build Coastguard Worker static inline GrFPResult GrFPSuccess(std::unique_ptr<GrFragmentProcessor> fp) {
672*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fp);
673*c8dee2aaSAndroid Build Coastguard Worker     return {true, std::move(fp)};
674*c8dee2aaSAndroid Build Coastguard Worker }
675*c8dee2aaSAndroid Build Coastguard Worker // Equivalent to GrFPSuccess except it allows the returned fragment processor to be null.
GrFPNullableSuccess(std::unique_ptr<GrFragmentProcessor> fp)676*c8dee2aaSAndroid Build Coastguard Worker static inline GrFPResult GrFPNullableSuccess(std::unique_ptr<GrFragmentProcessor> fp) {
677*c8dee2aaSAndroid Build Coastguard Worker     return {true, std::move(fp)};
678*c8dee2aaSAndroid Build Coastguard Worker }
679*c8dee2aaSAndroid Build Coastguard Worker 
680*c8dee2aaSAndroid Build Coastguard Worker #endif
681