-#ifndef __DALI_INTERNAL_PROGRAM_H__
-#define __DALI_INTERNAL_PROGRAM_H__
+#ifndef DALI_INTERNAL_PROGRAM_H
+#define DALI_INTERNAL_PROGRAM_H
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
// EXTERNAL INCLUDES
+#include <cstdint> // int32_t, uint32_t
#include <string>
// INTERNAL INCLUDES
+#include <dali/internal/common/const-string.h>
+#include <dali/internal/common/shader-data.h>
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/object/ref-object.h>
-#include <dali/integration-api/gl-abstraction.h>
-#include <dali/integration-api/shader-data.h>
namespace Dali
{
+namespace Graphics
+{
+class Controller;
+class Program;
+class Reflection;
+} // namespace Graphics
class Matrix;
-namespace Integration
-{
-class GlAbstraction;
-class ShaderData;
-}
-
namespace Internal
{
-
class ProgramCache;
-/*
+/**
* A program contains a vertex & fragment shader.
- *
- * A program will contain vertex attributes and uniform variables.
- *
- * uColor is set to the value specified by Actor::SetColor and is
- * animatable through the property Actor::COLOR
+ * It interfaces to the implementation program and it's reflection.
*/
class Program
{
public:
+ using Hash = std::size_t;
/**
- * Size of the uniform cache per program
- * GLES specification states that minimum uniform count for fragment shader
- * is 16 and for vertex shader 128. We're caching the 16 common ones for now
- */
- static const int MAX_UNIFORM_CACHE_SIZE = 16;
-
- /**
- * Constant for uniform / attribute not found
- */
- static const int NOT_FOUND = -1;
-
- /**
- * Vertex attributes
+ * Indices of default uniforms
*/
- enum AttribType
+ enum class DefaultUniformIndex
{
- ATTRIB_UNKNOWN = -1,
- ATTRIB_POSITION,
- ATTRIB_NORMAL,
- ATTRIB_TEXCOORD,
- ATTRIB_COLOR,
- ATTRIB_BONE_WEIGHTS,
- ATTRIB_BONE_INDICES,
- ATTRIB_TYPE_LAST
- };
-
- /**
- * Common shader uniform names
- */
- enum UniformType
- {
- UNIFORM_NOT_QUERIED = -2,
- UNIFORM_UNKNOWN = -1,
- UNIFORM_MVP_MATRIX,
- UNIFORM_MODELVIEW_MATRIX,
- UNIFORM_PROJECTION_MATRIX,
- UNIFORM_MODEL_MATRIX,
- UNIFORM_VIEW_MATRIX,
- UNIFORM_NORMAL_MATRIX,
- UNIFORM_COLOR,
- UNIFORM_CUSTOM_TEXTURE_COORDS,
- UNIFORM_SAMPLER,
- UNIFORM_SAMPLER_RECT,
- UNIFORM_EFFECT_SAMPLER,
- UNIFORM_EFFECT_SAMPLER_RECT,
- UNIFORM_TIME_DELTA,
- UNIFORM_SAMPLER_OPACITY,
- UNIFORM_SAMPLER_NORMAL_MAP,
-
- UNIFORM_TYPE_LAST
+ MODEL_MATRIX = 0,
+ MVP_MATRIX,
+ VIEW_MATRIX,
+ MODEL_VIEW_MATRIX,
+ NORMAL_MATRIX,
+ PROJECTION_MATRIX,
+ SIZE,
+ COLOR,
+ ACTOR_COLOR,
+
+ COUNT
};
/**
* @param[in] shaderData A pointer to a data structure containing the program source
* and optionally precompiled binary. If the binary is empty the program bytecode
* is copied into it after compilation and linking)
- * @param[in] modifiesGeometry True if the shader modifies geometry
+ * @param[in] gfxController Reference to valid graphics Controller object
* @return pointer to the program
*/
- static Program* New( ProgramCache& cache, Integration::ShaderDataPtr shaderData, bool modifiesGeometry );
-
- /**
- * Takes this program into use
- */
- void Use();
-
- /**
- * @return true if this program is used currently
- */
- bool IsUsed();
-
- /**
- * @param [in] type of the attribute
- * @return the index of the attribute
- */
- GLint GetAttribLocation( AttribType type );
-
- /**
- * Register a uniform name in our local cache
- * @param [in] name uniform name
- * @return the index of the uniform name in local cache
- */
- unsigned int RegisterUniform( const std::string& name );
-
- /**
- * Gets the location of a pre-registered uniform.
- * Uniforms in list UniformType are always registered and in the order of the enumeration
- * @param [in] uniformIndex of the uniform in local cache
- * @return the index of the uniform in the GL program
- */
- GLint GetUniformLocation( unsigned int uniformIndex );
-
- /**
- * Sets the uniform value
- * @param [in] location of uniform
- * @param [in] value0 as int
- */
- void SetUniform1i( GLint location, GLint value0 );
-
- /**
- * Sets the uniform value
- * @param [in] location of uniform
- * @param [in] value0 as int
- * @param [in] value1 as int
- * @param [in] value2 as int
- * @param [in] value3 as int
- */
- void SetUniform4i( GLint location, GLint value0, GLint value1, GLint value2, GLint value3 );
-
- /**
- * Sets the uniform value
- * @param [in] location of uniform
- * @param [in] value0 as float
- */
- void SetUniform1f( GLint location, GLfloat value0 );
-
- /**
- * Sets the uniform value
- * @param [in] location of uniform
- * @param [in] value0 as float
- * @param [in] value1 as float
- */
- void SetUniform2f( GLint location, GLfloat value0, GLfloat value1 );
-
- /**
- * Sets the uniform value
- * @param [in] location of uniform
- * @param [in] value0 as float
- * @param [in] value1 as float
- * @param [in] value2 as float
- */
- void SetUniform3f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2 );
-
- /**
- * Sets the uniform value
- * @param [in] location of uniform
- * @param [in] value0 as float
- * @param [in] value1 as float
- * @param [in] value2 as float
- * @param [in] value3 as float
- */
- void SetUniform4f( GLint location, GLfloat value0, GLfloat value1, GLfloat value2, GLfloat value3 );
-
- /**
- * Sets the uniform value as matrix. NOTE! we never want GPU to transpose
- * so make sure your matrix is in correct order for GL.
- * @param [in] location Location of uniform
- * @param [in] count Count of matrices
- * @param [in] value values as float pointers
- */
- void SetUniformMatrix4fv( GLint location, GLsizei count, const GLfloat* value );
-
- /**
- * Sets the uniform value as matrix. NOTE! we never want GPU to transpose
- * so make sure your matrix is in correct order for GL.
- * @param [in] location Location of uniform
- * @param [in] count Count of matrices
- * @param [in] value values as float pointers
- */
- void SetUniformMatrix3fv( GLint location, GLsizei count, const GLfloat* value );
-
- /**
- * Needs to be called when GL context is (re)created
- */
- void GlContextCreated();
-
- /**
- * Needs to be called when GL context is destroyed
- */
- void GlContextDestroyed();
-
- /**
- * @return true if this program modifies geometry
- */
- bool ModifiesGeometry();
+ static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController);
/**
* Set the projection matrix that has currently been sent
* @param matrix to set
*/
- void SetProjectionMatrix( const Matrix* matrix )
+ void SetProjectionMatrix(const Matrix* matrix)
{
mProjectionMatrix = matrix;
}
* Set the projection matrix that has currently been sent
* @param matrix to set
*/
- void SetViewMatrix( const Matrix* matrix )
+ void SetViewMatrix(const Matrix* matrix)
{
mViewMatrix = matrix;
}
return mViewMatrix;
}
-private: // Implementation
+ [[nodiscard]] Graphics::Program& GetGraphicsProgram() const
+ {
+ return *mGfxProgram;
+ }
+
+ [[nodiscard]] Graphics::Program* GetGraphicsProgramPtr() const
+ {
+ return mGfxProgram.get();
+ }
+
+ void SetGraphicsProgram(Graphics::UniquePtr<Graphics::Program>&& program);
/**
+ * Retrieves uniform data.
+ * The lookup tries to minimise string comparisons. Ideally, when the hashedName is known
+ * and there are no hash collisions in the reflection it's the most optimal case.
+ *
+ * @param name Name of uniform
+ * @param hashedName Hash value from name or 0 if unknown
+ * @param hashedNameNoArray Hash value from name without array index & trailing string, or 0 if unknown
+ * @param out Reference to output structure
+ *
+ * @return False when uniform is not found or due to hash collision the result is ambiguous
+ */
+ bool GetUniform(const std::string_view& name, Hash hashedName, Hash hashedNameNoArray, Graphics::UniformInfo& out) const;
+
+ /**
+ * Retrieves default uniform
+ * @param[in] defaultUniformIndex index of the uniform
+ * @return Valid pointer to the UniformInfo object or nullptr
+ */
+ [[nodiscard]] const Graphics::UniformInfo* GetDefaultUniform(DefaultUniformIndex defaultUniformIndex) const;
+
+private: // Implementation
+ /**
* Constructor, private so no direct instantiation
* @param[in] cache where the programs are stored
* @param[in] shaderData A smart pointer to a data structure containing the program source and binary
- * @param[in] modifiesGeometry True if the vertex shader changes geometry
+ * @param[in] gfxController Reference to Graphics Controller object
*/
- Program( ProgramCache& cache, Integration::ShaderDataPtr shaderData, bool modifiesGeometry );
+ Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController);
public:
+ Program() = delete; ///< default constructor, not defined
+ Program(const Program&) = delete; ///< copy constructor, not defined
+ Program& operator=(const Program&) = delete; ///< assignment operator, not defined
/**
* Destructor, non virtual as no virtual methods or inheritance
*/
~Program();
-private:
-
- // default constructor, not defined
- Program();
- // assignment operator, not defined
- Program& operator=( const Program& );
-
- /**
- * Load the shader, from a precompiled binary if available, else from source code
- */
- void Load();
-
- /**
- * Unload the shader
- */
- void Unload();
-
+public:
/**
- * Compile the shader
- * @param shaderType vertex or fragment shader
- * @param shaderId of the shader, returned
- * @param src of the shader
- * @return true if the compilation succeeded
+ * Struct ReflectionUniformInfo
+ * Contains details of a single uniform buffer field and/or sampler.
*/
- bool CompileShader(GLenum shaderType, GLuint& shaderId, const char* src);
+ struct ReflectionUniformInfo
+ {
+ size_t hashValue{0};
+ bool hasCollision{false};
+ Graphics::UniformInfo uniformInfo{};
+ };
/**
- * Links the shaders together to create program
+ * Build optimized shader reflection of uniforms
+ * @param graphicsReflection The graphics reflection
*/
- void Link();
+ void BuildReflection(const Graphics::Reflection& graphicsReflection);
/**
- * Frees the shader programs
+ * Struct UniformBlockMemoryRequirements
+ * Contains details of a uniform blocks memory requirements
*/
- void FreeShaders();
+ struct UniformBlockMemoryRequirements
+ {
+ uint32_t blockCount;
+ uint32_t totalSizeRequired;
+ };
/**
- * Resets caches
+ * Retrieves uniform blocks requirements
+ *
+ * @return Reference to the valid UniformBlockMemoryRequirements struct
*/
- void ResetAttribsUniformCache();
-
-private: // Data
+ [[nodiscard]] const UniformBlockMemoryRequirements& GetUniformBlocksMemoryRequirements() const
+ {
+ return mUniformBlockRequirements;
+ }
- ProgramCache& mCache; ///< The program cache
- Integration::GlAbstraction& mGlAbstraction; ///< The OpenGL Abstraction layer
- const Matrix* mProjectionMatrix; ///< currently set projection matrix
- const Matrix* mViewMatrix; ///< currently set view matrix
- bool mLinked; ///< whether the program is linked
- GLuint mVertexShaderId; ///< GL identifier for vertex shader
- GLuint mFragmentShaderId; ///< GL identifier for fragment shader
- GLuint mProgramId; ///< GL identifier for program
- Integration::ShaderDataPtr mProgramData; ///< Shader program source and binary (when compiled & linked or loaded)
+private: // Data
+ ProgramCache& mCache; ///< The program cache
+ const Matrix* mProjectionMatrix; ///< currently set projection matrix
+ const Matrix* mViewMatrix; ///< currently set view matrix
- // location caches
- GLint mAttribLocations[ ATTRIB_TYPE_LAST ]; ///< attribute location cache
- std::vector< std::pair< std::string, GLint > > mUniformLocations; ///< uniform location cache
+ Graphics::UniquePtr<Graphics::Program> mGfxProgram; ///< Gfx program
+ Graphics::Controller& mGfxController; /// < Gfx controller
+ Internal::ShaderDataPtr mProgramData; ///< Shader program source and binary (when compiled & linked or loaded)
// uniform value caching
- GLint mUniformCacheInt[ MAX_UNIFORM_CACHE_SIZE ]; ///< Value cache for uniforms of single int
- GLfloat mUniformCacheFloat[ MAX_UNIFORM_CACHE_SIZE ]; ///< Value cache for uniforms of single float
- GLfloat mUniformCacheFloat4[ MAX_UNIFORM_CACHE_SIZE ][4]; ///< Value cache for uniforms of four float
- bool mModifiesGeometry; ///< True if the program changes geometry
+ Vector3 mSizeUniformCache; ///< Cache value for size uniform
+
+ using UniformReflectionContainer = std::vector<ReflectionUniformInfo>;
+ UniformReflectionContainer mReflection{}; ///< Contains reflection build per program
+ UniformReflectionContainer mReflectionDefaultUniforms{}; ///< Contains default uniforms
+ UniformBlockMemoryRequirements mUniformBlockRequirements{}; ///< Memory requirements for uniform blocks
};
} // namespace Internal
} // namespace Dali
-#endif // __DALI_INTERNAL_PROGRAM_H__
+#endif // DALI_INTERNAL_PROGRAM_H