Lock uniform buffer only 1 times per each render + minor fixup of uniforms
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / uniform-buffer.h
1 #ifndef DALI_INTERNAL_UNIFORM_BUFFER_H
2 #define DALI_INTERNAL_UNIFORM_BUFFER_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 // INTERNAL INCLUDES
22 #include <dali/graphics-api/graphics-controller.h>
23
24 // EXTERNAL INCLUDES
25 #include <memory>
26
27 namespace Dali::Internal::Render
28 {
29 /**
30  * Class UniformBuffer
31  *
32  * The class wraps one or more Graphics::Buffer objects and creates
33  * a continuous memory to store uniforms. The UniformBuffer may
34  * reallocate and merge individual Graphics::Buffer objects into one.
35  *
36  * From the client side, the UBO memory is continuous and individual
37  * Graphics::Buffer objects are not visible.
38  */
39 class UniformBuffer
40 {
41   friend class UniformBufferManager;
42   friend class UniformBufferView;
43   friend class UniformBufferViewPool;
44
45 private:
46   /**
47    * Constructor of UniformBuffer
48    *
49    * @param[in] mController Pointer of the graphics controller
50    * @param[in] sizeInBytes initial size of allocated buffer
51    * @param[in] alignment memory alignment in bytes
52    * @param[in] usageFlags type of usage ( Graphics::BufferUsage )
53    * @param[in] propertiesFlags buffer properties (Gracphis::BufferPropertiesFlags)
54    */
55   UniformBuffer(Dali::Graphics::Controller*     mController,
56                 uint32_t                        sizeInBytes,
57                 uint32_t                        alignment,
58                 Graphics::BufferUsageFlags      usageFlags,
59                 Graphics::BufferPropertiesFlags propertiesFlags);
60
61 public:
62   /**
63    * Destructor of UniformBuffer
64    */
65   ~UniformBuffer();
66
67   /**
68    * @brief Writes data into the buffer
69    * @note We prefer to call ReadyToLockUniformBuffer before call Write API.
70    * And also, prefer to call UnlockUniformBuffer if current frame's all Write API action done.
71    *
72    * @param[in] data pointer to the source data
73    * @param[in] size size of source data
74    * @param[in] offset destination offset
75    */
76   void Write(const void* data, uint32_t size, uint32_t offset);
77
78   /**
79    * @brief Flushes whole buffer range
80    *
81    * @param[in] bufferIndex Index of Graphics::Buffer
82    */
83   void Flush(uint32_t bufferIndex = 0);
84
85   /**
86    * @brief Returns allocated ( requested ) size
87    * @return size of buffer
88    */
89   [[nodiscard]] uint32_t GetSize() const
90   {
91     return mSize;
92   }
93
94   /**
95    * @brief Return Graphics::Buffer object at specified array index
96    *
97    * @param[in] bufferIndex index of Graphics buffer
98    *
99    * @return pointer to the buffer object
100    */
101   [[nodiscard]] Dali::Graphics::Buffer* GetBuffer(uint32_t bufferIndex) const
102   {
103     return mBuffers[bufferIndex].buffer.get();
104   }
105
106   /**
107    * @brief Maps individual Graphics buffer memory
108    *
109    * @param[in] bufferIndex index of Graphics buffer
110    */
111   void Map(uint32_t bufferIndex = 0);
112
113   /**
114    * Unmaps individual Graphics buffer memory
115    *
116    * @param[in] bufferIndex index of Graphics buffer
117    */
118   void Unmap(uint32_t bufferIndex = 0);
119
120   /**
121    * @brief Resizes the buffer
122    *
123    * The resize strategy depends on 'invalidate' parameter.
124    *
125    * If 'invalidate' is true, all the content if the buffer
126    * is discarded, the individual Graphics::Buffers are deleted
127    * and a single Graphics::Buffer is allocated.
128    *
129    * If 'invalidate' is false, additional Graphics::Buffer
130    * is created and all recorded content is kept unchanged.
131    *
132    * @param[in] newSize new size of UniformBuffer
133    * @param[in] invalidate specifies whether the content should be discarded
134    *
135    */
136   void Resize(uint32_t newSize, bool invalidate);
137
138   /**
139    * @copydoc Dali::Internal::Render::UniformBufferViewPool::ReadyToLockUniformBuffer
140    */
141   void ReadyToLockUniformBuffer();
142
143   /**
144    * @copydoc Dali::Internal::Render::UniformBufferViewPool::UnlockUniformBuffer
145    */
146   void UnlockUniformBuffer();
147
148 private:
149   /**
150    * @brief GfxBuffer wraps single GPU buffer and encapsulates individual
151    * buffer mapping and create info details.
152    *
153    * The array of GfxBuffers makes a single UniformBuffer.
154    */
155   struct GfxBuffer
156   {
157     GfxBuffer()            = default;
158     ~GfxBuffer()           = default;
159     GfxBuffer(GfxBuffer&&) = default;
160     GfxBuffer(Graphics::UniquePtr<Graphics::Buffer>&& b, const Graphics::BufferCreateInfo& i)
161     : buffer(std::move(b)),
162       createInfo(i)
163     {
164     }
165
166     Graphics::UniquePtr<Graphics::Buffer> buffer{};          ///< Graphics buffer
167     Graphics::UniquePtr<Graphics::Memory> memory{};          ///< Mapped memory associated with buffer
168     Graphics::BufferCreateInfo            createInfo{};      ///< create info describing the buffer
169     void*                                 mappedPtr{};       ///< Mapped pointer (if mapped)
170     bool                                  needsUpdate{true}; ///< Indicates whether the buffer needs flushing the queue
171   };
172
173   /**
174    * @brief Returns GfxBuffer object by offset
175    *
176    * The memory of UniformBuffer is considered to be continuous, however,
177    * it may contain multiple graphics buffers.
178    *
179    */
180   const GfxBuffer* GetBufferByOffset(uint32_t offset, uint32_t* newOffset, uint32_t* bufferIndex) const;
181
182   std::vector<GfxBuffer> mBuffers; ///< List of GfxBuffer objects
183
184   Dali::Graphics::Controller* mController; ///< Pointer to the controller
185
186   uint32_t mSize;         ///< Current size of buffer
187   uint32_t mAlignment{0}; ///< Buffer alignment
188
189   Graphics::BufferUsageFlags      mUsageFlags;
190   Graphics::BufferPropertiesFlags mPropertiesFlags;
191
192   uint32_t mLockedBufferIndex;   ///< Current locked buffer region index.
193   uint8_t* mLockedPtr;           ///< Current locked buffer pointer.
194   bool     mReadyToBeLocked : 1; ///< True if current uniform buffer is ready to be locked.
195 };
196
197 } // namespace Dali::Internal::Render
198
199 #endif //DALI_INTERNAL_UNIFORM_BUFFER_H