Line data Source code
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 GrGLSLFragmentShaderBuilder_DEFINED
9 : #define GrGLSLFragmentShaderBuilder_DEFINED
10 :
11 : #include "GrBlend.h"
12 : #include "GrGLSLShaderBuilder.h"
13 : #include "GrProcessor.h"
14 :
15 : class GrRenderTarget;
16 : class GrGLSLVarying;
17 :
18 : /*
19 : * This base class encapsulates the common functionality which all processors use to build fragment
20 : * shaders.
21 : */
22 : class GrGLSLFragmentBuilder : public GrGLSLShaderBuilder {
23 : public:
24 0 : GrGLSLFragmentBuilder(GrGLSLProgramBuilder* program) : INHERITED(program) {}
25 0 : virtual ~GrGLSLFragmentBuilder() {}
26 :
27 : /**
28 : * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
29 : * if code is added that uses one of these features without calling enableFeature()
30 : */
31 : enum GLSLFeature {
32 : kMultisampleInterpolation_GLSLFeature
33 : };
34 :
35 : /**
36 : * If the feature is supported then true is returned and any necessary #extension declarations
37 : * are added to the shaders. If the feature is not supported then false will be returned.
38 : */
39 : virtual bool enableFeature(GLSLFeature) = 0;
40 :
41 : /**
42 : * This returns a variable name to access the 2D, perspective correct version of the coords in
43 : * the fragment shader. The passed in coordinates must either be of type kVec2f or kVec3f. If
44 : * the coordinates are 3-dimensional, it a perspective divide into is emitted into the
45 : * fragment shader (xy / z) to convert them to 2D.
46 : */
47 : virtual SkString ensureCoords2D(const GrShaderVar&) = 0;
48 :
49 : // TODO: remove this method.
50 : void declAppendf(const char* fmt, ...);
51 :
52 : private:
53 : typedef GrGLSLShaderBuilder INHERITED;
54 : };
55 :
56 : /*
57 : * This class is used by fragment processors to build their fragment code.
58 : */
59 0 : class GrGLSLFPFragmentBuilder : virtual public GrGLSLFragmentBuilder {
60 : public:
61 : /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
62 0 : GrGLSLFPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
63 :
64 : enum Coordinates {
65 : kSkiaDevice_Coordinates,
66 : kGLSLWindow_Coordinates,
67 :
68 : kLast_Coordinates = kGLSLWindow_Coordinates
69 : };
70 :
71 : /**
72 : * Appends the offset from the center of the pixel to a specified sample.
73 : *
74 : * @param sampleIdx GLSL expression of the sample index.
75 : * @param Coordinates Coordinate space in which to emit the offset.
76 : *
77 : * A processor must call setWillUseSampleLocations in its constructor before using this method.
78 : */
79 : virtual void appendOffsetToSample(const char* sampleIdx, Coordinates) = 0;
80 :
81 : /**
82 : * Subtracts sample coverage from the fragment. Any sample whose corresponding bit is not found
83 : * in the mask will not be written out to the framebuffer.
84 : *
85 : * @param mask int that contains the sample mask. Bit N corresponds to the Nth sample.
86 : * @param invert perform a bit-wise NOT on the provided mask before applying it?
87 : *
88 : * Requires GLSL support for sample variables.
89 : */
90 : virtual void maskSampleCoverage(const char* mask, bool invert = false) = 0;
91 :
92 : /** Returns a variable name that represents a vector to the nearest edge of the shape, in source
93 : space coordinates. */
94 : virtual const char* distanceVectorName() const = 0;
95 :
96 : /**
97 : * Overrides the default precision for the entire fragment program. Processors that require
98 : * high precision input (eg from incoming texture samples) may use this. For calculations that
99 : * are limited to a single processor's code, it is better to annotate individual declarations.
100 : */
101 : virtual void elevateDefaultPrecision(GrSLPrecision) = 0;
102 :
103 : /**
104 : * Fragment procs with child procs should call these functions before/after calling emitCode
105 : * on a child proc.
106 : */
107 : virtual void onBeforeChildProcEmitCode() = 0;
108 : virtual void onAfterChildProcEmitCode() = 0;
109 :
110 : virtual const SkString& getMangleString() const = 0;
111 : };
112 :
113 : /*
114 : * This class is used by primitive processors to build their fragment code.
115 : */
116 0 : class GrGLSLPPFragmentBuilder : public GrGLSLFPFragmentBuilder {
117 : public:
118 : /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
119 0 : GrGLSLPPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
120 :
121 : /**
122 : * Overrides the fragment's sample coverage. The provided mask determines which samples will now
123 : * be written out to the framebuffer. Note that this mask can be reduced by a future call to
124 : * maskSampleCoverage.
125 : *
126 : * If a primitive processor uses this method, it must guarantee that every codepath through the
127 : * shader overrides the sample mask at some point.
128 : *
129 : * @param mask int that contains the new coverage mask. Bit N corresponds to the Nth sample.
130 : *
131 : * Requires NV_sample_mask_override_coverage.
132 : */
133 : virtual void overrideSampleCoverage(const char* mask) = 0;
134 : };
135 :
136 : /*
137 : * This class is used by Xfer processors to build their fragment code.
138 : */
139 0 : class GrGLSLXPFragmentBuilder : virtual public GrGLSLFragmentBuilder {
140 : public:
141 : /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
142 0 : GrGLSLXPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
143 :
144 : virtual bool hasCustomColorOutput() const = 0;
145 : virtual bool hasSecondaryOutput() const = 0;
146 :
147 : /** Returns the variable name that holds the color of the destination pixel. This may be nullptr
148 : * if no effect advertised that it will read the destination. */
149 : virtual const char* dstColor() = 0;
150 :
151 : /** Adds any necessary layout qualifiers in order to legalize the supplied blend equation with
152 : this shader. It is only legal to call this method with an advanced blend equation, and only
153 : if these equations are supported. */
154 : virtual void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) = 0;
155 : };
156 :
157 : /*
158 : * This class implements the various fragment builder interfaces.
159 : */
160 0 : class GrGLSLFragmentShaderBuilder : public GrGLSLPPFragmentBuilder, public GrGLSLXPFragmentBuilder {
161 : public:
162 : /** Returns a nonzero key for a surface's origin. This should only be called if a processor will
163 : use the fragment position and/or sample locations. */
164 : static uint8_t KeyForSurfaceOrigin(GrSurfaceOrigin);
165 :
166 : GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program);
167 :
168 : // Shared GrGLSLFragmentBuilder interface.
169 : bool enableFeature(GLSLFeature) override;
170 : virtual SkString ensureCoords2D(const GrShaderVar&) override;
171 : const char* distanceVectorName() const override;
172 :
173 : // GrGLSLFPFragmentBuilder interface.
174 : void appendOffsetToSample(const char* sampleIdx, Coordinates) override;
175 : void maskSampleCoverage(const char* mask, bool invert = false) override;
176 : void overrideSampleCoverage(const char* mask) override;
177 : void elevateDefaultPrecision(GrSLPrecision) override;
178 0 : const SkString& getMangleString() const override { return fMangleString; }
179 : void onBeforeChildProcEmitCode() override;
180 : void onAfterChildProcEmitCode() override;
181 :
182 : // GrGLSLXPFragmentBuilder interface.
183 0 : bool hasCustomColorOutput() const override { return fHasCustomColorOutput; }
184 0 : bool hasSecondaryOutput() const override { return fHasSecondaryOutput; }
185 : const char* dstColor() override;
186 : void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override;
187 :
188 : private:
189 : // Private public interface, used by GrGLProgramBuilder to build a fragment shader
190 : void enableCustomOutput();
191 : void enableSecondaryOutput();
192 : const char* getPrimaryColorOutputName() const;
193 : const char* getSecondaryColorOutputName() const;
194 :
195 : #ifdef SK_DEBUG
196 : // As GLSLProcessors emit code, there are some conditions we need to verify. We use the below
197 : // state to track this. The reset call is called per processor emitted.
198 0 : GrProcessor::RequiredFeatures usedProcessorFeatures() const { return fUsedProcessorFeatures; }
199 0 : bool hasReadDstColor() const { return fHasReadDstColor; }
200 0 : void resetVerification() {
201 0 : fUsedProcessorFeatures = GrProcessor::kNone_RequiredFeatures;
202 0 : fHasReadDstColor = false;
203 0 : }
204 : #endif
205 :
206 0 : static const char* DeclaredColorOutputName() { return "sk_FragColor"; }
207 0 : static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryColorOut"; }
208 :
209 : GrSurfaceOrigin getSurfaceOrigin() const;
210 :
211 : void onFinalize() override;
212 : void defineSampleOffsetArray(const char* name, const SkMatrix&);
213 :
214 : static const char* kDstColorName;
215 :
216 : /*
217 : * State that tracks which child proc in the proc tree is currently emitting code. This is
218 : * used to update the fMangleString, which is used to mangle the names of uniforms and functions
219 : * emitted by the proc. fSubstageIndices is a stack: its count indicates how many levels deep
220 : * we are in the tree, and its second-to-last value is the index of the child proc at that
221 : * level which is currently emitting code. For example, if fSubstageIndices = [3, 1, 2, 0], that
222 : * means we're currently emitting code for the base proc's 3rd child's 1st child's 2nd child.
223 : */
224 : SkTArray<int> fSubstageIndices;
225 :
226 : /*
227 : * The mangle string is used to mangle the names of uniforms/functions emitted by the child
228 : * procs so no duplicate uniforms/functions appear in the generated shader program. The mangle
229 : * string is simply based on fSubstageIndices. For example, if fSubstageIndices = [3, 1, 2, 0],
230 : * then the manglestring will be "_c3_c1_c2", and any uniform/function emitted by that proc will
231 : * have "_c3_c1_c2" appended to its name, which can be interpreted as "base proc's 3rd child's
232 : * 1st child's 2nd child".
233 : */
234 : SkString fMangleString;
235 :
236 : bool fSetupFragPosition;
237 : bool fHasCustomColorOutput;
238 : int fCustomColorOutputIndex;
239 : bool fHasSecondaryOutput;
240 : uint8_t fUsedSampleOffsetArrays;
241 : bool fHasInitializedSampleMask;
242 : SkString fDistanceVectorOutput;
243 : GrSLPrecision fDefaultPrecision;
244 :
245 : #ifdef SK_DEBUG
246 : // some state to verify shaders and effects are consistent, this is reset between effects by
247 : // the program creator
248 : GrProcessor::RequiredFeatures fUsedProcessorFeatures;
249 : bool fHasReadDstColor;
250 : #endif
251 :
252 : friend class GrGLSLProgramBuilder;
253 : friend class GrGLProgramBuilder;
254 : };
255 :
256 : #endif
|