Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / GrGLProgramEffects.h
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 "GrGLProgramDataManager.h"
13 #include "GrTexture.h"
14 #include "GrTextureAccess.h"
15
16 class GrEffect;
17 class GrEffectStage;
18 class GrGLVertexProgramEffectsBuilder;
19 class GrGLShaderBuilder;
20 class GrGLFullShaderBuilder;
21 class GrGLFragmentOnlyShaderBuilder;
22
23 /**
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.
27  */
28 class GrGLProgramEffects : public SkRefCnt {
29 public:
30     typedef GrGLProgramDataManager::UniformHandle UniformHandle;
31
32     /**
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.
39      */
40     static bool GenEffectMetaKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
41
42     virtual ~GrGLProgramEffects();
43
44     /**
45      * Assigns a texture unit to each sampler. It starts on *texUnitIdx and writes the next
46      * available unit to *texUnitIdx when it returns.
47      */
48     void initSamplers(const GrGLProgramDataManager&, int* texUnitIdx);
49
50     /**
51      * Calls setData() on each effect, and sets their transformation matrices and texture bindings.
52      */
53     virtual void setData(GrGpuGL*,
54                          const GrGLProgramDataManager&,
55                          const GrEffectStage* effectStages[]) = 0;
56
57     /**
58      * Passed to GrGLEffects so they can add transformed coordinates to their shader code.
59      */
60     class TransformedCoords {
61     public:
62         TransformedCoords(const SkString& name, GrSLType type)
63             : fName(name), fType(type) {
64         }
65
66         const char* c_str() const { return fName.c_str(); }
67         GrSLType type() const { return fType; }
68         const SkString& getName() const { return fName; }
69
70     private:
71         SkString fName;
72         GrSLType fType;
73     };
74
75     typedef SkTArray<TransformedCoords> TransformedCoordsArray;
76
77     /**
78      * Passed to GrGLEffects so they can add texture reads to their shader code.
79      */
80     class TextureSampler {
81     public:
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);
87         }
88
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; }
93
94     private:
95         UniformHandle fSamplerUniform;
96         uint32_t      fConfigComponentMask;
97         char          fSwizzle[5];
98     };
99
100     typedef SkTArray<TextureSampler> TextureSamplerArray;
101
102 protected:
103     /**
104      * Helpers for GenEffectMetaKey.
105      */
106     static uint32_t GenAttribKey(const GrDrawEffect&);
107     static uint32_t GenTransformKey(const GrDrawEffect&);
108     static uint32_t GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
109
110     GrGLProgramEffects(int reserveCount)
111         : fGLEffects(reserveCount)
112         , fSamplers(reserveCount) {
113     }
114
115     /**
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.
119      */
120     void emitSamplers(GrGLShaderBuilder*, const GrEffect*, TextureSamplerArray*);
121
122     /**
123      * Helper for setData(). Binds all the textures for an effect.
124      */
125     void bindTextures(GrGpuGL*, const GrEffect*, int effectIdx);
126
127     struct Sampler {
128         SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
129         UniformHandle fUniform;
130         int           fTextureUnit;
131     };
132
133     SkTArray<GrGLEffect*>                  fGLEffects;
134     SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
135
136 private:
137     typedef SkRefCnt INHERITED;
138 };
139
140 /**
141  * This is an abstract base class for constructing different types of GrGLProgramEffects objects.
142  */
143 class GrGLProgramEffectsBuilder {
144 public:
145     virtual ~GrGLProgramEffectsBuilder() { }
146
147     /**
148      * Emits the effect's shader code, and stores the necessary uniforms internally.
149      */
150     virtual void emitEffect(const GrEffectStage&,
151                             const GrEffectKey&,
152                             const char* outColor,
153                             const char* inColor,
154                             int stageIndex) = 0;
155 };
156
157 ////////////////////////////////////////////////////////////////////////////////
158
159 /**
160  * This is a GrGLProgramEffects implementation that does coord transforms with the vertex shader.
161  */
162 class GrGLVertexProgramEffects : public GrGLProgramEffects {
163 public:
164     virtual void setData(GrGpuGL*,
165                          const GrGLProgramDataManager&,
166                          const GrEffectStage* effectStages[]) SK_OVERRIDE;
167
168 private:
169     friend class GrGLVertexProgramEffectsBuilder;
170
171     GrGLVertexProgramEffects(int reserveCount, bool explicitLocalCoords)
172         : INHERITED(reserveCount)
173         , fTransforms(reserveCount)
174         , fHasExplicitLocalCoords(explicitLocalCoords) {
175     }
176
177     /**
178      * Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called
179      * during the construction phase.
180      */
181     void emitEffect(GrGLFullShaderBuilder*,
182                     const GrEffectStage&,
183                     const GrEffectKey&,
184                     const char* outColor,
185                     const char* inColor,
186                     int stageIndex);
187
188     /**
189      * Helper for emitEffect(). Emits any attributes an effect may have.
190      */
191     void emitAttributes(GrGLFullShaderBuilder*, const GrEffectStage&);
192
193     /**
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.
199      */
200     void emitTransforms(GrGLFullShaderBuilder*,
201                         const GrDrawEffect&,
202                         TransformedCoordsArray*);
203
204     /**
205      * Helper for setData(). Sets all the transform matrices for an effect.
206      */
207     void setTransformData(const GrGLProgramDataManager&, const GrDrawEffect&, int effectIdx);
208
209     struct Transform {
210         Transform() { fCurrentValue = SkMatrix::InvalidMatrix(); }
211         UniformHandle fHandle;
212         SkMatrix      fCurrentValue;
213     };
214
215     SkTArray<SkSTArray<2, Transform, true> > fTransforms;
216     bool                                     fHasExplicitLocalCoords;
217
218     typedef GrGLProgramEffects INHERITED;
219 };
220
221 /**
222  * This class is used to construct a GrGLVertexProgramEffects* object.
223  */
224 class GrGLVertexProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
225 public:
226     GrGLVertexProgramEffectsBuilder(GrGLFullShaderBuilder*, int reserveCount);
227     virtual ~GrGLVertexProgramEffectsBuilder() { }
228
229     virtual void emitEffect(const GrEffectStage&,
230                             const GrEffectKey&,
231                             const char* outColor,
232                             const char* inColor,
233                             int stageIndex) SK_OVERRIDE;
234
235     /**
236      * Finalizes the building process and returns the effect array. After this call, the builder
237      * becomes invalid.
238      */
239     GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
240
241 private:
242     GrGLFullShaderBuilder*                  fBuilder;
243     SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects;
244
245     typedef GrGLProgramEffectsBuilder INHERITED;
246 };
247
248 ////////////////////////////////////////////////////////////////////////////////
249
250 /**
251  * This is a GrGLProgramEffects implementation that does coord transforms with
252  * the the  NV_path_rendering PathTexGen functionality.
253  */
254 class GrGLPathTexGenProgramEffects : public GrGLProgramEffects {
255 public:
256     virtual void setData(GrGpuGL*,
257                          const GrGLProgramDataManager&,
258                          const GrEffectStage* effectStages[]) SK_OVERRIDE;
259
260 private:
261     friend class GrGLPathTexGenProgramEffectsBuilder;
262
263     GrGLPathTexGenProgramEffects(int reserveCount)
264         : INHERITED(reserveCount)
265         , fTransforms(reserveCount) {
266     }
267
268     /**
269      * Helper for GrGLProgramEffectsBuilder::emitEfffect(). This method is meant to only be called
270      * during the construction phase.
271      */
272     void emitEffect(GrGLFragmentOnlyShaderBuilder*,
273                     const GrEffectStage&,
274                     const GrEffectKey&,
275                     const char* outColor,
276                     const char* inColor,
277                     int stageIndex);
278
279     /**
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.
286      */
287     void setupPathTexGen(GrGLFragmentOnlyShaderBuilder*,
288                          const GrDrawEffect&,
289                          TransformedCoordsArray*);
290
291     /**
292      * Helper for setData(). Sets the PathTexGen state for each transform in an effect.
293      */
294     void setPathTexGenState(GrGpuGL*, const GrDrawEffect&, int effectIdx);
295
296     struct Transforms {
297         Transforms(uint32_t transformKey, int texCoordIndex)
298             : fTransformKey(transformKey), fTexCoordIndex(texCoordIndex) {}
299         uint32_t    fTransformKey;
300         int         fTexCoordIndex;
301     };
302
303     SkTArray<Transforms> fTransforms;
304
305     typedef GrGLProgramEffects INHERITED;
306 };
307
308 /**
309  * This class is used to construct a GrGLPathTexGenProgramEffects* object.
310  */
311 class GrGLPathTexGenProgramEffectsBuilder : public GrGLProgramEffectsBuilder {
312 public:
313     GrGLPathTexGenProgramEffectsBuilder(GrGLFragmentOnlyShaderBuilder*, int reserveCount);
314     virtual ~GrGLPathTexGenProgramEffectsBuilder() { }
315
316     virtual void emitEffect(const GrEffectStage&,
317                             const GrEffectKey&,
318                             const char* outColor,
319                             const char* inColor,
320                             int stageIndex) SK_OVERRIDE;
321
322     /**
323      * Finalizes the building process and returns the effect array. After this call, the builder
324      * becomes invalid.
325      */
326     GrGLProgramEffects* finish() { return fProgramEffects.detach(); }
327
328 private:
329     GrGLFragmentOnlyShaderBuilder*          fBuilder;
330     SkAutoTDelete<GrGLPathTexGenProgramEffects> fProgramEffects;
331
332     typedef GrGLProgramEffectsBuilder INHERITED;
333 };
334
335 #endif