2 * Copyright 2013 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef GrGLProgramEffects_DEFINED
9 #define GrGLProgramEffects_DEFINED
11 #include "GrBackendEffectFactory.h"
12 #include "GrGLProgramDataManager.h"
13 #include "GrTexture.h"
14 #include "GrTextureAccess.h"
18 class GrGLVertexProgramEffectsBuilder;
19 class GrGLShaderBuilder;
20 class GrGLFullShaderBuilder;
21 class GrGLFragmentOnlyShaderBuilder;
24 * This class encapsulates an array of GrGLEffects and their supporting data (coord transforms
25 * and textures). It is built with GrGLProgramEffectsBuilder, then used to manage the necessary GL
26 * state and shader uniforms.
28 class GrGLProgramEffects : public SkRefCnt {
30 typedef GrGLProgramDataManager::UniformHandle UniformHandle;
33 * This class emits some of the code inserted into the shaders for an effect. The code it
34 * creates may be dependent on properties of the effect that the effect itself doesn't use
35 * in its key (e.g. the pixel format of textures used). So this class inserts a meta-key for
36 * every effect using this function. It is also responsible for inserting the effect's class ID
37 * which must be different for every GrEffect subclass. It can fail if an effect uses too many
38 * textures, attributes, etc for the space allotted in the meta-key.
40 static bool GenEffectMetaKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
42 virtual ~GrGLProgramEffects();
45 * Assigns a texture unit to each sampler. It starts on *texUnitIdx and writes the next
46 * available unit to *texUnitIdx when it returns.
48 void initSamplers(const GrGLProgramDataManager&, int* texUnitIdx);
51 * Calls setData() on each effect, and sets their transformation matrices and texture bindings.
53 virtual void setData(GrGpuGL*,
54 const GrGLProgramDataManager&,
55 const GrEffectStage* effectStages[]) = 0;
58 * Passed to GrGLEffects so they can add transformed coordinates to their shader code.
60 class TransformedCoords {
62 TransformedCoords(const SkString& name, GrSLType type)
63 : fName(name), fType(type) {
66 const char* c_str() const { return fName.c_str(); }
67 GrSLType type() const { return fType; }
68 const SkString& getName() const { return fName; }
75 typedef SkTArray<TransformedCoords> TransformedCoordsArray;
78 * Passed to GrGLEffects so they can add texture reads to their shader code.
80 class TextureSampler {
82 TextureSampler(UniformHandle uniform, const GrTextureAccess& access)
83 : fSamplerUniform(uniform)
84 , fConfigComponentMask(GrPixelConfigComponentMask(access.getTexture()->config())) {
85 SkASSERT(0 != fConfigComponentMask);
86 memcpy(fSwizzle, access.getSwizzle(), 5);
89 UniformHandle samplerUniform() const { return fSamplerUniform; }
90 // bitfield of GrColorComponentFlags present in the texture's config.
91 uint32_t configComponentMask() const { return fConfigComponentMask; }
92 const char* swizzle() const { return fSwizzle; }
95 UniformHandle fSamplerUniform;
96 uint32_t fConfigComponentMask;
100 typedef SkTArray<TextureSampler> TextureSamplerArray;
104 * Helpers for GenEffectMetaKey.
106 static uint32_t GenAttribKey(const GrDrawEffect&);
107 static uint32_t GenTransformKey(const GrDrawEffect&);
108 static uint32_t GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
110 GrGLProgramEffects(int reserveCount)
111 : fGLEffects(reserveCount)
112 , fSamplers(reserveCount) {
116 * Helper for emitEffect() in a subclasses. Emits uniforms for an effect's texture accesses and
117 * appends the necessary data to the TextureSamplerArray* object so effects can add texture
118 * lookups to their code. This method is only meant to be called during the construction phase.
120 void emitSamplers(GrGLShaderBuilder*, const GrEffect*, TextureSamplerArray*);
123 * Helper for setData(). Binds all the textures for an effect.
125 void bindTextures(GrGpuGL*, const GrEffect*, int effectIdx);
128 SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
129 UniformHandle fUniform;
133 SkTArray<GrGLEffect*> fGLEffects;
134 SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
137 typedef SkRefCnt INHERITED;
141 * This is an abstract base class for constructing different types of GrGLProgramEffects objects.
143 class GrGLProgramEffectsBuilder {
145 virtual ~GrGLProgramEffectsBuilder() { }
148 * Emits the effect's shader code, and stores the necessary uniforms internally.
150 virtual void emitEffect(const GrEffectStage&,
152 const char* outColor,
157 ////////////////////////////////////////////////////////////////////////////////
160 * This is a GrGLProgramEffects implementation that does coord transforms with the vertex shader.
162 class GrGLVertexProgramEffects : public GrGLProgramEffects {
164 virtual void setData(GrGpuGL*,
165 const GrGLProgramDataManager&,
166 const GrEffectStage* effectStages[]) SK_OVERRIDE;
169 friend class GrGLVertexProgramEffectsBuilder;
171 GrGLVertexProgramEffects(int reserveCount, bool explicitLocalCoords)
172 : INHERITED(reserveCount)
173 , fTransforms(reserveCount)
174 , fHasExplicitLocalCoords(explicitLocalCoords) {
178 * Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called
179 * during the construction phase.
181 void emitEffect(GrGLFullShaderBuilder*,
182 const GrEffectStage&,
184 const char* outColor,
189 * Helper for emitEffect(). Emits any attributes an effect may have.
191 void emitAttributes(GrGLFullShaderBuilder*, const GrEffectStage&);
194 * Helper for emitEffect(). Emits code to implement an effect's coord transforms in the VS.
195 * Varyings are added as an outputs of the VS and inputs to the FS. The varyings may be either a
196 * vec2f or vec3f depending upon whether perspective interpolation is required or not. The names
197 * of the varyings in the VS and FS as well their types are appended to the
198 * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function.
200 void emitTransforms(GrGLFullShaderBuilder*,
202 TransformedCoordsArray*);
205 * Helper for setData(). Sets all the transform matrices for an effect.
207 void setTransformData(const GrGLProgramDataManager&, const GrDrawEffect&, int effectIdx);
210 Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
211 UniformHandle fHandle;
212 SkMatrix fCurrentValue;
215 SkTArray<SkSTArray<2, Transform, true> > fTransforms;
216 bool fHasExplicitLocalCoords;
218 typedef GrGLProgramEffects INHERITED;
222 * This class is used to construct a GrGLVertexProgramEffects* object.
224 class GrGLVertexProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
226 GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder*, int reserveCount);
227 virtual ~GrGLVertexProgramEffectsBuilder() { }
229 virtual void emitEffect(const GrEffectStage&,
231 const char* outColor,
233 int stageIndex) SK_OVERRIDE;
236 * Finalizes the building process and returns the effect array. After this call, the builder
239 GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
242 GrGLFullShaderBuilder* fBuilder;
243 SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects;
245 typedef GrGLProgramEffectsBuilder INHERITED;
248 ////////////////////////////////////////////////////////////////////////////////
251 * This is a GrGLProgramEffects implementation that does coord transforms with
252 * the the NV_path_rendering PathTexGen functionality.
254 class GrGLPathTexGenProgramEffects : public GrGLProgramEffects {
256 virtual void setData(GrGpuGL*,
257 const GrGLProgramDataManager&,
258 const GrEffectStage* effectStages[]) SK_OVERRIDE;
261 friend class GrGLPathTexGenProgramEffectsBuilder;
263 GrGLPathTexGenProgramEffects(int reserveCount)
264 : INHERITED(reserveCount)
265 , fTransforms(reserveCount) {
269 * Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called
270 * during the construction phase.
272 void emitEffect(GrGLFragmentOnlyShaderBuilder*,
273 const GrEffectStage&,
275 const char* outColor,
280 * Helper for emitEffect(). Allocates texture units from the builder for each transform in an
281 * effect. The transforms all use adjacent texture units. They either use two or three of the
282 * coordinates at a given texture unit, depending on if they need perspective interpolation.
283 * The expressions to access the transformed coords (i.e. 'vec2(gl_TexCoord[0])') as well as the
284 * types are appended to the TransformedCoordsArray* object, which is in turn passed to the
285 * effect's emitCode() function.
287 void setupPathTexGen(GrGLFragmentOnlyShaderBuilder*,
289 TransformedCoordsArray*);
292 * Helper for setData(). Sets the PathTexGen state for each transform in an effect.
294 void setPathTexGenState(GrGpuGL*, const GrDrawEffect&, int effectIdx);
297 Transforms(uint32_t transformKey, int texCoordIndex)
298 : fTransformKey(transformKey), fTexCoordIndex(texCoordIndex) {}
299 uint32_t fTransformKey;
303 SkTArray<Transforms> fTransforms;
305 typedef GrGLProgramEffects INHERITED;
309 * This class is used to construct a GrGLPathTexGenProgramEffects* object.
311 class GrGLPathTexGenProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
313 GrGLPathTexGenProgramEffectsBuilder(GrGLFragmentOnlyShaderBuilder*, int reserveCount);
314 virtual ~GrGLPathTexGenProgramEffectsBuilder() { }
316 virtual void emitEffect(const GrEffectStage&,
318 const char* outColor,
320 int stageIndex) SK_OVERRIDE;
323 * Finalizes the building process and returns the effect array. After this call, the builder
326 GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
329 GrGLFragmentOnlyShaderBuilder* fBuilder;
330 SkAutoTDelete<GrGLPathTexGenProgramEffects> fProgramEffects;
332 typedef GrGLProgramEffectsBuilder INHERITED;