|
1 /* |
|
2 * Copyright 2013 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 GrGLProgramEffects_DEFINED |
|
9 #define GrGLProgramEffects_DEFINED |
|
10 |
|
11 #include "GrBackendEffectFactory.h" |
|
12 #include "GrTexture.h" |
|
13 #include "GrTextureAccess.h" |
|
14 #include "GrGLUniformManager.h" |
|
15 |
|
16 class GrEffectStage; |
|
17 class GrGLVertexProgramEffectsBuilder; |
|
18 class GrGLShaderBuilder; |
|
19 class GrGLFullShaderBuilder; |
|
20 class GrGLFragmentOnlyShaderBuilder; |
|
21 |
|
22 /** |
|
23 * This class encapsulates an array of GrGLEffects and their supporting data (coord transforms |
|
24 * and textures). It is built with GrGLProgramEffectsBuilder, then used to manage the necessary GL |
|
25 * state and shader uniforms. |
|
26 */ |
|
27 class GrGLProgramEffects { |
|
28 public: |
|
29 typedef GrBackendEffectFactory::EffectKey EffectKey; |
|
30 typedef GrGLUniformManager::UniformHandle UniformHandle; |
|
31 |
|
32 /** |
|
33 * These methods generate different portions of an effect's final key. |
|
34 */ |
|
35 static EffectKey GenAttribKey(const GrDrawEffect&); |
|
36 static EffectKey GenTransformKey(const GrDrawEffect&); |
|
37 static EffectKey GenTextureKey(const GrDrawEffect&, const GrGLCaps&); |
|
38 |
|
39 virtual ~GrGLProgramEffects(); |
|
40 |
|
41 /** |
|
42 * Assigns a texture unit to each sampler. It starts on *texUnitIdx and writes the next |
|
43 * available unit to *texUnitIdx when it returns. |
|
44 */ |
|
45 void initSamplers(const GrGLUniformManager&, int* texUnitIdx); |
|
46 |
|
47 /** |
|
48 * Calls setData() on each effect, and sets their transformation matrices and texture bindings. |
|
49 */ |
|
50 virtual void setData(GrGpuGL*, |
|
51 const GrGLUniformManager&, |
|
52 const GrEffectStage* effectStages[]) = 0; |
|
53 |
|
54 /** |
|
55 * Passed to GrGLEffects so they can add transformed coordinates to their shader code. |
|
56 */ |
|
57 class TransformedCoords { |
|
58 public: |
|
59 TransformedCoords(const SkString& name, GrSLType type) |
|
60 : fName(name), fType(type) { |
|
61 } |
|
62 |
|
63 const char* c_str() const { return fName.c_str(); } |
|
64 GrSLType type() const { return fType; } |
|
65 const SkString& getName() const { return fName; } |
|
66 |
|
67 private: |
|
68 SkString fName; |
|
69 GrSLType fType; |
|
70 }; |
|
71 |
|
72 typedef SkTArray<TransformedCoords> TransformedCoordsArray; |
|
73 |
|
74 /** |
|
75 * Passed to GrGLEffects so they can add texture reads to their shader code. |
|
76 */ |
|
77 class TextureSampler { |
|
78 public: |
|
79 TextureSampler(UniformHandle uniform, const GrTextureAccess& access) |
|
80 : fSamplerUniform(uniform) |
|
81 , fConfigComponentMask(GrPixelConfigComponentMask(access.getTexture()->config())) { |
|
82 SkASSERT(0 != fConfigComponentMask); |
|
83 memcpy(fSwizzle, access.getSwizzle(), 5); |
|
84 } |
|
85 |
|
86 UniformHandle samplerUniform() const { return fSamplerUniform; } |
|
87 // bitfield of GrColorComponentFlags present in the texture's config. |
|
88 uint32_t configComponentMask() const { return fConfigComponentMask; } |
|
89 const char* swizzle() const { return fSwizzle; } |
|
90 |
|
91 private: |
|
92 UniformHandle fSamplerUniform; |
|
93 uint32_t fConfigComponentMask; |
|
94 char fSwizzle[5]; |
|
95 }; |
|
96 |
|
97 typedef SkTArray<TextureSampler> TextureSamplerArray; |
|
98 |
|
99 protected: |
|
100 GrGLProgramEffects(int reserveCount) |
|
101 : fGLEffects(reserveCount) |
|
102 , fSamplers(reserveCount) { |
|
103 } |
|
104 |
|
105 /** |
|
106 * Helper for emitEffect() in a subclasses. Emits uniforms for an effect's texture accesses and |
|
107 * appends the necessary data to the TextureSamplerArray* object so effects can add texture |
|
108 * lookups to their code. This method is only meant to be called during the construction phase. |
|
109 */ |
|
110 void emitSamplers(GrGLShaderBuilder*, const GrEffectRef&, TextureSamplerArray*); |
|
111 |
|
112 /** |
|
113 * Helper for setData(). Binds all the textures for an effect. |
|
114 */ |
|
115 void bindTextures(GrGpuGL*, const GrEffectRef&, int effectIdx); |
|
116 |
|
117 struct Sampler { |
|
118 SkDEBUGCODE(Sampler() : fTextureUnit(-1) {}) |
|
119 UniformHandle fUniform; |
|
120 int fTextureUnit; |
|
121 }; |
|
122 |
|
123 SkTArray<GrGLEffect*> fGLEffects; |
|
124 SkTArray<SkSTArray<4, Sampler, true> > fSamplers; |
|
125 }; |
|
126 |
|
127 /** |
|
128 * This is an abstract base class for constructing different types of GrGLProgramEffects objects. |
|
129 */ |
|
130 class GrGLProgramEffectsBuilder { |
|
131 public: |
|
132 virtual ~GrGLProgramEffectsBuilder() { } |
|
133 |
|
134 /** |
|
135 * Emits the effect's shader code, and stores the necessary uniforms internally. |
|
136 */ |
|
137 virtual void emitEffect(const GrEffectStage&, |
|
138 GrGLProgramEffects::EffectKey, |
|
139 const char* outColor, |
|
140 const char* inColor, |
|
141 int stageIndex) = 0; |
|
142 }; |
|
143 |
|
144 //////////////////////////////////////////////////////////////////////////////// |
|
145 |
|
146 /** |
|
147 * This is a GrGLProgramEffects implementation that does coord transforms with the vertex shader. |
|
148 */ |
|
149 class GrGLVertexProgramEffects : public GrGLProgramEffects { |
|
150 public: |
|
151 virtual void setData(GrGpuGL*, |
|
152 const GrGLUniformManager&, |
|
153 const GrEffectStage* effectStages[]) SK_OVERRIDE; |
|
154 |
|
155 private: |
|
156 friend class GrGLVertexProgramEffectsBuilder; |
|
157 |
|
158 GrGLVertexProgramEffects(int reserveCount, bool explicitLocalCoords) |
|
159 : INHERITED(reserveCount) |
|
160 , fTransforms(reserveCount) |
|
161 , fHasExplicitLocalCoords(explicitLocalCoords) { |
|
162 } |
|
163 |
|
164 /** |
|
165 * Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called |
|
166 * during the construction phase. |
|
167 */ |
|
168 void emitEffect(GrGLFullShaderBuilder*, |
|
169 const GrEffectStage&, |
|
170 GrGLProgramEffects::EffectKey, |
|
171 const char* outColor, |
|
172 const char* inColor, |
|
173 int stageIndex); |
|
174 |
|
175 /** |
|
176 * Helper for emitEffect(). Emits any attributes an effect may have. |
|
177 */ |
|
178 void emitAttributes(GrGLFullShaderBuilder*, const GrEffectStage&); |
|
179 |
|
180 /** |
|
181 * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS. |
|
182 * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a |
|
183 * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names |
|
184 * of the varyings in the VS and FS as well their types are appended to the |
|
185 * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function. |
|
186 */ |
|
187 void emitTransforms(GrGLFullShaderBuilder*, |
|
188 const GrEffectRef&, |
|
189 EffectKey, |
|
190 TransformedCoordsArray*); |
|
191 |
|
192 /** |
|
193 * Helper for setData(). Sets all the transform matrices for an effect. |
|
194 */ |
|
195 void setTransformData(const GrGLUniformManager&, const GrDrawEffect&, int effectIdx); |
|
196 |
|
197 struct Transform { |
|
198 Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); } |
|
199 UniformHandle fHandle; |
|
200 GrSLType fType; |
|
201 SkMatrix fCurrentValue; |
|
202 }; |
|
203 |
|
204 SkTArray<SkSTArray<2, Transform, true> > fTransforms; |
|
205 bool fHasExplicitLocalCoords; |
|
206 |
|
207 typedef GrGLProgramEffects INHERITED; |
|
208 }; |
|
209 |
|
210 /** |
|
211 * This class is used to construct a GrGLVertexProgramEffects* object. |
|
212 */ |
|
213 class GrGLVertexProgramEffectsBuilder : public GrGLProgramEffectsBuilder { |
|
214 public: |
|
215 GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder*, int reserveCount); |
|
216 virtual ~GrGLVertexProgramEffectsBuilder() { } |
|
217 |
|
218 virtual void emitEffect(const GrEffectStage&, |
|
219 GrGLProgramEffects::EffectKey, |
|
220 const char* outColor, |
|
221 const char* inColor, |
|
222 int stageIndex) SK_OVERRIDE; |
|
223 |
|
224 /** |
|
225 * Finalizes the building process and returns the effect array. After this call, the builder |
|
226 * becomes invalid. |
|
227 */ |
|
228 GrGLProgramEffects* finish() { return fProgramEffects.detach(); } |
|
229 |
|
230 private: |
|
231 GrGLFullShaderBuilder* fBuilder; |
|
232 SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects; |
|
233 |
|
234 typedef GrGLProgramEffectsBuilder INHERITED; |
|
235 }; |
|
236 |
|
237 //////////////////////////////////////////////////////////////////////////////// |
|
238 |
|
239 /** |
|
240 * This is a GrGLProgramEffects implementation that does coord transforms with the the built-in GL |
|
241 * TexGen functionality. |
|
242 */ |
|
243 class GrGLTexGenProgramEffects : public GrGLProgramEffects { |
|
244 public: |
|
245 virtual void setData(GrGpuGL*, |
|
246 const GrGLUniformManager&, |
|
247 const GrEffectStage* effectStages[]) SK_OVERRIDE; |
|
248 |
|
249 private: |
|
250 friend class GrGLTexGenProgramEffectsBuilder; |
|
251 |
|
252 GrGLTexGenProgramEffects(int reserveCount) |
|
253 : INHERITED(reserveCount) |
|
254 , fTransforms(reserveCount) { |
|
255 } |
|
256 |
|
257 /** |
|
258 * Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called |
|
259 * during the construction phase. |
|
260 */ |
|
261 void emitEffect(GrGLFragmentOnlyShaderBuilder*, |
|
262 const GrEffectStage&, |
|
263 GrGLProgramEffects::EffectKey, |
|
264 const char* outColor, |
|
265 const char* inColor, |
|
266 int stageIndex); |
|
267 |
|
268 /** |
|
269 * Helper for emitEffect(). Allocates texture units from the builder for each transform in an |
|
270 * effect. The transforms all use adjacent texture units. They either use two or three of the |
|
271 * coordinates at a given texture unit, depending on if they need perspective interpolation. |
|
272 * The expressions to access the transformed coords (i.e. 'vec2(gl_TexCoord[0])') as well as the |
|
273 * types are appended to the TransformedCoordsArray* object, which is in turn passed to the |
|
274 * effect's emitCode() function. |
|
275 */ |
|
276 void setupTexGen(GrGLFragmentOnlyShaderBuilder*, |
|
277 const GrEffectRef&, |
|
278 EffectKey, |
|
279 TransformedCoordsArray*); |
|
280 |
|
281 /** |
|
282 * Helper for setData(). Sets the TexGen state for each transform in an effect. |
|
283 */ |
|
284 void setTexGenState(GrGpuGL*, const GrDrawEffect&, int effectIdx); |
|
285 |
|
286 struct Transforms { |
|
287 Transforms(EffectKey transformKey, int texCoordIndex) |
|
288 : fTransformKey(transformKey), fTexCoordIndex(texCoordIndex) {} |
|
289 EffectKey fTransformKey; |
|
290 int fTexCoordIndex; |
|
291 }; |
|
292 |
|
293 SkTArray<Transforms> fTransforms; |
|
294 |
|
295 typedef GrGLProgramEffects INHERITED; |
|
296 }; |
|
297 |
|
298 /** |
|
299 * This class is used to construct a GrGLTexGenProgramEffects* object. |
|
300 */ |
|
301 class GrGLTexGenProgramEffectsBuilder : public GrGLProgramEffectsBuilder { |
|
302 public: |
|
303 GrGLTexGenProgramEffectsBuilder(GrGLFragmentOnlyShaderBuilder*, int reserveCount); |
|
304 virtual ~GrGLTexGenProgramEffectsBuilder() { } |
|
305 |
|
306 virtual void emitEffect(const GrEffectStage&, |
|
307 GrGLProgramEffects::EffectKey, |
|
308 const char* outColor, |
|
309 const char* inColor, |
|
310 int stageIndex) SK_OVERRIDE; |
|
311 |
|
312 /** |
|
313 * Finalizes the building process and returns the effect array. After this call, the builder |
|
314 * becomes invalid. |
|
315 */ |
|
316 GrGLProgramEffects* finish() { return fProgramEffects.detach(); } |
|
317 |
|
318 private: |
|
319 GrGLFragmentOnlyShaderBuilder* fBuilder; |
|
320 SkAutoTDelete<GrGLTexGenProgramEffects> fProgramEffects; |
|
321 |
|
322 typedef GrGLProgramEffectsBuilder INHERITED; |
|
323 }; |
|
324 |
|
325 #endif |