Merge branch 'devel/master' into devel/new_mesh
[platform/core/uifw/dali-core.git] / dali / internal / render / shaders / program.h
1 #ifndef __DALI_INTERNAL_PROGRAM_H__
2 #define __DALI_INTERNAL_PROGRAM_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <string>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/vector-wrapper.h>
26 #include <dali/public-api/object/ref-object.h>
27 #include <dali/integration-api/gl-abstraction.h>
28 #include <dali/integration-api/shader-data.h>
29
30 namespace Dali
31 {
32
33 class Matrix;
34
35 namespace Integration
36 {
37 class GlAbstraction;
38 class ShaderData;
39 }
40
41 namespace Internal
42 {
43
44 class ProgramCache;
45
46 /*
47  * A program contains a vertex & fragment shader.
48  *
49  * A program will contain vertex attributes and uniform variables.
50  *
51  * uColor is set to the value specified by Actor::SetColor and is
52  * animatable through the property Actor::COLOR
53  */
54 class Program
55 {
56 public:
57
58   /**
59    * Size of the uniform cache per program
60    * GLES specification states that minimum uniform count for fragment shader
61    * is 16 and for vertex shader 128. We're caching the 16 common ones for now
62    */
63   static const int MAX_UNIFORM_CACHE_SIZE = 16;
64
65   /**
66    * Constant for uniform / attribute not found
67    */
68   static const int NOT_FOUND = -1;
69
70   /**
71    * Vertex attributes
72    */
73   enum AttribType
74   {
75     ATTRIB_UNKNOWN = -1,
76     ATTRIB_POSITION,
77     ATTRIB_NORMAL,
78     ATTRIB_TEXCOORD,
79     ATTRIB_COLOR,
80     ATTRIB_BONE_WEIGHTS,
81     ATTRIB_BONE_INDICES,
82     ATTRIB_TYPE_LAST
83   };
84
85   /**
86    * Common shader uniform names
87    */
88   enum UniformType
89   {
90     UNIFORM_NOT_QUERIED = -2,
91     UNIFORM_UNKNOWN = -1,
92     UNIFORM_MVP_MATRIX,
93     UNIFORM_MODELVIEW_MATRIX,
94     UNIFORM_PROJECTION_MATRIX,
95     UNIFORM_MODEL_MATRIX,
96     UNIFORM_VIEW_MATRIX,
97     UNIFORM_NORMAL_MATRIX,
98     UNIFORM_COLOR,
99     UNIFORM_CUSTOM_TEXTURE_COORDS,
100     UNIFORM_SAMPLER,
101     UNIFORM_SAMPLER_RECT,
102     UNIFORM_EFFECT_SAMPLER,
103     UNIFORM_EFFECT_SAMPLER_RECT,
104     UNIFORM_TIME_DELTA,
105     UNIFORM_SAMPLER_OPACITY,
106     UNIFORM_SAMPLER_NORMAL_MAP,
107
108     UNIFORM_SIZE,
109     UNIFORM_TYPE_LAST
110   };
111
112   /**
113    * Creates a new program, or returns a copy of an existing program in the program cache
114    * @param[in] cache where the programs are stored
115    * @param[in] shaderData  A pointer to a data structure containing the program source
116    *                        and optionally precompiled binary. If the binary is empty the program bytecode
117    *                        is copied into it after compilation and linking)
118    * @param[in] modifiesGeometry True if the shader modifies geometry
119    * @return pointer to the program
120    */
121   static Program* New( ProgramCache& cache, Integration::ShaderDataPtr shaderData, bool modifiesGeometry );
122
123   /**
124    * Takes this program into use
125    */
126   void Use();
127
128   /**
129    * @return true if this program is used currently
130    */
131   bool IsUsed();
132
133   /**
134    * @param [in] type of the attribute
135    * @return the index of the attribute
136    */
137   GLint GetAttribLocation( AttribType type );
138
139   /**
140    * Register an attribute name in our local cache
141    * @param [in] name attribute name
142    * @return the index of the attribute name in local cache
143    */
144   unsigned int RegisterCustomAttribute( const std::string& name );
145
146   /**
147    * Gets the location of a pre-registered attribute.
148    * @param [in] attributeIndex of the attribute in local cache
149    * @return the index of the attribute in the GL program
150    */
151   GLint GetCustomAttributeLocation( unsigned int attributeIndex );
152
153   /**
154    * Register a uniform name in our local cache
155    * @param [in] name uniform name
156    * @return the index of the uniform name in local cache
157    */
158   unsigned int RegisterUniform( const std::string& name );
159
160   /**
161    * Gets the location of a pre-registered uniform.
162    * Uniforms in list UniformType are always registered and in the order of the enumeration
163    * @param [in] uniformIndex of the uniform in local cache
164    * @return the index of the uniform in the GL program
165    */
166   GLint GetUniformLocation( unsigned int uniformIndex );
167
168   /**
169    * Sets the uniform value
170    * @param [in] location of uniform
171    * @param [in] value0 as int
172    */
173   void SetUniform1i( GLint location, GLint value0 );
174
175   /**
176    * Sets the uniform value
177    * @param [in] location of uniform
178    * @param [in] value0 as int
179    * @param [in] value1 as int
180    * @param [in] value2 as int
181    * @param [in] value3 as int
182    */
183   void SetUniform4i( GLint location, GLint value0, GLint value1, GLint value2, GLint value3 );
184
185   /**
186    * Sets the uniform value
187    * @param [in] location of uniform
188    * @param [in] value0 as float
189    */
190   void SetUniform1f( GLint location, GLfloat value0 );
191
192   /**
193    * Sets the uniform value
194    * @param [in] location of uniform
195    * @param [in] value0 as float
196    * @param [in] value1 as float
197    */
198   void SetUniform2f( GLint location, GLfloat value0, GLfloat value1 );
199
200   /**
201    * Sets the uniform value
202    * @param [in] location of uniform
203    * @param [in] value0 as float
204    * @param [in] value1 as float
205    * @param [in] value2 as float
206    */
207   void SetUniform3f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2 );
208
209   /**
210    * Sets the uniform value
211    * @param [in] location of uniform
212    * @param [in] value0 as float
213    * @param [in] value1 as float
214    * @param [in] value2 as float
215    * @param [in] value3 as float
216    */
217   void SetUniform4f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2, GLfloat value3 );
218
219   /**
220    * Sets the uniform value as matrix. NOTE! we never want GPU to transpose
221    * so make sure your matrix is in correct order for GL.
222    * @param [in] location Location of uniform
223    * @param [in] count Count of matrices
224    * @param [in] value values as float pointers
225    */
226   void SetUniformMatrix4fv( GLint location, GLsizei count, const GLfloat* value );
227
228   /**
229    * Sets the uniform value as matrix. NOTE! we never want GPU to transpose
230    * so make sure your matrix is in correct order for GL.
231    * @param [in] location Location of uniform
232    * @param [in] count Count of matrices
233    * @param [in] value values as float pointers
234    */
235   void SetUniformMatrix3fv( GLint location, GLsizei count, const GLfloat* value );
236
237   /**
238    * Needs to be called when GL context is (re)created
239    */
240   void GlContextCreated();
241
242   /**
243    * Needs to be called when GL context is destroyed
244    */
245   void GlContextDestroyed();
246
247   /**
248    * @return true if this program modifies geometry
249    */
250   bool ModifiesGeometry();
251
252   /**
253    * Set the projection matrix that has currently been sent
254    * @param matrix to set
255    */
256   void SetProjectionMatrix( const Matrix* matrix )
257   {
258     mProjectionMatrix = matrix;
259   }
260
261   /**
262    * Get the projection matrix that has currently been sent
263    * @return the matrix that is set
264    */
265   const Matrix* GetProjectionMatrix()
266   {
267     return mProjectionMatrix;
268   }
269
270   /**
271    * Set the projection matrix that has currently been sent
272    * @param matrix to set
273    */
274   void SetViewMatrix( const Matrix* matrix )
275   {
276     mViewMatrix = matrix;
277   }
278
279   /**
280    * Get the projection matrix that has currently been sent
281    * @return the matrix that is set
282    */
283   const Matrix* GetViewMatrix()
284   {
285     return mViewMatrix;
286   }
287
288 private: // Implementation
289
290   /**
291    * Constructor, private so no direct instantiation
292    * @param[in] cache where the programs are stored
293    * @param[in] shaderData A smart pointer to a data structure containing the program source and binary
294    * @param[in] modifiesGeometry True if the vertex shader changes geometry
295    */
296   Program( ProgramCache& cache, Integration::ShaderDataPtr shaderData, bool modifiesGeometry );
297
298 public:
299
300   /**
301    * Destructor, non virtual as no virtual methods or inheritance
302    */
303   ~Program();
304
305 private:
306
307   // default constructor, not defined
308   Program();
309   // assignment operator, not defined
310   Program& operator=( const Program& );
311
312   /**
313    * Load the shader, from a precompiled binary if available, else from source code
314    */
315   void Load();
316
317   /**
318    * Unload the shader
319    */
320   void Unload();
321
322   /**
323    * Compile the shader
324    * @param shaderType vertex or fragment shader
325    * @param shaderId of the shader, returned
326    * @param src of the shader
327    * @return true if the compilation succeeded
328    */
329   bool CompileShader(GLenum shaderType, GLuint& shaderId, const char* src);
330
331   /**
332    * Links the shaders together to create program
333    */
334   void Link();
335
336   /**
337    * Frees the shader programs
338    */
339   void FreeShaders();
340
341   /**
342    * Resets caches
343    */
344   void ResetAttribsUniformCache();
345
346 private:  // Data
347
348   ProgramCache& mCache;                       ///< The program cache
349   Integration::GlAbstraction& mGlAbstraction; ///< The OpenGL Abstraction layer
350   const Matrix* mProjectionMatrix;            ///< currently set projection matrix
351   const Matrix* mViewMatrix;                  ///< currently set view matrix
352   bool mLinked;                               ///< whether the program is linked
353   GLuint mVertexShaderId;                     ///< GL identifier for vertex shader
354   GLuint mFragmentShaderId;                   ///< GL identifier for fragment shader
355   GLuint mProgramId;                          ///< GL identifier for program
356   Integration::ShaderDataPtr mProgramData;    ///< Shader program source and binary (when compiled & linked or loaded)
357
358   // location caches
359   std::vector< std::pair< std::string, GLint > > mAttributeLocations; ///< attribute location cache
360   std::vector< std::pair< std::string, GLint > > mUniformLocations; ///< uniform location cache
361
362   // uniform value caching
363   GLint mUniformCacheInt[ MAX_UNIFORM_CACHE_SIZE ];         ///< Value cache for uniforms of single int
364   GLfloat mUniformCacheFloat[ MAX_UNIFORM_CACHE_SIZE ];     ///< Value cache for uniforms of single float
365   GLfloat mUniformCacheFloat4[ MAX_UNIFORM_CACHE_SIZE ][4]; ///< Value cache for uniforms of four float
366   bool mModifiesGeometry;  ///< True if the program changes geometry
367
368 };
369
370 } // namespace Internal
371
372 } // namespace Dali
373
374 #endif // __DALI_INTERNAL_PROGRAM_H__