1 #ifndef DALI_INTERNAL_PROGRAM_H
2 #define DALI_INTERNAL_PROGRAM_H
5 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include <cstdint> // int32_t, uint32_t
26 #include <dali/public-api/common/vector-wrapper.h>
27 #include <dali/public-api/object/ref-object.h>
28 #include <dali/integration-api/gl-abstraction.h>
29 #include <dali/internal/common/shader-data.h>
48 * A program contains a vertex & fragment shader.
50 * Program caches some of vertex attribute locations and uniform variable values to reduce unnecessary state changes.
57 * Size of the uniform cache per program
58 * GLES specification states that minimum uniform count for fragment shader
59 * is 16 and for vertex shader 128. We're caching the 16 common ones for now
61 static const int32_t MAX_UNIFORM_CACHE_SIZE = 16;
64 * Constant for uniform / attribute not found
66 static const int32_t NOT_FOUND = -1;
80 * Common shader uniform names
84 UNIFORM_NOT_QUERIED = -2,
87 UNIFORM_MODELVIEW_MATRIX,
88 UNIFORM_PROJECTION_MATRIX,
91 UNIFORM_NORMAL_MATRIX,
95 UNIFORM_EFFECT_SAMPLER,
102 * Creates a new program, or returns a copy of an existing program in the program cache
103 * @param[in] cache where the programs are stored
104 * @param[in] shaderData A pointer to a data structure containing the program source
105 * and optionally precompiled binary. If the binary is empty the program bytecode
106 * is copied into it after compilation and linking)
107 * @param[in] modifiesGeometry True if the shader modifies geometry
108 * @return pointer to the program
110 static Program* New( ProgramCache& cache, Internal::ShaderDataPtr shaderData, bool modifiesGeometry );
113 * Takes this program into use
118 * @return true if this program is used currently
123 * @param [in] type of the attribute
124 * @return the index of the attribute
126 GLint GetAttribLocation( AttribType type );
129 * Register an attribute name in our local cache
130 * @param [in] name attribute name
131 * @return the index of the attribute name in local cache
133 uint32_t RegisterCustomAttribute( const std::string& name );
136 * Gets the location of a pre-registered attribute.
137 * @param [in] attributeIndex of the attribute in local cache
138 * @return the index of the attribute in the GL program
140 GLint GetCustomAttributeLocation( uint32_t attributeIndex );
143 * Register a uniform name in our local cache
144 * @param [in] name uniform name
145 * @return the index of the uniform name in local cache
147 uint32_t RegisterUniform( const std::string& name );
150 * Gets the location of a pre-registered uniform.
151 * Uniforms in list UniformType are always registered and in the order of the enumeration
152 * @param [in] uniformIndex of the uniform in local cache
153 * @return the index of the uniform in the GL program
155 GLint GetUniformLocation( uint32_t uniformIndex );
158 * Introspect the newly loaded shader to get the active sampler locations
160 void GetActiveSamplerUniforms();
163 * Gets the uniform location for a sampler
164 * @param [in] index The index of the active sampler
165 * @param [out] location The location of the requested sampler
166 * @return true if the active sampler was found
168 bool GetSamplerUniformLocation( uint32_t index, GLint& location );
171 * Get the number of active samplers present in the shader
172 * @return The number of active samplers
174 uint32_t GetActiveSamplerCount() const;
177 * Sets the uniform value
178 * @param [in] location of uniform
179 * @param [in] value0 as int
181 void SetUniform1i( GLint location, GLint value0 );
184 * Sets the uniform value
185 * @param [in] location of uniform
186 * @param [in] value0 as int
187 * @param [in] value1 as int
188 * @param [in] value2 as int
189 * @param [in] value3 as int
191 void SetUniform4i( GLint location, GLint value0, GLint value1, GLint value2, GLint value3 );
194 * Sets the uniform value
195 * @param [in] location of uniform
196 * @param [in] value0 as float
198 void SetUniform1f( GLint location, GLfloat value0 );
201 * Sets the uniform value
202 * @param [in] location of uniform
203 * @param [in] value0 as float
204 * @param [in] value1 as float
206 void SetUniform2f( GLint location, GLfloat value0, GLfloat value1 );
209 * Special handling for size as we're using uniform geometry so size is passed on to most programs
210 * but it rarely changes so we can cache it
211 * @param [in] location of uniform
212 * @param [in] value0 as float
213 * @param [in] value1 as float
214 * @param [in] value2 as float
216 void SetSizeUniform3f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2 );
219 * Sets the uniform value
220 * @param [in] location of uniform
221 * @param [in] value0 as float
222 * @param [in] value1 as float
223 * @param [in] value2 as float
225 void SetUniform3f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2 );
228 * Sets the uniform value
229 * @param [in] location of uniform
230 * @param [in] value0 as float
231 * @param [in] value1 as float
232 * @param [in] value2 as float
233 * @param [in] value3 as float
235 void SetUniform4f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2, GLfloat value3 );
238 * Sets the uniform value as matrix. NOTE! we never want GPU to transpose
239 * so make sure your matrix is in correct order for GL.
240 * @param [in] location Location of uniform
241 * @param [in] count Count of matrices
242 * @param [in] value values as float pointers
244 void SetUniformMatrix4fv( GLint location, GLsizei count, const GLfloat* value );
247 * Sets the uniform value as matrix. NOTE! we never want GPU to transpose
248 * so make sure your matrix is in correct order for GL.
249 * @param [in] location Location of uniform
250 * @param [in] count Count of matrices
251 * @param [in] value values as float pointers
253 void SetUniformMatrix3fv( GLint location, GLsizei count, const GLfloat* value );
256 * Needs to be called when GL context is (re)created
258 void GlContextCreated();
261 * Needs to be called when GL context is destroyed
263 void GlContextDestroyed();
266 * @return true if this program modifies geometry
268 bool ModifiesGeometry();
271 * Set the projection matrix that has currently been sent
272 * @param matrix to set
274 void SetProjectionMatrix( const Matrix* matrix )
276 mProjectionMatrix = matrix;
280 * Get the projection matrix that has currently been sent
281 * @return the matrix that is set
283 const Matrix* GetProjectionMatrix()
285 return mProjectionMatrix;
289 * Set the projection matrix that has currently been sent
290 * @param matrix to set
292 void SetViewMatrix( const Matrix* matrix )
294 mViewMatrix = matrix;
298 * Get the projection matrix that has currently been sent
299 * @return the matrix that is set
301 const Matrix* GetViewMatrix()
306 private: // Implementation
309 * Constructor, private so no direct instantiation
310 * @param[in] cache where the programs are stored
311 * @param[in] shaderData A smart pointer to a data structure containing the program source and binary
312 * @param[in] modifiesGeometry True if the vertex shader changes geometry
314 Program( ProgramCache& cache, Internal::ShaderDataPtr shaderData, bool modifiesGeometry );
319 * Destructor, non virtual as no virtual methods or inheritance
325 Program(); ///< default constructor, not defined
326 Program( const Program& ); ///< copy constructor, not defined
327 Program& operator=( const Program& ); ///< assignment operator, not defined
330 * Load the shader, from a precompiled binary if available, else from source code
341 * @param shaderType vertex or fragment shader
342 * @param shaderId of the shader, returned
343 * @param src of the shader
344 * @return true if the compilation succeeded
346 bool CompileShader(GLenum shaderType, GLuint& shaderId, const char* src);
349 * Links the shaders together to create program
354 * Frees the shader programs
361 void ResetAttribsUniformCache();
365 ProgramCache& mCache; ///< The program cache
366 Integration::GlAbstraction& mGlAbstraction; ///< The OpenGL Abstraction layer
367 const Matrix* mProjectionMatrix; ///< currently set projection matrix
368 const Matrix* mViewMatrix; ///< currently set view matrix
369 bool mLinked; ///< whether the program is linked
370 GLuint mVertexShaderId; ///< GL identifier for vertex shader
371 GLuint mFragmentShaderId; ///< GL identifier for fragment shader
372 GLuint mProgramId; ///< GL identifier for program
373 Internal::ShaderDataPtr mProgramData; ///< Shader program source and binary (when compiled & linked or loaded)
376 using NameLocationPair = std::pair<std::string, GLint>;
377 using Locations = std::vector<NameLocationPair>;
379 Locations mAttributeLocations; ///< attribute location cache
380 Locations mUniformLocations; ///< uniform location cache
381 std::vector<GLint> mSamplerUniformLocations; ///< sampler uniform location cache
383 // uniform value caching
384 GLint mUniformCacheInt[ MAX_UNIFORM_CACHE_SIZE ]; ///< Value cache for uniforms of single int
385 GLfloat mUniformCacheFloat[ MAX_UNIFORM_CACHE_SIZE ]; ///< Value cache for uniforms of single float
386 GLfloat mUniformCacheFloat2[ MAX_UNIFORM_CACHE_SIZE ][2]; ///< Value cache for uniforms of two floats
387 GLfloat mUniformCacheFloat4[ MAX_UNIFORM_CACHE_SIZE ][4]; ///< Value cache for uniforms of four floats
388 Vector3 mSizeUniformCache; ///< Cache value for size uniform
389 bool mModifiesGeometry; ///< True if the program changes geometry
393 } // namespace Internal
397 #endif // DALI_INTERNAL_PROGRAM_H