blob: 4dab6f2a09bd2582fc30576c8331f27c0569b062 [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 /**
70 * Fragment procs with child procs should call these functions before/after calling emitCode
71 * on a child proc.
72 */
73 virtual void onBeforeChildProcEmitCode() = 0;
74 virtual void onAfterChildProcEmitCode() = 0;
75
76 virtual const SkString& getMangleString() const = 0;
77};
78
79/*
80 * This class is used by primitive processors to build their fragment code.
81 */
82class GrGLSLPPFragmentBuilder : public GrGLSLFPFragmentBuilder {
83public:
84 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
85 GrGLSLPPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
86};
87
88/*
89 * This class is used by Xfer processors to build their fragment code.
90 */
91class GrGLSLXPFragmentBuilder : virtual public GrGLSLFragmentBuilder {
92public:
93 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
94 GrGLSLXPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
95
96 virtual bool hasCustomColorOutput() const = 0;
97 virtual bool hasSecondaryOutput() const = 0;
98
99 /** Returns the variable name that holds the color of the destination pixel. This may be nullptr
100 * if no effect advertised that it will read the destination. */
joshualittb0a8a372014-09-23 09:50:21 -0700101 virtual const char* dstColor() = 0;
102
cdalton8917d622015-05-06 13:40:21 -0700103 /** Adds any necessary layout qualifiers in order to legalize the supplied blend equation with
104 this shader. It is only legal to call this method with an advanced blend equation, and only
105 if these equations are supported. */
106 virtual void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) = 0;
joshualittb0a8a372014-09-23 09:50:21 -0700107};
108
cdalton85285412016-02-18 12:37:07 -0800109/*
110 * This class implements the various fragment builder interfaces.
111 */
112class GrGLSLFragmentShaderBuilder : public GrGLSLPPFragmentBuilder, public GrGLSLXPFragmentBuilder {
joshualitt30ba4362014-08-21 20:18:45 -0700113public:
joshualitt30ba4362014-08-21 20:18:45 -0700114 typedef uint8_t FragPosKey;
115
joshualitt30ba4362014-08-21 20:18:45 -0700116 /** Returns a key for reading the fragment location. This should only be called if there is an
117 effect that will requires the fragment position. If the fragment position is not required,
118 the key is 0. */
egdaniel574a4c12015-11-02 06:22:44 -0800119 static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst);
joshualitt30ba4362014-08-21 20:18:45 -0700120
egdaniel2d721d32015-11-11 13:06:05 -0800121 GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program, uint8_t fragPosKey);
joshualitt30ba4362014-08-21 20:18:45 -0700122
cdalton85285412016-02-18 12:37:07 -0800123 // Shared GrGLSLFragmentBuilder interface.
mtklein36352bf2015-03-25 18:17:31 -0700124 bool enableFeature(GLSLFeature) override;
egdaniel7dc4bd02015-10-29 07:57:01 -0700125 virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords,
mtklein36352bf2015-03-25 18:17:31 -0700126 int index) override;
127 const char* fragmentPosition() override;
joshualittdb0d3ca2014-10-07 12:42:26 -0700128
cdalton85285412016-02-18 12:37:07 -0800129 // GrGLSLFPFragmentBuilder interface.
130 const SkString& getMangleString() const override { return fMangleString; }
131 void onBeforeChildProcEmitCode() override;
132 void onAfterChildProcEmitCode() override;
133
134 // GrGLSLXPFragmentBuilder interface.
135 bool hasCustomColorOutput() const override { return fHasCustomColorOutput; }
136 bool hasSecondaryOutput() const override { return fHasSecondaryOutput; }
137 const char* dstColor() override;
cdalton8917d622015-05-06 13:40:21 -0700138 void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override;
139
joshualitt74077b92014-10-24 11:26:03 -0700140private:
joshualitt47bb3822014-10-07 16:43:25 -0700141 // Private public interface, used by GrGLProgramBuilder to build a fragment shader
joshualitt47bb3822014-10-07 16:43:25 -0700142 void enableCustomOutput();
143 void enableSecondaryOutput();
144 const char* getPrimaryColorOutputName() const;
145 const char* getSecondaryColorOutputName() const;
joshualitt47bb3822014-10-07 16:43:25 -0700146
egdaniel57d3b032015-11-13 11:57:27 -0800147 // As GLSLProcessors emit code, there are some conditions we need to verify. We use the below
joshualitt47bb3822014-10-07 16:43:25 -0700148 // state to track this. The reset call is called per processor emitted.
149 bool hasReadDstColor() const { return fHasReadDstColor; }
150 bool hasReadFragmentPosition() const { return fHasReadFragmentPosition; }
151 void reset() {
152 fHasReadDstColor = false;
153 fHasReadFragmentPosition = false;
154 }
joshualitt30ba4362014-08-21 20:18:45 -0700155
egdaniel8dcdedc2015-11-11 06:27:20 -0800156 static const char* DeclaredColorOutputName() { return "fsColorOut"; }
157 static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryColorOut"; }
158
joshualitt74077b92014-10-24 11:26:03 -0700159 /*
160 * An internal call for GrGLProgramBuilder to use to add varyings to the vertex shader
161 */
egdaniel8dcdedc2015-11-11 06:27:20 -0800162 void addVarying(GrGLSLVarying*, GrSLPrecision);
joshualitt74077b92014-10-24 11:26:03 -0700163
egdaniel574a4c12015-11-02 06:22:44 -0800164 void onFinalize() override;
165
joshualitt47bb3822014-10-07 16:43:25 -0700166 // Interpretation of FragPosKey when generating code
joshualitt30ba4362014-08-21 20:18:45 -0700167 enum {
168 kNoFragPosRead_FragPosKey = 0, // The fragment positition will not be needed.
169 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to top-left.
170 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left.
171 };
172
bsalomon6a44c6a2015-05-26 09:49:05 -0700173 static const char* kDstTextureColorName;
joshualitt47bb3822014-10-07 16:43:25 -0700174
cdalton85285412016-02-18 12:37:07 -0800175 /*
176 * State that tracks which child proc in the proc tree is currently emitting code. This is
177 * used to update the fMangleString, which is used to mangle the names of uniforms and functions
178 * emitted by the proc. fSubstageIndices is a stack: its count indicates how many levels deep
179 * we are in the tree, and its second-to-last value is the index of the child proc at that
180 * level which is currently emitting code. For example, if fSubstageIndices = [3, 1, 2, 0], that
181 * means we're currently emitting code for the base proc's 3rd child's 1st child's 2nd child.
182 */
183 SkTArray<int> fSubstageIndices;
184
185 /*
186 * The mangle string is used to mangle the names of uniforms/functions emitted by the child
187 * procs so no duplicate uniforms/functions appear in the generated shader program. The mangle
188 * string is simply based on fSubstageIndices. For example, if fSubstageIndices = [3, 1, 2, 0],
189 * then the manglestring will be "_c3_c1_c2", and any uniform/function emitted by that proc will
190 * have "_c3_c1_c2" appended to its name, which can be interpreted as "base proc's 3rd child's
191 * 1st child's 2nd child".
192 */
193 SkString fMangleString;
194
joshualitt30ba4362014-08-21 20:18:45 -0700195 bool fSetupFragPosition;
196 bool fTopLeftFragPosRead;
cdalton85285412016-02-18 12:37:07 -0800197 bool fHasCustomColorOutput;
joshualittb4384b92014-10-21 12:53:15 -0700198 int fCustomColorOutputIndex;
cdalton85285412016-02-18 12:37:07 -0800199 bool fHasSecondaryOutput;
joshualitt30ba4362014-08-21 20:18:45 -0700200
joshualitt47bb3822014-10-07 16:43:25 -0700201 // some state to verify shaders and effects are consistent, this is reset between effects by
202 // the program creator
203 bool fHasReadDstColor;
204 bool fHasReadFragmentPosition;
joshualittfe1233c2014-10-07 12:16:35 -0700205
egdanielfa896322016-01-13 12:19:30 -0800206 friend class GrGLSLProgramBuilder;
joshualitt47bb3822014-10-07 16:43:25 -0700207 friend class GrGLProgramBuilder;
joshualitt30ba4362014-08-21 20:18:45 -0700208};
209
210#endif