1 #ifndef DALI_INTERNAL_PROGRAM_H
2 #define DALI_INTERNAL_PROGRAM_H
5 * Copyright (c) 2021 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.
22 #include <cstdint> // int32_t, uint32_t
26 #include <dali/integration-api/gl-abstraction.h>
27 #include <dali/internal/common/const-string.h>
28 #include <dali/internal/common/shader-data.h>
29 #include <dali/public-api/common/vector-wrapper.h>
30 #include <dali/public-api/object/ref-object.h>
39 } // namespace Graphics
47 } // namespace Integration
54 * A program contains a vertex & fragment shader.
56 * Program caches some of vertex attribute locations and uniform variable values to reduce unnecessary state changes.
62 * Size of the uniform cache per program
63 * GLES specification states that minimum uniform count for fragment shader
64 * is 16 and for vertex shader 128. We're caching the 16 common ones for now
66 static const int32_t MAX_UNIFORM_CACHE_SIZE = 16;
69 * Constant for uniform / attribute not found
71 static const int32_t NOT_FOUND = -1;
85 * Common shader uniform names
89 UNIFORM_NOT_QUERIED = -2,
92 UNIFORM_MODELVIEW_MATRIX,
93 UNIFORM_PROJECTION_MATRIX,
96 UNIFORM_NORMAL_MATRIX,
100 UNIFORM_EFFECT_SAMPLER,
107 * Indices of default uniforms
109 enum class DefaultUniformIndex
122 * Creates a new program, or returns a copy of an existing program in the program cache
123 * @param[in] cache where the programs are stored
124 * @param[in] shaderData A pointer to a data structure containing the program source
125 * and optionally precompiled binary. If the binary is empty the program bytecode
126 * is copied into it after compilation and linking)
127 * param[in] gfxController Reference to valid graphics Controller object
128 * param[in] gfxProgram Reference to vali graphics Program object
129 * @param[in] modifiesGeometry True if the shader modifies geometry
130 * @return pointer to the program
132 static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr<Graphics::Program>&& gfxProgram, bool modifiesGeometry);
135 * Takes this program into use
140 * @return true if this program is used currently
145 * @param [in] type of the attribute
146 * @return the index of the attribute
148 GLint GetAttribLocation(AttribType type);
151 * Register an attribute name in our local cache
152 * @param [in] name attribute name
153 * @return the index of the attribute name in local cache
155 uint32_t RegisterCustomAttribute(ConstString name);
158 * Gets the location of a pre-registered attribute.
159 * @param [in] attributeIndex of the attribute in local cache
160 * @return the index of the attribute in the GL program
162 GLint GetCustomAttributeLocation(uint32_t attributeIndex);
165 * Register a uniform name in our local cache
166 * @param [in] name uniform name
167 * @return the index of the uniform name in local cache
169 uint32_t RegisterUniform(ConstString name);
172 * Gets the location of a pre-registered uniform.
173 * Uniforms in list UniformType are always registered and in the order of the enumeration
174 * @param [in] uniformIndex of the uniform in local cache
175 * @return the index of the uniform in the GL program
177 GLint GetUniformLocation(uint32_t uniformIndex);
180 * Introspect the newly loaded shader to get the active sampler locations
182 void GetActiveSamplerUniforms();
185 * Gets the uniform location for a sampler
186 * @param [in] index The index of the active sampler
187 * @param [out] location The location of the requested sampler
188 * @return true if the active sampler was found
190 bool GetSamplerUniformLocation(uint32_t index, GLint& location);
193 * Get the number of active samplers present in the shader
194 * @return The number of active samplers
196 uint32_t GetActiveSamplerCount() const;
199 * Sets the uniform value
200 * @param [in] location of uniform
201 * @param [in] value0 as int
203 void SetUniform1i(GLint location, GLint value0);
206 * Sets the uniform value
207 * @param [in] location of uniform
208 * @param [in] value0 as int
209 * @param [in] value1 as int
210 * @param [in] value2 as int
211 * @param [in] value3 as int
213 void SetUniform4i(GLint location, GLint value0, GLint value1, GLint value2, GLint value3);
216 * Sets the uniform value
217 * @param [in] location of uniform
218 * @param [in] value0 as float
220 void SetUniform1f(GLint location, GLfloat value0);
223 * Sets the uniform value
224 * @param [in] location of uniform
225 * @param [in] value0 as float
226 * @param [in] value1 as float
228 void SetUniform2f(GLint location, GLfloat value0, GLfloat value1);
231 * Special handling for size as we're using uniform geometry so size is passed on to most programs
232 * but it rarely changes so we can cache it
233 * @param [in] location of uniform
234 * @param [in] value0 as float
235 * @param [in] value1 as float
236 * @param [in] value2 as float
238 void SetSizeUniform3f(GLint location, GLfloat value0, GLfloat value1, GLfloat value2);
241 * Sets the uniform value
242 * @param [in] location of uniform
243 * @param [in] value0 as float
244 * @param [in] value1 as float
245 * @param [in] value2 as float
247 void SetUniform3f(GLint location, GLfloat value0, GLfloat value1, GLfloat value2);
250 * Sets the uniform value
251 * @param [in] location of uniform
252 * @param [in] value0 as float
253 * @param [in] value1 as float
254 * @param [in] value2 as float
255 * @param [in] value3 as float
257 void SetUniform4f(GLint location, GLfloat value0, GLfloat value1, GLfloat value2, GLfloat value3);
260 * Sets the uniform value as matrix. NOTE! we never want GPU to transpose
261 * so make sure your matrix is in correct order for GL.
262 * @param [in] location Location of uniform
263 * @param [in] count Count of matrices
264 * @param [in] value values as float pointers
266 void SetUniformMatrix4fv(GLint location, GLsizei count, const GLfloat* value);
269 * Sets the uniform value as matrix. NOTE! we never want GPU to transpose
270 * so make sure your matrix is in correct order for GL.
271 * @param [in] location Location of uniform
272 * @param [in] count Count of matrices
273 * @param [in] value values as float pointers
275 void SetUniformMatrix3fv(GLint location, GLsizei count, const GLfloat* value);
278 * Needs to be called when GL context is (re)created
280 void GlContextCreated();
283 * Needs to be called when GL context is destroyed
285 void GlContextDestroyed();
288 * @return true if this program modifies geometry
290 bool ModifiesGeometry();
293 * Set the projection matrix that has currently been sent
294 * @param matrix to set
296 void SetProjectionMatrix(const Matrix* matrix)
298 mProjectionMatrix = matrix;
302 * Get the projection matrix that has currently been sent
303 * @return the matrix that is set
305 const Matrix* GetProjectionMatrix()
307 return mProjectionMatrix;
311 * Set the projection matrix that has currently been sent
312 * @param matrix to set
314 void SetViewMatrix(const Matrix* matrix)
316 mViewMatrix = matrix;
320 * Get the projection matrix that has currently been sent
321 * @return the matrix that is set
323 const Matrix* GetViewMatrix()
328 GLuint GetProgramId()
333 [[nodiscard]] Graphics::Program& GetGraphicsProgram() const
339 * Retrieves uniform data.
340 * The lookup tries to minimise string comparisons. Ideally, when the hashedName is known
341 * and there are no hash collisions in the reflection it's the most optimal case.
343 * @param name Name of uniform
344 * @param hashedName Hash value from name or 0 if unknown
345 * @param out Reference to output structure
347 * @return False when uniform is not found or due to hash collision the result is ambiguous
349 bool GetUniform(const std::string& name, size_t hashedName, Graphics::UniformInfo& out) const;
352 * Retrieves default uniform
353 * @param[in] defaultUniformIndex index of the uniform
354 * @param[out] outputUniformInfo the reference to UniformInfo object
355 * @return True is uniform found, false otherwise
357 bool GetDefaultUniform(DefaultUniformIndex defaultUniformIndex, Graphics::UniformInfo& outputUniformInfo) const;
360 * Retrievs default uniform
361 * @param[in] defaultUniformIndex index of the uniform
362 * @return Valid pointer to the UniformInfo object or nullptr
364 const Graphics::UniformInfo* GetDefaultUniform(DefaultUniformIndex defaultUniformIndex) const;
366 private: // Implementation
368 * Constructor, private so no direct instantiation
369 * @param[in] cache where the programs are stored
370 * @param[in] shaderData A smart pointer to a data structure containing the program source and binary
371 * @param[in] gfxProgram Graphics Program object
372 * @param[in] gfxController Reference to Graphics Controller object
373 * @param[in] modifiesGeometry True if the vertex shader changes geometry
375 Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr<Graphics::Program>&& gfxProgram, bool modifiesGeometry);
379 * Destructor, non virtual as no virtual methods or inheritance
384 Program(); ///< default constructor, not defined
385 Program(const Program&); ///< copy constructor, not defined
386 Program& operator=(const Program&); ///< assignment operator, not defined
391 void ResetAttribsUniformCache();
394 * Struct ReflectionUniformInfo
395 * Contains details of a single uniform buffer field and/or sampler.
397 struct ReflectionUniformInfo
400 bool hasCollision{false};
401 Graphics::UniformInfo uniformInfo{};
405 * Build optimized shader reflection of uniforms
406 * @param graphicsReflection The graphics reflection
408 void BuildReflection(const Graphics::Reflection& graphicsReflection);
411 ProgramCache& mCache; ///< The program cache
412 Integration::GlAbstraction& mGlAbstraction; ///< The OpenGL Abstraction layer
413 const Matrix* mProjectionMatrix; ///< currently set projection matrix
414 const Matrix* mViewMatrix; ///< currently set view matrix
415 GLuint mProgramId; ///< GL identifier for program
416 Graphics::UniquePtr<Graphics::Program> mGfxProgram; ///< Gfx program
417 Graphics::Controller& mGfxController; /// < Gfx controller
418 Internal::ShaderDataPtr mProgramData; ///< Shader program source and binary (when compiled & linked or loaded)
421 using NameLocationPair = std::pair<ConstString, GLint>;
422 using Locations = std::vector<NameLocationPair>;
424 Locations mAttributeLocations; ///< attribute location cache
425 Locations mUniformLocations; ///< uniform location cache
426 std::vector<GLint> mSamplerUniformLocations; ///< sampler uniform location cache
428 // uniform value caching
429 GLint mUniformCacheInt[MAX_UNIFORM_CACHE_SIZE]; ///< Value cache for uniforms of single int
430 GLfloat mUniformCacheFloat[MAX_UNIFORM_CACHE_SIZE]; ///< Value cache for uniforms of single float
431 GLfloat mUniformCacheFloat2[MAX_UNIFORM_CACHE_SIZE][2]; ///< Value cache for uniforms of two floats
432 GLfloat mUniformCacheFloat4[MAX_UNIFORM_CACHE_SIZE][4]; ///< Value cache for uniforms of four floats
433 Vector3 mSizeUniformCache; ///< Cache value for size uniform
434 bool mModifiesGeometry; ///< True if the program changes geometry
436 using UniformReflectionContainer = std::vector<ReflectionUniformInfo>;
438 UniformReflectionContainer mReflection{}; ///< Contains reflection build per program
439 UniformReflectionContainer mReflectionDefaultUniforms{}; ///< Contains default uniforms
442 } // namespace Internal
446 #endif // DALI_INTERNAL_PROGRAM_H