blob: b9816af71a2a014ea8eb1388443078993c8fa4a5 [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
egdaniel7dc4bd02015-10-29 07:57:01 -070013#include "glsl/GrGLSLProcessorTypes.h"
14
egdaniel574a4c12015-11-02 06:22:44 -080015class GrRenderTarget;
egdaniel8dcdedc2015-11-11 06:27:20 -080016class GrGLSLVarying;
joshualitt74077b92014-10-24 11:26:03 -070017
joshualittb0a8a372014-09-23 09:50:21 -070018/*
cdalton85285412016-02-18 12:37:07 -080019 * This base class encapsulates the common functionality which all processors use to build fragment
20 * shaders.
joshualittb0a8a372014-09-23 09:50:21 -070021 */
egdaniel2d721d32015-11-11 13:06:05 -080022class GrGLSLFragmentBuilder : public GrGLSLShaderBuilder {
joshualittb0a8a372014-09-23 09:50:21 -070023public:
cdalton85285412016-02-18 12:37:07 -080024 GrGLSLFragmentBuilder(GrGLSLProgramBuilder* program) : INHERITED(program) {}
egdaniel2d721d32015-11-11 13:06:05 -080025 virtual ~GrGLSLFragmentBuilder() {}
cdalton85285412016-02-18 12:37:07 -080026
joshualittb0a8a372014-09-23 09:50:21 -070027 /**
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 {
cdaltonc08f1962016-02-12 12:14:06 -080032 kStandardDerivatives_GLSLFeature = kLastGLSLPrivateFeature + 1,
benjaminwagner1751dc72016-02-12 15:20:55 -080033 kPixelLocalStorage_GLSLFeature
joshualittb0a8a372014-09-23 09:50:21 -070034 };
35
36 /**
37 * If the feature is supported then true is returned and any necessary #extension declarations
38 * are added to the shaders. If the feature is not supported then false will be returned.
39 */
40 virtual bool enableFeature(GLSLFeature) = 0;
41
42 /**
43 * This returns a variable name to access the 2D, perspective correct version of the coords in
44 * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
45 * perspective divide into the fragment shader (xy / z) to convert them to 2D.
46 */
egdaniel7dc4bd02015-10-29 07:57:01 -070047 virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords, int index) = 0;
joshualittb0a8a372014-09-23 09:50:21 -070048
49
50 /** Returns a variable name that represents the position of the fragment in the FS. The position
51 is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
52 virtual const char* fragmentPosition() = 0;
53
cdalton85285412016-02-18 12:37:07 -080054 // TODO: remove this method.
ethannicholas22793252016-01-30 09:59:10 -080055 void declAppendf(const char* fmt, ...);
56
joshualittb0a8a372014-09-23 09:50:21 -070057private:
egdaniel2d721d32015-11-11 13:06:05 -080058 typedef GrGLSLShaderBuilder INHERITED;
joshualittb0a8a372014-09-23 09:50:21 -070059};
60
61/*
cdalton85285412016-02-18 12:37:07 -080062 * This class is used by fragment processors to build their fragment code.
joshualittb0a8a372014-09-23 09:50:21 -070063 */
cdalton85285412016-02-18 12:37:07 -080064class GrGLSLFPFragmentBuilder : virtual public GrGLSLFragmentBuilder {
joshualittb0a8a372014-09-23 09:50:21 -070065public:
cdalton85285412016-02-18 12:37:07 -080066 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
67 GrGLSLFPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
joshualitt47bb3822014-10-07 16:43:25 -070068
cdalton85285412016-02-18 12:37:07 -080069 /**
cdalton33ad7012016-02-22 07:55:44 -080070 * Subtracts sample coverage from the fragment. Any sample whose corresponding bit is not found
71 * in the mask will not be written out to the framebuffer.
72 *
73 * @param mask int that contains the sample mask. Bit N corresponds to the Nth sample.
74 * @param invert perform a bit-wise NOT on the provided mask before applying it?
75 *
76 * Requires GLSL support for sample variables.
77 */
78 virtual void maskSampleCoverage(const char* mask, bool invert = false) = 0;
79
80 /**
cdalton85285412016-02-18 12:37:07 -080081 * Fragment procs with child procs should call these functions before/after calling emitCode
82 * on a child proc.
83 */
84 virtual void onBeforeChildProcEmitCode() = 0;
85 virtual void onAfterChildProcEmitCode() = 0;
86
87 virtual const SkString& getMangleString() const = 0;
88};
89
90/*
91 * This class is used by primitive processors to build their fragment code.
92 */
93class GrGLSLPPFragmentBuilder : public GrGLSLFPFragmentBuilder {
94public:
95 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
96 GrGLSLPPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
cdalton33ad7012016-02-22 07:55:44 -080097
98 /**
99 * Overrides the fragment's sample coverage. The provided mask determines which samples will now
100 * be written out to the framebuffer. Note that this mask can be reduced by a future call to
101 * maskSampleCoverage.
102 *
103 * If a primitive processor uses this method, it must guarantee that every codepath through the
104 * shader overrides the sample mask at some point.
105 *
106 * @param mask int that contains the new coverage mask. Bit N corresponds to the Nth sample.
107 *
108 * Requires NV_sample_mask_override_coverage.
109 */
110 virtual void overrideSampleCoverage(const char* mask) = 0;
cdalton85285412016-02-18 12:37:07 -0800111};
112
113/*
114 * This class is used by Xfer processors to build their fragment code.
115 */
116class GrGLSLXPFragmentBuilder : virtual public GrGLSLFragmentBuilder {
117public:
118 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
119 GrGLSLXPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
120
121 virtual bool hasCustomColorOutput() const = 0;
122 virtual bool hasSecondaryOutput() const = 0;
123
124 /** Returns the variable name that holds the color of the destination pixel. This may be nullptr
125 * if no effect advertised that it will read the destination. */
joshualittb0a8a372014-09-23 09:50:21 -0700126 virtual const char* dstColor() = 0;
127
cdalton8917d622015-05-06 13:40:21 -0700128 /** Adds any necessary layout qualifiers in order to legalize the supplied blend equation with
129 this shader. It is only legal to call this method with an advanced blend equation, and only
130 if these equations are supported. */
131 virtual void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) = 0;
joshualittb0a8a372014-09-23 09:50:21 -0700132};
133
cdalton85285412016-02-18 12:37:07 -0800134/*
135 * This class implements the various fragment builder interfaces.
136 */
137class GrGLSLFragmentShaderBuilder : public GrGLSLPPFragmentBuilder, public GrGLSLXPFragmentBuilder {
joshualitt30ba4362014-08-21 20:18:45 -0700138public:
joshualitt30ba4362014-08-21 20:18:45 -0700139 typedef uint8_t FragPosKey;
140
joshualitt30ba4362014-08-21 20:18:45 -0700141 /** Returns a key for reading the fragment location. This should only be called if there is an
142 effect that will requires the fragment position. If the fragment position is not required,
143 the key is 0. */
egdaniel574a4c12015-11-02 06:22:44 -0800144 static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst);
joshualitt30ba4362014-08-21 20:18:45 -0700145
egdaniel2d721d32015-11-11 13:06:05 -0800146 GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program, uint8_t fragPosKey);
joshualitt30ba4362014-08-21 20:18:45 -0700147
cdalton85285412016-02-18 12:37:07 -0800148 // Shared GrGLSLFragmentBuilder interface.
mtklein36352bf2015-03-25 18:17:31 -0700149 bool enableFeature(GLSLFeature) override;
egdaniel7dc4bd02015-10-29 07:57:01 -0700150 virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords,
mtklein36352bf2015-03-25 18:17:31 -0700151 int index) override;
152 const char* fragmentPosition() override;
joshualittdb0d3ca2014-10-07 12:42:26 -0700153
cdalton85285412016-02-18 12:37:07 -0800154 // GrGLSLFPFragmentBuilder interface.
cdalton33ad7012016-02-22 07:55:44 -0800155 void maskSampleCoverage(const char* mask, bool invert = false) override;
156 void overrideSampleCoverage(const char* mask) override;
cdalton85285412016-02-18 12:37:07 -0800157 const SkString& getMangleString() const override { return fMangleString; }
158 void onBeforeChildProcEmitCode() override;
159 void onAfterChildProcEmitCode() override;
160
161 // GrGLSLXPFragmentBuilder interface.
162 bool hasCustomColorOutput() const override { return fHasCustomColorOutput; }
163 bool hasSecondaryOutput() const override { return fHasSecondaryOutput; }
164 const char* dstColor() override;
cdalton8917d622015-05-06 13:40:21 -0700165 void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override;
166
joshualitt74077b92014-10-24 11:26:03 -0700167private:
joshualitt47bb3822014-10-07 16:43:25 -0700168 // Private public interface, used by GrGLProgramBuilder to build a fragment shader
joshualitt47bb3822014-10-07 16:43:25 -0700169 void enableCustomOutput();
170 void enableSecondaryOutput();
171 const char* getPrimaryColorOutputName() const;
172 const char* getSecondaryColorOutputName() const;
joshualitt47bb3822014-10-07 16:43:25 -0700173
egdaniel57d3b032015-11-13 11:57:27 -0800174 // As GLSLProcessors emit code, there are some conditions we need to verify. We use the below
joshualitt47bb3822014-10-07 16:43:25 -0700175 // state to track this. The reset call is called per processor emitted.
176 bool hasReadDstColor() const { return fHasReadDstColor; }
177 bool hasReadFragmentPosition() const { return fHasReadFragmentPosition; }
178 void reset() {
179 fHasReadDstColor = false;
180 fHasReadFragmentPosition = false;
181 }
joshualitt30ba4362014-08-21 20:18:45 -0700182
egdaniel8dcdedc2015-11-11 06:27:20 -0800183 static const char* DeclaredColorOutputName() { return "fsColorOut"; }
184 static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryColorOut"; }
185
joshualitt74077b92014-10-24 11:26:03 -0700186 /*
187 * An internal call for GrGLProgramBuilder to use to add varyings to the vertex shader
188 */
egdaniel8dcdedc2015-11-11 06:27:20 -0800189 void addVarying(GrGLSLVarying*, GrSLPrecision);
joshualitt74077b92014-10-24 11:26:03 -0700190
egdaniel574a4c12015-11-02 06:22:44 -0800191 void onFinalize() override;
192
joshualitt47bb3822014-10-07 16:43:25 -0700193 // Interpretation of FragPosKey when generating code
joshualitt30ba4362014-08-21 20:18:45 -0700194 enum {
195 kNoFragPosRead_FragPosKey = 0, // The fragment positition will not be needed.
196 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to top-left.
197 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left.
198 };
199
bsalomon6a44c6a2015-05-26 09:49:05 -0700200 static const char* kDstTextureColorName;
joshualitt47bb3822014-10-07 16:43:25 -0700201
cdalton85285412016-02-18 12:37:07 -0800202 /*
203 * State that tracks which child proc in the proc tree is currently emitting code. This is
204 * used to update the fMangleString, which is used to mangle the names of uniforms and functions
205 * emitted by the proc. fSubstageIndices is a stack: its count indicates how many levels deep
206 * we are in the tree, and its second-to-last value is the index of the child proc at that
207 * level which is currently emitting code. For example, if fSubstageIndices = [3, 1, 2, 0], that
208 * means we're currently emitting code for the base proc's 3rd child's 1st child's 2nd child.
209 */
210 SkTArray<int> fSubstageIndices;
211
212 /*
213 * The mangle string is used to mangle the names of uniforms/functions emitted by the child
214 * procs so no duplicate uniforms/functions appear in the generated shader program. The mangle
215 * string is simply based on fSubstageIndices. For example, if fSubstageIndices = [3, 1, 2, 0],
216 * then the manglestring will be "_c3_c1_c2", and any uniform/function emitted by that proc will
217 * have "_c3_c1_c2" appended to its name, which can be interpreted as "base proc's 3rd child's
218 * 1st child's 2nd child".
219 */
220 SkString fMangleString;
221
joshualitt30ba4362014-08-21 20:18:45 -0700222 bool fSetupFragPosition;
223 bool fTopLeftFragPosRead;
cdalton85285412016-02-18 12:37:07 -0800224 bool fHasCustomColorOutput;
joshualittb4384b92014-10-21 12:53:15 -0700225 int fCustomColorOutputIndex;
cdalton85285412016-02-18 12:37:07 -0800226 bool fHasSecondaryOutput;
cdalton33ad7012016-02-22 07:55:44 -0800227 bool fHasInitializedSampleMask;
joshualitt30ba4362014-08-21 20:18:45 -0700228
joshualitt47bb3822014-10-07 16:43:25 -0700229 // some state to verify shaders and effects are consistent, this is reset between effects by
230 // the program creator
231 bool fHasReadDstColor;
232 bool fHasReadFragmentPosition;
joshualittfe1233c2014-10-07 12:16:35 -0700233
egdanielfa896322016-01-13 12:19:30 -0800234 friend class GrGLSLProgramBuilder;
joshualitt47bb3822014-10-07 16:43:25 -0700235 friend class GrGLProgramBuilder;
joshualitt30ba4362014-08-21 20:18:45 -0700236};
237
238#endif