[dali_2.3.30] Merge branch 'devel/master'
[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) 2023 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 namespace Render
47 {
48 class UniformBufferManager;
49 }
50
51 /**
52  * A program contains a vertex & fragment shader.
53  * It interfaces to the implementation program and it's reflection.
54  */
55 class Program
56 {
57 public:
58   using Hash = std::size_t;
59
60   /**
61    * Indices of default uniforms
62    */
63   enum class DefaultUniformIndex
64   {
65     MODEL_MATRIX = 0,
66     MVP_MATRIX,
67     VIEW_MATRIX,
68     MODEL_VIEW_MATRIX,
69     NORMAL_MATRIX,
70     PROJECTION_MATRIX,
71     SCALE,
72     SIZE,
73     COLOR,
74     ACTOR_COLOR,
75
76     COUNT
77   };
78
79   /**
80    * Creates a new program, or returns a copy of an existing program in the program cache
81    * @param[in] cache where the programs are stored
82    * @param[in] shaderData  A pointer to a data structure containing the program source
83    *                        and optionally precompiled binary. If the binary is empty the program bytecode
84    *                        is copied into it after compilation and linking)
85    * @param[in]  gfxController Reference to valid graphics Controller object
86    * @return pointer to the program
87    */
88   static Program* New(ProgramCache& cache, const Internal::ShaderDataPtr& shaderData, Graphics::Controller& gfxController);
89
90   Internal::ShaderDataPtr GetShaderData()
91   {
92     return mProgramData;
93   }
94
95   [[nodiscard]] Graphics::Program& GetGraphicsProgram() const
96   {
97     return *mGfxProgram;
98   }
99
100   [[nodiscard]] Graphics::Program* GetGraphicsProgramPtr() const
101   {
102     return mGfxProgram.get();
103   }
104
105   /**
106    * Setup the actual program, and ensure that it's reflection is generated.
107    */
108   void SetGraphicsProgram(Graphics::UniquePtr<Graphics::Program>&& program, Render::UniformBufferManager& uniformBufferManager);
109
110   /**
111    * Retrieves uniform data.
112    * The lookup tries to minimise string comparisons. Ideally, when the hashedName is known
113    * and there are no hash collisions in the reflection it's the most optimal case.
114    *
115    * @param name Name of uniform
116    * @param hashedName Hash value from name or 0 if unknown
117    * @param hashedNameNoArray Hash value from name without array index & trailing string, or 0 if unknown
118    * @param out Reference to output structure
119    *
120    * @return False when uniform is not found or due to hash collision the result is ambiguous
121    */
122   bool GetUniform(const std::string_view& name, Hash hashedName, Hash hashedNameNoArray, Graphics::UniformInfo& out) const;
123
124   /**
125    * Retrieves default uniform
126    * @param[in] defaultUniformIndex index of the uniform
127    * @return Valid pointer to the UniformInfo object or nullptr
128    */
129   [[nodiscard]] const Graphics::UniformInfo* GetDefaultUniform(DefaultUniformIndex defaultUniformIndex) const;
130
131 private: // Implementation
132   /**
133    * Constructor, private so no direct instantiation
134    * @param[in] cache where the programs are stored
135    * @param[in] shaderData A smart pointer to a data structure containing the program source and binary
136    * @param[in] gfxController Reference to Graphics Controller object
137    */
138   Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController);
139
140 public:
141   Program()               = delete;            ///< default constructor, not defined
142   Program(const Program&) = delete;            ///< copy constructor, not defined
143   Program& operator=(const Program&) = delete; ///< assignment operator, not defined
144
145   /**
146    * Destructor, non virtual as no virtual methods or inheritance
147    */
148   ~Program();
149
150 public:
151   /**
152    * Struct ReflectionUniformInfo
153    * Contains details of a single uniform buffer field and/or sampler.
154    */
155   struct ReflectionUniformInfo
156   {
157     size_t                hashValue{0};
158     bool                  hasCollision{false};
159     Graphics::UniformInfo uniformInfo{};
160   };
161
162   /**
163    * Build optimized shader reflection of uniforms
164    * @param graphicsReflection The graphics reflection
165    */
166   void BuildReflection(const Graphics::Reflection& graphicsReflection, Render::UniformBufferManager& uniformBufferManager);
167
168   /**
169    * Struct UniformBlockMemoryRequirements
170    * Contains details of a uniform blocks memory requirements
171    */
172   struct UniformBlockMemoryRequirements
173   {
174     uint32_t blockCount{0u};
175     uint32_t totalSizeRequired{0u};
176     uint32_t totalCpuSizeRequired{0u}; ///< requirements for CPU memory
177     uint32_t totalGpuSizeRequired{0u}; ///< requirements of hardware buffer
178
179     // Per block
180     std::vector<uint32_t> blockSize{};
181     std::vector<uint32_t> blockSizeAligned{};
182   };
183   /**
184    * Retrieves uniform blocks requirements
185    *
186    * @return Reference to the valid UniformBlockMemoryRequirements struct
187    */
188   [[nodiscard]] const UniformBlockMemoryRequirements& GetUniformBlocksMemoryRequirements() const
189   {
190     return mUniformBlockMemoryRequirements;
191   }
192
193 private:                                                 // Data
194   ProgramCache&                          mCache;         ///< The program cache
195   Graphics::UniquePtr<Graphics::Program> mGfxProgram;    ///< Gfx program
196   Graphics::Controller&                  mGfxController; /// < Gfx controller
197   Internal::ShaderDataPtr                mProgramData;   ///< Shader program source and binary (when compiled & linked or loaded)
198
199   // uniform value caching
200   Vector3 mSizeUniformCache; ///< Cache value for size uniform
201
202   using UniformReflectionContainer = std::vector<ReflectionUniformInfo>;
203
204   UniformReflectionContainer mReflection{};                ///< Contains reflection build per program
205   UniformReflectionContainer mReflectionDefaultUniforms{}; ///< Contains default uniforms
206
207   UniformBlockMemoryRequirements mUniformBlockMemoryRequirements; ///< Memory requirements per each block, block 0 = standalone/emulated
208 };
209
210 } // namespace Internal
211
212 } // namespace Dali
213
214 #endif // DALI_INTERNAL_PROGRAM_H