Lock uniform buffer only 1 times per each render + minor fixup of uniforms
[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) 2022 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 <cstdint> // int32_t, uint32_t
23 #include <string>
24
25 // INTERNAL INCLUDES
26 #include <dali/internal/common/const-string.h>
27 #include <dali/internal/common/shader-data.h>
28 #include <dali/public-api/common/vector-wrapper.h>
29 #include <dali/public-api/object/ref-object.h>
30
31 namespace Dali
32 {
33 namespace Graphics
34 {
35 class Controller;
36 class Program;
37 class Reflection;
38 } // namespace Graphics
39
40 class Matrix;
41
42 namespace Internal
43 {
44 class ProgramCache;
45
46 /**
47  * A program contains a vertex & fragment shader.
48  * It interfaces to the implementation program and it's reflection.
49  */
50 class Program
51 {
52 public:
53   using Hash = std::size_t;
54
55   /**
56    * Indices of default uniforms
57    */
58   enum class DefaultUniformIndex
59   {
60     MODEL_MATRIX = 0,
61     MVP_MATRIX,
62     VIEW_MATRIX,
63     MODEL_VIEW_MATRIX,
64     NORMAL_MATRIX,
65     PROJECTION_MATRIX,
66     SIZE,
67     COLOR,
68     ACTOR_COLOR,
69
70     COUNT
71   };
72
73   /**
74    * Creates a new program, or returns a copy of an existing program in the program cache
75    * @param[in] cache where the programs are stored
76    * @param[in] shaderData  A pointer to a data structure containing the program source
77    *                        and optionally precompiled binary. If the binary is empty the program bytecode
78    *                        is copied into it after compilation and linking)
79    * @param[in]  gfxController Reference to valid graphics Controller object
80    * @return pointer to the program
81    */
82   static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController);
83
84   /**
85    * Set the projection matrix that has currently been sent
86    * @param matrix to set
87    */
88   void SetProjectionMatrix(const Matrix* matrix)
89   {
90     mProjectionMatrix = matrix;
91   }
92
93   /**
94    * Get the projection matrix that has currently been sent
95    * @return the matrix that is set
96    */
97   const Matrix* GetProjectionMatrix()
98   {
99     return mProjectionMatrix;
100   }
101
102   /**
103    * Set the projection matrix that has currently been sent
104    * @param matrix to set
105    */
106   void SetViewMatrix(const Matrix* matrix)
107   {
108     mViewMatrix = matrix;
109   }
110
111   /**
112    * Get the projection matrix that has currently been sent
113    * @return the matrix that is set
114    */
115   const Matrix* GetViewMatrix()
116   {
117     return mViewMatrix;
118   }
119
120   [[nodiscard]] Graphics::Program& GetGraphicsProgram() const
121   {
122     return *mGfxProgram;
123   }
124
125   [[nodiscard]] Graphics::Program* GetGraphicsProgramPtr() const
126   {
127     return mGfxProgram.get();
128   }
129
130   void SetGraphicsProgram(Graphics::UniquePtr<Graphics::Program>&& program);
131
132   /**
133    * Retrieves uniform data.
134    * The lookup tries to minimise string comparisons. Ideally, when the hashedName is known
135    * and there are no hash collisions in the reflection it's the most optimal case.
136    *
137    * @param name Name of uniform
138    * @param hashedName Hash value from name or 0 if unknown
139    * @param hashedNameNoArray Hash value from name without array index & trailing string, or 0 if unknown
140    * @param out Reference to output structure
141    *
142    * @return False when uniform is not found or due to hash collision the result is ambiguous
143    */
144   bool GetUniform(const std::string_view& name, Hash hashedName, Hash hashedNameNoArray, Graphics::UniformInfo& out) const;
145
146   /**
147    * Retrieves default uniform
148    * @param[in] defaultUniformIndex index of the uniform
149    * @return Valid pointer to the UniformInfo object or nullptr
150    */
151   [[nodiscard]] const Graphics::UniformInfo* GetDefaultUniform(DefaultUniformIndex defaultUniformIndex) const;
152
153 private: // Implementation
154   /**
155    * Constructor, private so no direct instantiation
156    * @param[in] cache where the programs are stored
157    * @param[in] shaderData A smart pointer to a data structure containing the program source and binary
158    * @param[in] gfxController Reference to Graphics Controller object
159    */
160   Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController);
161
162 public:
163   Program()               = delete;            ///< default constructor, not defined
164   Program(const Program&) = delete;            ///< copy constructor, not defined
165   Program& operator=(const Program&) = delete; ///< assignment operator, not defined
166
167   /**
168    * Destructor, non virtual as no virtual methods or inheritance
169    */
170   ~Program();
171
172 public:
173   /**
174    * Struct ReflectionUniformInfo
175    * Contains details of a single uniform buffer field and/or sampler.
176    */
177   struct ReflectionUniformInfo
178   {
179     size_t                hashValue{0};
180     bool                  hasCollision{false};
181     Graphics::UniformInfo uniformInfo{};
182   };
183
184   /**
185    * Build optimized shader reflection of uniforms
186    * @param graphicsReflection The graphics reflection
187    */
188   void BuildReflection(const Graphics::Reflection& graphicsReflection);
189
190   /**
191    * Struct UniformBlockMemoryRequirements
192    * Contains details of a uniform blocks memory requirements
193    */
194   struct UniformBlockMemoryRequirements
195   {
196     uint32_t blockCount;
197     uint32_t totalSizeRequired;
198   };
199
200   /**
201    * Retrieves uniform blocks requirements
202    *
203    * @return Reference to the valid UniformBlockMemoryRequirements struct
204    */
205   [[nodiscard]] const UniformBlockMemoryRequirements& GetUniformBlocksMemoryRequirements() const
206   {
207     return mUniformBlockRequirements;
208   }
209
210 private:                           // Data
211   ProgramCache& mCache;            ///< The program cache
212   const Matrix* mProjectionMatrix; ///< currently set projection matrix
213   const Matrix* mViewMatrix;       ///< currently set view matrix
214
215   Graphics::UniquePtr<Graphics::Program> mGfxProgram;    ///< Gfx program
216   Graphics::Controller&                  mGfxController; /// < Gfx controller
217   Internal::ShaderDataPtr                mProgramData;   ///< Shader program source and binary (when compiled & linked or loaded)
218
219   // uniform value caching
220   Vector3 mSizeUniformCache; ///< Cache value for size uniform
221
222   using UniformReflectionContainer = std::vector<ReflectionUniformInfo>;
223
224   UniformReflectionContainer     mReflection{};                ///< Contains reflection build per program
225   UniformReflectionContainer     mReflectionDefaultUniforms{}; ///< Contains default uniforms
226   UniformBlockMemoryRequirements mUniformBlockRequirements{};  ///< Memory requirements for uniform blocks
227 };
228
229 } // namespace Internal
230
231 } // namespace Dali
232
233 #endif // DALI_INTERNAL_PROGRAM_H