cd55e66737470de77c9139cfa9d420a4db9067f6
[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) 2016 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/internal/common/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_TEXCOORD,
78     ATTRIB_TYPE_LAST
79   };
80
81   /**
82    * Common shader uniform names
83    */
84   enum UniformType
85   {
86     UNIFORM_NOT_QUERIED = -2,
87     UNIFORM_UNKNOWN = -1,
88     UNIFORM_MVP_MATRIX,
89     UNIFORM_MODELVIEW_MATRIX,
90     UNIFORM_PROJECTION_MATRIX,
91     UNIFORM_MODEL_MATRIX,
92     UNIFORM_VIEW_MATRIX,
93     UNIFORM_NORMAL_MATRIX,
94     UNIFORM_COLOR,
95     UNIFORM_SAMPLER,
96     UNIFORM_SAMPLER_RECT,
97     UNIFORM_EFFECT_SAMPLER,
98
99     UNIFORM_SIZE,
100     UNIFORM_TYPE_LAST
101   };
102
103   /**
104    * Creates a new program, or returns a copy of an existing program in the program cache
105    * @param[in] cache where the programs are stored
106    * @param[in] shaderData  A pointer to a data structure containing the program source
107    *                        and optionally precompiled binary. If the binary is empty the program bytecode
108    *                        is copied into it after compilation and linking)
109    * @param[in] modifiesGeometry True if the shader modifies geometry
110    * @return pointer to the program
111    */
112   static Program* New( ProgramCache& cache, Internal::ShaderDataPtr shaderData, bool modifiesGeometry );
113
114   /**
115    * Takes this program into use
116    */
117   void Use();
118
119   /**
120    * @return true if this program is used currently
121    */
122   bool IsUsed();
123
124   /**
125    * @param [in] type of the attribute
126    * @return the index of the attribute
127    */
128   GLint GetAttribLocation( AttribType type );
129
130   /**
131    * Register an attribute name in our local cache
132    * @param [in] name attribute name
133    * @return the index of the attribute name in local cache
134    */
135   unsigned int RegisterCustomAttribute( const std::string& name );
136
137   /**
138    * Gets the location of a pre-registered attribute.
139    * @param [in] attributeIndex of the attribute in local cache
140    * @return the index of the attribute in the GL program
141    */
142   GLint GetCustomAttributeLocation( unsigned int attributeIndex );
143
144   /**
145    * Register a uniform name in our local cache
146    * @param [in] name uniform name
147    * @return the index of the uniform name in local cache
148    */
149   unsigned int RegisterUniform( const std::string& name );
150
151   /**
152    * Gets the location of a pre-registered uniform.
153    * Uniforms in list UniformType are always registered and in the order of the enumeration
154    * @param [in] uniformIndex of the uniform in local cache
155    * @return the index of the uniform in the GL program
156    */
157   GLint GetUniformLocation( unsigned int uniformIndex );
158
159   /**
160    * Introspect the newly loaded shader to get the active sampler locations
161    */
162   void GetActiveSamplerUniforms();
163
164   /**
165    * Gets the uniform location for a sampler
166    * @param [in] index The index of the active sampler
167    * @param [out] location The location of the requested sampler
168    * @return true if the active sampler was found
169    */
170   bool GetSamplerUniformLocation( unsigned int index, GLint& location );
171
172   /**
173    * Get the number of active samplers present in the shader
174    * @return The number of active samplers
175    */
176   size_t GetActiveSamplerCount() const;
177
178   /**
179    * Sets the uniform value
180    * @param [in] location of uniform
181    * @param [in] value0 as int
182    */
183   void SetUniform1i( GLint location, GLint value0 );
184
185   /**
186    * Sets the uniform value
187    * @param [in] location of uniform
188    * @param [in] value0 as int
189    * @param [in] value1 as int
190    * @param [in] value2 as int
191    * @param [in] value3 as int
192    */
193   void SetUniform4i( GLint location, GLint value0, GLint value1, GLint value2, GLint value3 );
194
195   /**
196    * Sets the uniform value
197    * @param [in] location of uniform
198    * @param [in] value0 as float
199    */
200   void SetUniform1f( GLint location, GLfloat value0 );
201
202   /**
203    * Sets the uniform value
204    * @param [in] location of uniform
205    * @param [in] value0 as float
206    * @param [in] value1 as float
207    */
208   void SetUniform2f( GLint location, GLfloat value0, GLfloat value1 );
209
210   /**
211    * Special handling for size as we're using uniform geometry so size is passed on to most programs
212    * but it rarely changes so we can cache it
213    * @param [in] location of uniform
214    * @param [in] value0 as float
215    * @param [in] value1 as float
216    * @param [in] value2 as float
217    */
218   void SetSizeUniform3f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2 );
219
220   /**
221    * Sets the uniform value
222    * @param [in] location of uniform
223    * @param [in] value0 as float
224    * @param [in] value1 as float
225    * @param [in] value2 as float
226    */
227   void SetUniform3f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2 );
228
229   /**
230    * Sets the uniform value
231    * @param [in] location of uniform
232    * @param [in] value0 as float
233    * @param [in] value1 as float
234    * @param [in] value2 as float
235    * @param [in] value3 as float
236    */
237   void SetUniform4f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2, GLfloat value3 );
238
239   /**
240    * Sets the uniform value as matrix. NOTE! we never want GPU to transpose
241    * so make sure your matrix is in correct order for GL.
242    * @param [in] location Location of uniform
243    * @param [in] count Count of matrices
244    * @param [in] value values as float pointers
245    */
246   void SetUniformMatrix4fv( GLint location, GLsizei count, const GLfloat* value );
247
248   /**
249    * Sets the uniform value as matrix. NOTE! we never want GPU to transpose
250    * so make sure your matrix is in correct order for GL.
251    * @param [in] location Location of uniform
252    * @param [in] count Count of matrices
253    * @param [in] value values as float pointers
254    */
255   void SetUniformMatrix3fv( GLint location, GLsizei count, const GLfloat* value );
256
257   /**
258    * Needs to be called when GL context is (re)created
259    */
260   void GlContextCreated();
261
262   /**
263    * Needs to be called when GL context is destroyed
264    */
265   void GlContextDestroyed();
266
267   /**
268    * @return true if this program modifies geometry
269    */
270   bool ModifiesGeometry();
271
272   /**
273    * Set the projection matrix that has currently been sent
274    * @param matrix to set
275    */
276   void SetProjectionMatrix( const Matrix* matrix )
277   {
278     mProjectionMatrix = matrix;
279   }
280
281   /**
282    * Get the projection matrix that has currently been sent
283    * @return the matrix that is set
284    */
285   const Matrix* GetProjectionMatrix()
286   {
287     return mProjectionMatrix;
288   }
289
290   /**
291    * Set the projection matrix that has currently been sent
292    * @param matrix to set
293    */
294   void SetViewMatrix( const Matrix* matrix )
295   {
296     mViewMatrix = matrix;
297   }
298
299   /**
300    * Get the projection matrix that has currently been sent
301    * @return the matrix that is set
302    */
303   const Matrix* GetViewMatrix()
304   {
305     return mViewMatrix;
306   }
307
308 private: // Implementation
309
310   /**
311    * Constructor, private so no direct instantiation
312    * @param[in] cache where the programs are stored
313    * @param[in] shaderData A smart pointer to a data structure containing the program source and binary
314    * @param[in] modifiesGeometry True if the vertex shader changes geometry
315    */
316   Program( ProgramCache& cache, Internal::ShaderDataPtr shaderData, bool modifiesGeometry );
317
318 public:
319
320   /**
321    * Destructor, non virtual as no virtual methods or inheritance
322    */
323   ~Program();
324
325 private:
326
327   Program(); ///> default constructor, not defined
328   Program( const Program& ); ///< copy constructor, not defined
329   Program& operator=( const Program& ); ///< assignment operator, not defined
330
331   /**
332    * Load the shader, from a precompiled binary if available, else from source code
333    */
334   void Load();
335
336   /**
337    * Unload the shader
338    */
339   void Unload();
340
341   /**
342    * Compile the shader
343    * @param shaderType vertex or fragment shader
344    * @param shaderId of the shader, returned
345    * @param src of the shader
346    * @return true if the compilation succeeded
347    */
348   bool CompileShader(GLenum shaderType, GLuint& shaderId, const char* src);
349
350   /**
351    * Links the shaders together to create program
352    */
353   void Link();
354
355   /**
356    * Frees the shader programs
357    */
358   void FreeShaders();
359
360   /**
361    * Resets caches
362    */
363   void ResetAttribsUniformCache();
364
365 private:  // Data
366
367   ProgramCache& mCache;                       ///< The program cache
368   Integration::GlAbstraction& mGlAbstraction; ///< The OpenGL Abstraction layer
369   const Matrix* mProjectionMatrix;            ///< currently set projection matrix
370   const Matrix* mViewMatrix;                  ///< currently set view matrix
371   bool mLinked;                               ///< whether the program is linked
372   GLuint mVertexShaderId;                     ///< GL identifier for vertex shader
373   GLuint mFragmentShaderId;                   ///< GL identifier for fragment shader
374   GLuint mProgramId;                          ///< GL identifier for program
375   Internal::ShaderDataPtr mProgramData;       ///< Shader program source and binary (when compiled & linked or loaded)
376
377   // location caches
378   typedef std::pair< std::string, GLint > NameLocationPair;
379   typedef std::vector< NameLocationPair > Locations;
380
381   Locations mAttributeLocations;      ///< attribute location cache
382   Locations mUniformLocations;        ///< uniform location cache
383   std::vector<GLint> mSamplerUniformLocations; ///< sampler uniform location cache
384
385   // uniform value caching
386   GLint mUniformCacheInt[ MAX_UNIFORM_CACHE_SIZE ];         ///< Value cache for uniforms of single int
387   GLfloat mUniformCacheFloat[ MAX_UNIFORM_CACHE_SIZE ];     ///< Value cache for uniforms of single float
388   GLfloat mUniformCacheFloat2[ MAX_UNIFORM_CACHE_SIZE ][2]; ///< Value cache for uniforms of two floats
389   GLfloat mUniformCacheFloat4[ MAX_UNIFORM_CACHE_SIZE ][4]; ///< Value cache for uniforms of four floats
390   Vector3 mSizeUniformCache;                                ///< Cache value for size uniform
391   bool mModifiesGeometry;  ///< True if the program changes geometry
392
393 };
394
395 } // namespace Internal
396
397 } // namespace Dali
398
399 #endif // __DALI_INTERNAL_PROGRAM_H__