#define DALI_INTERNAL_PROGRAM_H
/*
- * Copyright (c) 2021 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.
#include <string>
// INTERNAL INCLUDES
-#include <dali/integration-api/gl-abstraction.h>
#include <dali/internal/common/const-string.h>
#include <dali/internal/common/shader-data.h>
#include <dali/public-api/common/vector-wrapper.h>
{
class Controller;
class Program;
-}
-class Matrix;
+class Reflection;
+} // namespace Graphics
-namespace Integration
-{
-class GlAbstraction;
-class ShaderData;
-} // namespace Integration
+class Matrix;
namespace Internal
{
/**
* A program contains a vertex & fragment shader.
- *
- * Program caches some of vertex attribute locations and uniform variable values to reduce unnecessary state changes.
+ * It interfaces to the implementation program and it's reflection.
*/
class Program
{
public:
- /**
- * 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 int32_t MAX_UNIFORM_CACHE_SIZE = 16;
-
- /**
- * Constant for uniform / attribute not found
- */
- static const int32_t NOT_FOUND = -1;
-
- /**
- * Vertex attributes
- */
- enum AttribType
- {
- ATTRIB_UNKNOWN = -1,
- ATTRIB_POSITION,
- ATTRIB_TEXCOORD,
- ATTRIB_TYPE_LAST
- };
+ using Hash = std::size_t;
/**
- * Common shader uniform names
+ * Indices of default uniforms
*/
- enum UniformType
+ enum class DefaultUniformIndex
{
- 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_SAMPLER,
- UNIFORM_SAMPLER_RECT,
- UNIFORM_EFFECT_SAMPLER,
-
- UNIFORM_SIZE,
- 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] gfxController Reference to valid graphics Controller object
- * param[in] gfxProgram Reference to vali graphics Program object
- * @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, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr<Graphics::Program>&& gfxProgram, 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 an attribute name in our local cache
- * @param [in] name attribute name
- * @return the index of the attribute name in local cache
- */
- uint32_t RegisterCustomAttribute(ConstString name);
-
- /**
- * Gets the location of a pre-registered attribute.
- * @param [in] attributeIndex of the attribute in local cache
- * @return the index of the attribute in the GL program
- */
- GLint GetCustomAttributeLocation(uint32_t attributeIndex);
-
- /**
- * Register a uniform name in our local cache
- * @param [in] name uniform name
- * @return the index of the uniform name in local cache
- */
- uint32_t RegisterUniform(ConstString 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(uint32_t uniformIndex);
-
- /**
- * Introspect the newly loaded shader to get the active sampler locations
- */
- void GetActiveSamplerUniforms();
-
- /**
- * Gets the uniform location for a sampler
- * @param [in] index The index of the active sampler
- * @param [out] location The location of the requested sampler
- * @return true if the active sampler was found
- */
- bool GetSamplerUniformLocation(uint32_t index, GLint& location);
-
- /**
- * Get the number of active samplers present in the shader
- * @return The number of active samplers
- */
- uint32_t GetActiveSamplerCount() const;
-
- /**
- * 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);
-
- /**
- * Special handling for size as we're using uniform geometry so size is passed on to most programs
- * but it rarely changes so we can cache it
- * @param [in] location of uniform
- * @param [in] value0 as float
- * @param [in] value1 as float
- * @param [in] value2 as float
- */
- void SetSizeUniform3f(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
- */
- 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
return mViewMatrix;
}
- GLuint GetProgramId()
+ [[nodiscard]] Graphics::Program& GetGraphicsProgram() const
{
- return mProgramId;
+ return *mGfxProgram;
}
- [[nodiscard]] Graphics::Program& GetGraphicsProgram() const
+ [[nodiscard]] Graphics::Program* GetGraphicsProgramPtr() const
{
- return *mGfxProgram;
+ 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] gfxProgram Graphics Program object
* @param[in] gfxController Reference to Graphics Controller object
- * @param[in] modifiesGeometry True if the vertex shader changes geometry
*/
- Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr<Graphics::Program>&& gfxProgram, 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:
- Program(); ///< default constructor, not defined
- Program(const Program&); ///< copy constructor, not defined
- Program& operator=(const Program&); ///< assignment operator, not defined
-
+public:
/**
- * Load the shader, from a precompiled binary if available, else from source code
+ * Struct ReflectionUniformInfo
+ * Contains details of a single uniform buffer field and/or sampler.
*/
- void Load();
+ struct ReflectionUniformInfo
+ {
+ size_t hashValue{0};
+ bool hasCollision{false};
+ Graphics::UniformInfo uniformInfo{};
+ };
/**
- * Unload the shader
+ * Build optimized shader reflection of uniforms
+ * @param graphicsReflection The graphics reflection
*/
- void Unload();
+ void BuildReflection(const Graphics::Reflection& graphicsReflection);
/**
- * 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 UniformBlockMemoryRequirements
+ * Contains details of a uniform blocks memory requirements
*/
- bool CompileShader(GLenum shaderType, GLuint& shaderId, const char* src);
+ struct UniformBlockMemoryRequirements
+ {
+ uint32_t blockCount;
+ uint32_t totalSizeRequired;
+ };
/**
- * Links the shaders together to create program
+ * Retrieves uniform blocks requirements
+ *
+ * @return Reference to the valid UniformBlockMemoryRequirements struct
*/
- void Link();
+ [[nodiscard]] const UniformBlockMemoryRequirements& GetUniformBlocksMemoryRequirements() const
+ {
+ return mUniformBlockRequirements;
+ }
- /**
- * Frees the shader programs
- */
- void FreeShaders();
+private: // Data
+ ProgramCache& mCache; ///< The program cache
+ const Matrix* mProjectionMatrix; ///< currently set projection matrix
+ const Matrix* mViewMatrix; ///< currently set view matrix
- /**
- * Resets caches
- */
- void ResetAttribsUniformCache();
-
-private: // Data
- 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
- 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)
-
- // location caches
- using NameLocationPair = std::pair<ConstString, GLint>;
- using Locations = std::vector<NameLocationPair>;
-
- Locations mAttributeLocations; ///< attribute location cache
- Locations mUniformLocations; ///< uniform location cache
- std::vector<GLint> mSamplerUniformLocations; ///< sampler 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 mUniformCacheFloat2[MAX_UNIFORM_CACHE_SIZE][2]; ///< Value cache for uniforms of two floats
- GLfloat mUniformCacheFloat4[MAX_UNIFORM_CACHE_SIZE][4]; ///< Value cache for uniforms of four floats
- Vector3 mSizeUniformCache; ///< Cache value for size uniform
- 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