OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrGLSLFragmentShaderBuilder_DEFINED | 8 #ifndef GrGLSLFragmentShaderBuilder_DEFINED |
9 #define GrGLSLFragmentShaderBuilder_DEFINED | 9 #define GrGLSLFragmentShaderBuilder_DEFINED |
10 | 10 |
11 #include "GrGLSLShaderBuilder.h" | 11 #include "GrGLSLShaderBuilder.h" |
12 | 12 |
13 #include "glsl/GrGLSLProcessorTypes.h" | 13 #include "glsl/GrGLSLProcessorTypes.h" |
14 | 14 |
15 class GrRenderTarget; | 15 class GrRenderTarget; |
16 class GrGLSLVarying; | 16 class GrGLSLVarying; |
17 | 17 |
18 /* | 18 /* |
19 * This base class encapsulates the functionality which the GP uses to build fra
gment shaders | 19 * This base class encapsulates the common functionality which all processors us
e to build fragment |
| 20 * shaders. |
20 */ | 21 */ |
21 class GrGLSLFragmentBuilder : public GrGLSLShaderBuilder { | 22 class GrGLSLFragmentBuilder : public GrGLSLShaderBuilder { |
22 public: | 23 public: |
23 GrGLSLFragmentBuilder(GrGLSLProgramBuilder* program) | 24 GrGLSLFragmentBuilder(GrGLSLProgramBuilder* program) : INHERITED(program) {} |
24 : INHERITED(program) | |
25 , fHasCustomColorOutput(false) | |
26 , fHasSecondaryOutput(false) { | |
27 fSubstageIndices.push_back(0); | |
28 } | |
29 virtual ~GrGLSLFragmentBuilder() {} | 25 virtual ~GrGLSLFragmentBuilder() {} |
| 26 |
30 /** | 27 /** |
31 * Use of these features may require a GLSL extension to be enabled. Shaders
may not compile | 28 * Use of these features may require a GLSL extension to be enabled. Shaders
may not compile |
32 * if code is added that uses one of these features without calling enableFe
ature() | 29 * if code is added that uses one of these features without calling enableFe
ature() |
33 */ | 30 */ |
34 enum GLSLFeature { | 31 enum GLSLFeature { |
35 kStandardDerivatives_GLSLFeature = kLastGLSLPrivateFeature + 1, | 32 kStandardDerivatives_GLSLFeature = kLastGLSLPrivateFeature + 1, |
36 kPixelLocalStorage_GLSLFeature | 33 kPixelLocalStorage_GLSLFeature |
37 }; | 34 }; |
38 | 35 |
39 /** | 36 /** |
40 * If the feature is supported then true is returned and any necessary #exte
nsion declarations | 37 * If the feature is supported then true is returned and any necessary #exte
nsion declarations |
41 * are added to the shaders. If the feature is not supported then false will
be returned. | 38 * are added to the shaders. If the feature is not supported then false will
be returned. |
42 */ | 39 */ |
43 virtual bool enableFeature(GLSLFeature) = 0; | 40 virtual bool enableFeature(GLSLFeature) = 0; |
44 | 41 |
45 /** | 42 /** |
46 * This returns a variable name to access the 2D, perspective correct versio
n of the coords in | 43 * This returns a variable name to access the 2D, perspective correct versio
n of the coords in |
47 * the fragment shader. If the coordinates at index are 3-dimensional, it im
mediately emits a | 44 * the fragment shader. If the coordinates at index are 3-dimensional, it im
mediately emits a |
48 * perspective divide into the fragment shader (xy / z) to convert them to 2
D. | 45 * perspective divide into the fragment shader (xy / z) to convert them to 2
D. |
49 */ | 46 */ |
50 virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords
, int index) = 0; | 47 virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords
, int index) = 0; |
51 | 48 |
52 | 49 |
53 /** Returns a variable name that represents the position of the fragment in
the FS. The position | 50 /** Returns a variable name that represents the position of the fragment in
the FS. The position |
54 is in device space (e.g. 0,0 is the top left and pixel centers are at ha
lf-integers). */ | 51 is in device space (e.g. 0,0 is the top left and pixel centers are at ha
lf-integers). */ |
55 virtual const char* fragmentPosition() = 0; | 52 virtual const char* fragmentPosition() = 0; |
56 | 53 |
| 54 // TODO: remove this method. |
| 55 void declAppendf(const char* fmt, ...); |
| 56 |
| 57 private: |
| 58 typedef GrGLSLShaderBuilder INHERITED; |
| 59 }; |
| 60 |
| 61 /* |
| 62 * This class is used by fragment processors to build their fragment code. |
| 63 */ |
| 64 class GrGLSLFPFragmentBuilder : virtual public GrGLSLFragmentBuilder { |
| 65 public: |
| 66 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilde
r. */ |
| 67 GrGLSLFPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {} |
| 68 |
57 /** | 69 /** |
58 * Fragment procs with child procs should call these functions before/after
calling emitCode | 70 * Fragment procs with child procs should call these functions before/after
calling emitCode |
59 * on a child proc. | 71 * on a child proc. |
60 */ | 72 */ |
61 void onBeforeChildProcEmitCode(); | 73 virtual void onBeforeChildProcEmitCode() = 0; |
62 void onAfterChildProcEmitCode(); | 74 virtual void onAfterChildProcEmitCode() = 0; |
63 | 75 |
64 const SkString& getMangleString() const { return fMangleString; } | 76 virtual const SkString& getMangleString() const = 0; |
65 | |
66 bool hasCustomColorOutput() const { return fHasCustomColorOutput; } | |
67 bool hasSecondaryOutput() const { return fHasSecondaryOutput; } | |
68 | |
69 void declAppendf(const char* fmt, ...); | |
70 | |
71 protected: | |
72 bool fHasCustomColorOutput; | |
73 bool fHasSecondaryOutput; | |
74 | |
75 private: | |
76 /* | |
77 * State that tracks which child proc in the proc tree is currently emitting
code. This is | |
78 * used to update the fMangleString, which is used to mangle the names of un
iforms and functions | |
79 * emitted by the proc. fSubstageIndices is a stack: its count indicates ho
w many levels deep | |
80 * we are in the tree, and its second-to-last value is the index of the chil
d proc at that | |
81 * level which is currently emitting code. For example, if fSubstageIndices
= [3, 1, 2, 0], that | |
82 * means we're currently emitting code for the base proc's 3rd child's 1st c
hild's 2nd child. | |
83 */ | |
84 SkTArray<int> fSubstageIndices; | |
85 | |
86 /* | |
87 * The mangle string is used to mangle the names of uniforms/functions emitt
ed by the child | |
88 * procs so no duplicate uniforms/functions appear in the generated shader p
rogram. The mangle | |
89 * string is simply based on fSubstageIndices. For example, if fSubstageIndi
ces = [3, 1, 2, 0], | |
90 * then the manglestring will be "_c3_c1_c2", and any uniform/function emitt
ed by that proc will | |
91 * have "_c3_c1_c2" appended to its name, which can be interpreted as "base
proc's 3rd child's | |
92 * 1st child's 2nd child". | |
93 */ | |
94 SkString fMangleString; | |
95 | |
96 friend class GrGLPathProcessor; | |
97 | |
98 typedef GrGLSLShaderBuilder INHERITED; | |
99 }; | 77 }; |
100 | 78 |
101 /* | 79 /* |
102 * Fragment processor's, in addition to all of the above, may need to use dst co
lor so they use | 80 * This class is used by primitive processors to build their fragment code. |
103 * this builder to create their shader. Because this is the only shader builder
the FP sees, we | |
104 * just call it FPShaderBuilder | |
105 */ | 81 */ |
106 class GrGLSLXPFragmentBuilder : public GrGLSLFragmentBuilder { | 82 class GrGLSLPPFragmentBuilder : public GrGLSLFPFragmentBuilder { |
107 public: | 83 public: |
108 GrGLSLXPFragmentBuilder(GrGLSLProgramBuilder* program) : INHERITED(program)
{} | 84 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilde
r. */ |
| 85 GrGLSLPPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {} |
| 86 }; |
109 | 87 |
110 /** Returns the variable name that holds the color of the destination pixel.
This may be nullptr if | 88 /* |
111 no effect advertised that it will read the destination. */ | 89 * This class is used by Xfer processors to build their fragment code. |
| 90 */ |
| 91 class GrGLSLXPFragmentBuilder : virtual public GrGLSLFragmentBuilder { |
| 92 public: |
| 93 /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilde
r. */ |
| 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. */ |
112 virtual const char* dstColor() = 0; | 101 virtual const char* dstColor() = 0; |
113 | 102 |
114 /** Adds any necessary layout qualifiers in order to legalize the supplied b
lend equation with | 103 /** Adds any necessary layout qualifiers in order to legalize the supplied b
lend equation with |
115 this shader. It is only legal to call this method with an advanced blend
equation, and only | 104 this shader. It is only legal to call this method with an advanced blend
equation, and only |
116 if these equations are supported. */ | 105 if these equations are supported. */ |
117 virtual void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) = 0; | 106 virtual void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) = 0; |
118 | |
119 private: | |
120 typedef GrGLSLFragmentBuilder INHERITED; | |
121 }; | 107 }; |
122 | 108 |
123 // TODO rename to Fragment Builder | 109 /* |
124 class GrGLSLFragmentShaderBuilder : public GrGLSLXPFragmentBuilder { | 110 * This class implements the various fragment builder interfaces. |
| 111 */ |
| 112 class GrGLSLFragmentShaderBuilder : public GrGLSLPPFragmentBuilder, public GrGLS
LXPFragmentBuilder { |
125 public: | 113 public: |
126 typedef uint8_t FragPosKey; | 114 typedef uint8_t FragPosKey; |
127 | 115 |
128 /** Returns a key for reading the fragment location. This should only be cal
led if there is an | 116 /** Returns a key for reading the fragment location. This should only be cal
led if there is an |
129 effect that will requires the fragment position. If the fragment position
is not required, | 117 effect that will requires the fragment position. If the fragment position
is not required, |
130 the key is 0. */ | 118 the key is 0. */ |
131 static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst); | 119 static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst); |
132 | 120 |
133 GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program, uint8_t fragPosKe
y); | 121 GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program, uint8_t fragPosKe
y); |
134 | 122 |
135 // true public interface, defined explicitly in the abstract interfaces abov
e | 123 // Shared GrGLSLFragmentBuilder interface. |
136 bool enableFeature(GLSLFeature) override; | 124 bool enableFeature(GLSLFeature) override; |
137 virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords
, | 125 virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords
, |
138 int index) override; | 126 int index) override; |
139 const char* fragmentPosition() override; | 127 const char* fragmentPosition() override; |
| 128 |
| 129 // 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; } |
140 const char* dstColor() override; | 137 const char* dstColor() override; |
141 | |
142 void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override; | 138 void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override; |
143 | 139 |
144 private: | 140 private: |
145 // Private public interface, used by GrGLProgramBuilder to build a fragment
shader | 141 // Private public interface, used by GrGLProgramBuilder to build a fragment
shader |
146 void enableCustomOutput(); | 142 void enableCustomOutput(); |
147 void enableSecondaryOutput(); | 143 void enableSecondaryOutput(); |
148 const char* getPrimaryColorOutputName() const; | 144 const char* getPrimaryColorOutputName() const; |
149 const char* getSecondaryColorOutputName() const; | 145 const char* getSecondaryColorOutputName() const; |
150 | 146 |
151 // As GLSLProcessors emit code, there are some conditions we need to verify.
We use the below | 147 // As GLSLProcessors emit code, there are some conditions we need to verify.
We use the below |
(...skipping 17 matching lines...) Expand all Loading... |
169 | 165 |
170 // Interpretation of FragPosKey when generating code | 166 // Interpretation of FragPosKey when generating code |
171 enum { | 167 enum { |
172 kNoFragPosRead_FragPosKey = 0, // The fragment positition wil
l not be needed. | 168 kNoFragPosRead_FragPosKey = 0, // The fragment positition wil
l not be needed. |
173 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to t
op-left. | 169 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to t
op-left. |
174 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to b
ottom-left. | 170 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to b
ottom-left. |
175 }; | 171 }; |
176 | 172 |
177 static const char* kDstTextureColorName; | 173 static const char* kDstTextureColorName; |
178 | 174 |
| 175 /* |
| 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 un
iforms and functions |
| 178 * emitted by the proc. fSubstageIndices is a stack: its count indicates ho
w many levels deep |
| 179 * we are in the tree, and its second-to-last value is the index of the chil
d 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 c
hild's 2nd child. |
| 182 */ |
| 183 SkTArray<int> fSubstageIndices; |
| 184 |
| 185 /* |
| 186 * The mangle string is used to mangle the names of uniforms/functions emitt
ed by the child |
| 187 * procs so no duplicate uniforms/functions appear in the generated shader p
rogram. The mangle |
| 188 * string is simply based on fSubstageIndices. For example, if fSubstageIndi
ces = [3, 1, 2, 0], |
| 189 * then the manglestring will be "_c3_c1_c2", and any uniform/function emitt
ed 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 |
179 bool fSetupFragPosition; | 195 bool fSetupFragPosition; |
180 bool fTopLeftFragPosRead; | 196 bool fTopLeftFragPosRead; |
| 197 bool fHasCustomColorOutput; |
181 int fCustomColorOutputIndex; | 198 int fCustomColorOutputIndex; |
| 199 bool fHasSecondaryOutput; |
182 | 200 |
183 // some state to verify shaders and effects are consistent, this is reset be
tween effects by | 201 // some state to verify shaders and effects are consistent, this is reset be
tween effects by |
184 // the program creator | 202 // the program creator |
185 bool fHasReadDstColor; | 203 bool fHasReadDstColor; |
186 bool fHasReadFragmentPosition; | 204 bool fHasReadFragmentPosition; |
187 | 205 |
188 friend class GrGLSLProgramBuilder; | 206 friend class GrGLSLProgramBuilder; |
189 friend class GrGLProgramBuilder; | 207 friend class GrGLProgramBuilder; |
190 | |
191 typedef GrGLSLXPFragmentBuilder INHERITED; | |
192 }; | 208 }; |
193 | 209 |
194 #endif | 210 #endif |
OLD | NEW |