blob: 57b8ee91c60631d77f36536e2cacb9ec75e5f89e [file] [log] [blame]
joshualitt30ba4362014-08-21 20:18:45 -07001/*
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
egdaniel2d721d32015-11-11 13:06:05 -08008#ifndef GrGLSLFragmentShaderBuilder_DEFINED
9#define GrGLSLFragmentShaderBuilder_DEFINED
joshualitt47bb3822014-10-07 16:43:25 -070010
egdaniel2d721d32015-11-11 13:06:05 -080011#include "GrGLSLShaderBuilder.h"
joshualitt30ba4362014-08-21 20:18:45 -070012
cdalton87332102016-02-26 12:22:02 -080013#include "GrProcessor.h"
egdaniel7dc4bd02015-10-29 07:57:01 -070014#include "glsl/GrGLSLProcessorTypes.h"
15
egdaniel574a4c12015-11-02 06:22:44 -080016class GrRenderTarget;
egdaniel8dcdedc2015-11-11 06:27:20 -080017class GrGLSLVarying;
joshualitt74077b92014-10-24 11:26:03 -070018
joshualittb0a8a372014-09-23 09:50:21 -070019/*
cdalton85285412016-02-18 12:37:07 -080020 * This base class encapsulates the common functionality which all processors use to build fragment
21 * shaders.
joshualittb0a8a372014-09-23 09:50:21 -070022 */
egdaniel2d721d32015-11-11 13:06:05 -080023class GrGLSLFragmentBuilder : public GrGLSLShaderBuilder {
joshualittb0a8a372014-09-23 09:50:21 -070024public:
cdalton85285412016-02-18 12:37:07 -080025 GrGLSLFragmentBuilder(GrGLSLProgramBuilder* program) : INHERITED(program) {}
egdaniel2d721d32015-11-11 13:06:05 -080026 virtual ~GrGLSLFragmentBuilder() {}
cdalton85285412016-02-18 12:37:07 -080027
joshualittb0a8a372014-09-23 09:50:21 -070028 /**
29 * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
30 * if code is added that uses one of these features without calling enableFeature()
31 */
32 enum GLSLFeature {
cdaltonc08f1962016-02-12 12:14:06 -080033 kStandardDerivatives_GLSLFeature = kLastGLSLPrivateFeature + 1,
cdalton4a98cdb2016-03-01 12:12:20 -080034 kPixelLocalStorage_GLSLFeature,
35 kMultisampleInterpolation_GLSLFeature
joshualittb0a8a372014-09-23 09:50:21 -070036 };
37
38 /**
39 * If the feature is supported then true is returned and any necessary #extension declarations
40 * are added to the shaders. If the feature is not supported then false will be returned.
41 */
42 virtual bool enableFeature(GLSLFeature) = 0;
43
44 /**
45 * This returns a variable name to access the 2D, perspective correct version of the coords in
46 * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
47 * perspective divide into the fragment shader (xy / z) to convert them to 2D.
48 */
egdaniel7dc4bd02015-10-29 07:57:01 -070049 virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords, int index) = 0;
joshualittb0a8a372014-09-23 09:50:21 -070050
51
52 /** Returns a variable name that represents the position of the fragment in the FS. The position
53 is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
54 virtual const char* fragmentPosition() = 0;
55
cdalton85285412016-02-18 12:37:07 -080056 // TODO: remove this method.
ethannicholas22793252016-01-30 09:59:10 -080057 void declAppendf(const char* fmt, ...);
58
joshualittb0a8a372014-09-23 09:50:21 -070059private:
egdaniel2d721d32015-11-11 13:06:05 -080060 typedef GrGLSLShaderBuilder INHERITED;
joshualittb0a8a372014-09-23 09:50:21 -070061};
62
63/*
cdalton85285412016-02-18 12:37:07 -080064 * This class is used by fragment processors to build their fragment code.
joshualittb0a8a372014-09-23 09:50:21 -070065 */
cdalton85285412016-02-18 12:37:07 -080066class GrGLSLFPFragmentBuilder : virtual public GrGLSLFragmentBuilder {
joshualittb0a8a372014-09-23 09:50:21 -070067public:
cdalton85285412016-02-18 12:37:07 -080068 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
69 GrGLSLFPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
joshualitt47bb3822014-10-07 16:43:25 -070070
cdalton85285412016-02-18 12:37:07 -080071 /**
cdalton33ad7012016-02-22 07:55:44 -080072 * Subtracts sample coverage from the fragment. Any sample whose corresponding bit is not found
73 * in the mask will not be written out to the framebuffer.
74 *
75 * @param mask int that contains the sample mask. Bit N corresponds to the Nth sample.
76 * @param invert perform a bit-wise NOT on the provided mask before applying it?
77 *
78 * Requires GLSL support for sample variables.
79 */
80 virtual void maskSampleCoverage(const char* mask, bool invert = false) = 0;
81
82 /**
cdalton85285412016-02-18 12:37:07 -080083 * Fragment procs with child procs should call these functions before/after calling emitCode
84 * on a child proc.
85 */
86 virtual void onBeforeChildProcEmitCode() = 0;
87 virtual void onAfterChildProcEmitCode() = 0;
88
89 virtual const SkString& getMangleString() const = 0;
90};
91
92/*
93 * This class is used by primitive processors to build their fragment code.
94 */
95class GrGLSLPPFragmentBuilder : public GrGLSLFPFragmentBuilder {
96public:
97 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
98 GrGLSLPPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
cdalton33ad7012016-02-22 07:55:44 -080099
100 /**
101 * Overrides the fragment's sample coverage. The provided mask determines which samples will now
102 * be written out to the framebuffer. Note that this mask can be reduced by a future call to
103 * maskSampleCoverage.
104 *
105 * If a primitive processor uses this method, it must guarantee that every codepath through the
106 * shader overrides the sample mask at some point.
107 *
108 * @param mask int that contains the new coverage mask. Bit N corresponds to the Nth sample.
109 *
110 * Requires NV_sample_mask_override_coverage.
111 */
112 virtual void overrideSampleCoverage(const char* mask) = 0;
cdalton85285412016-02-18 12:37:07 -0800113};
114
115/*
116 * This class is used by Xfer processors to build their fragment code.
117 */
118class GrGLSLXPFragmentBuilder : virtual public GrGLSLFragmentBuilder {
119public:
120 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
121 GrGLSLXPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
122
123 virtual bool hasCustomColorOutput() const = 0;
124 virtual bool hasSecondaryOutput() const = 0;
125
126 /** Returns the variable name that holds the color of the destination pixel. This may be nullptr
127 * if no effect advertised that it will read the destination. */
joshualittb0a8a372014-09-23 09:50:21 -0700128 virtual const char* dstColor() = 0;
129
cdalton8917d622015-05-06 13:40:21 -0700130 /** Adds any necessary layout qualifiers in order to legalize the supplied blend equation with
131 this shader. It is only legal to call this method with an advanced blend equation, and only
132 if these equations are supported. */
133 virtual void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) = 0;
joshualittb0a8a372014-09-23 09:50:21 -0700134};
135
cdalton85285412016-02-18 12:37:07 -0800136/*
137 * This class implements the various fragment builder interfaces.
138 */
139class GrGLSLFragmentShaderBuilder : public GrGLSLPPFragmentBuilder, public GrGLSLXPFragmentBuilder {
joshualitt30ba4362014-08-21 20:18:45 -0700140public:
joshualitt30ba4362014-08-21 20:18:45 -0700141 typedef uint8_t FragPosKey;
142
joshualitt30ba4362014-08-21 20:18:45 -0700143 /** Returns a key for reading the fragment location. This should only be called if there is an
144 effect that will requires the fragment position. If the fragment position is not required,
145 the key is 0. */
egdaniel574a4c12015-11-02 06:22:44 -0800146 static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst);
joshualitt30ba4362014-08-21 20:18:45 -0700147
egdaniel2d721d32015-11-11 13:06:05 -0800148 GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program, uint8_t fragPosKey);
joshualitt30ba4362014-08-21 20:18:45 -0700149
cdalton85285412016-02-18 12:37:07 -0800150 // Shared GrGLSLFragmentBuilder interface.
mtklein36352bf2015-03-25 18:17:31 -0700151 bool enableFeature(GLSLFeature) override;
egdaniel7dc4bd02015-10-29 07:57:01 -0700152 virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords,
mtklein36352bf2015-03-25 18:17:31 -0700153 int index) override;
154 const char* fragmentPosition() override;
joshualittdb0d3ca2014-10-07 12:42:26 -0700155
cdalton85285412016-02-18 12:37:07 -0800156 // GrGLSLFPFragmentBuilder interface.
cdalton33ad7012016-02-22 07:55:44 -0800157 void maskSampleCoverage(const char* mask, bool invert = false) override;
158 void overrideSampleCoverage(const char* mask) override;
cdalton85285412016-02-18 12:37:07 -0800159 const SkString& getMangleString() const override { return fMangleString; }
160 void onBeforeChildProcEmitCode() override;
161 void onAfterChildProcEmitCode() override;
162
163 // GrGLSLXPFragmentBuilder interface.
164 bool hasCustomColorOutput() const override { return fHasCustomColorOutput; }
165 bool hasSecondaryOutput() const override { return fHasSecondaryOutput; }
166 const char* dstColor() override;
cdalton8917d622015-05-06 13:40:21 -0700167 void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override;
168
joshualitt74077b92014-10-24 11:26:03 -0700169private:
cdalton87332102016-02-26 12:22:02 -0800170 bool hasFragmentPosition() const;
171
joshualitt47bb3822014-10-07 16:43:25 -0700172 // Private public interface, used by GrGLProgramBuilder to build a fragment shader
joshualitt47bb3822014-10-07 16:43:25 -0700173 void enableCustomOutput();
174 void enableSecondaryOutput();
175 const char* getPrimaryColorOutputName() const;
176 const char* getSecondaryColorOutputName() const;
joshualitt47bb3822014-10-07 16:43:25 -0700177
cdalton87332102016-02-26 12:22:02 -0800178#ifdef SK_DEBUG
egdaniel57d3b032015-11-13 11:57:27 -0800179 // As GLSLProcessors emit code, there are some conditions we need to verify. We use the below
joshualitt47bb3822014-10-07 16:43:25 -0700180 // state to track this. The reset call is called per processor emitted.
cdalton87332102016-02-26 12:22:02 -0800181 GrProcessor::RequiredFeatures usedProcessorFeatures() const { return fUsedProcessorFeatures; }
joshualitt47bb3822014-10-07 16:43:25 -0700182 bool hasReadDstColor() const { return fHasReadDstColor; }
cdalton87332102016-02-26 12:22:02 -0800183 void resetVerification() {
184 fUsedProcessorFeatures = GrProcessor::kNone_RequiredFeatures;
joshualitt47bb3822014-10-07 16:43:25 -0700185 fHasReadDstColor = false;
joshualitt47bb3822014-10-07 16:43:25 -0700186 }
cdalton87332102016-02-26 12:22:02 -0800187#endif
joshualitt30ba4362014-08-21 20:18:45 -0700188
egdaniel8dcdedc2015-11-11 06:27:20 -0800189 static const char* DeclaredColorOutputName() { return "fsColorOut"; }
190 static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryColorOut"; }
191
joshualitt74077b92014-10-24 11:26:03 -0700192 /*
193 * An internal call for GrGLProgramBuilder to use to add varyings to the vertex shader
194 */
egdaniel8dcdedc2015-11-11 06:27:20 -0800195 void addVarying(GrGLSLVarying*, GrSLPrecision);
joshualitt74077b92014-10-24 11:26:03 -0700196
egdaniel574a4c12015-11-02 06:22:44 -0800197 void onFinalize() override;
198
joshualitt47bb3822014-10-07 16:43:25 -0700199 // Interpretation of FragPosKey when generating code
joshualitt30ba4362014-08-21 20:18:45 -0700200 enum {
201 kNoFragPosRead_FragPosKey = 0, // The fragment positition will not be needed.
202 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to top-left.
203 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left.
204 };
205
bsalomon6a44c6a2015-05-26 09:49:05 -0700206 static const char* kDstTextureColorName;
joshualitt47bb3822014-10-07 16:43:25 -0700207
cdalton85285412016-02-18 12:37:07 -0800208 /*
209 * State that tracks which child proc in the proc tree is currently emitting code. This is
210 * used to update the fMangleString, which is used to mangle the names of uniforms and functions
211 * emitted by the proc. fSubstageIndices is a stack: its count indicates how many levels deep
212 * we are in the tree, and its second-to-last value is the index of the child proc at that
213 * level which is currently emitting code. For example, if fSubstageIndices = [3, 1, 2, 0], that
214 * means we're currently emitting code for the base proc's 3rd child's 1st child's 2nd child.
215 */
216 SkTArray<int> fSubstageIndices;
217
218 /*
219 * The mangle string is used to mangle the names of uniforms/functions emitted by the child
220 * procs so no duplicate uniforms/functions appear in the generated shader program. The mangle
221 * string is simply based on fSubstageIndices. For example, if fSubstageIndices = [3, 1, 2, 0],
222 * then the manglestring will be "_c3_c1_c2", and any uniform/function emitted by that proc will
223 * have "_c3_c1_c2" appended to its name, which can be interpreted as "base proc's 3rd child's
224 * 1st child's 2nd child".
225 */
226 SkString fMangleString;
227
joshualitt30ba4362014-08-21 20:18:45 -0700228 bool fSetupFragPosition;
229 bool fTopLeftFragPosRead;
cdalton85285412016-02-18 12:37:07 -0800230 bool fHasCustomColorOutput;
joshualittb4384b92014-10-21 12:53:15 -0700231 int fCustomColorOutputIndex;
cdalton85285412016-02-18 12:37:07 -0800232 bool fHasSecondaryOutput;
cdalton33ad7012016-02-22 07:55:44 -0800233 bool fHasInitializedSampleMask;
joshualitt30ba4362014-08-21 20:18:45 -0700234
cdalton87332102016-02-26 12:22:02 -0800235#ifdef SK_DEBUG
joshualitt47bb3822014-10-07 16:43:25 -0700236 // some state to verify shaders and effects are consistent, this is reset between effects by
237 // the program creator
cdalton87332102016-02-26 12:22:02 -0800238 GrProcessor::RequiredFeatures fUsedProcessorFeatures;
joshualitt47bb3822014-10-07 16:43:25 -0700239 bool fHasReadDstColor;
cdalton87332102016-02-26 12:22:02 -0800240#endif
joshualittfe1233c2014-10-07 12:16:35 -0700241
egdanielfa896322016-01-13 12:19:30 -0800242 friend class GrGLSLProgramBuilder;
joshualitt47bb3822014-10-07 16:43:25 -0700243 friend class GrGLProgramBuilder;
joshualitt30ba4362014-08-21 20:18:45 -0700244};
245
246#endif