1 #ifndef DALI_INTERNAL_RENDER_VERTEX_BUFFER_H
2 #define DALI_INTERNAL_RENDER_VERTEX_BUFFER_H
5 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <dali/public-api/common/vector-wrapper.h>
22 #include <dali/public-api/object/property.h>
24 #include <dali/graphics-api/graphics-types.h>
25 #include <dali/internal/common/const-string.h>
26 #include <dali/internal/common/owner-pointer.h>
27 #include <dali/internal/render/renderers/gpu-buffer.h>
31 class VertexBufferUpdateCallback;
37 * Helper class using atomic swaps for lockless synchronization
48 * Attempts to change state 'from' to 'to' and repeats
51 void ChangeState(T from, T to)
55 while(!value.compare_exchange_weak(expected, to, std::memory_order_release, std::memory_order_relaxed))
57 expected = from; // it's needed to revert the value of 'expected'
61 std::atomic<T> value{};
76 * Structure that holds the meta-data of the format of VertexBuffer.
80 std::vector<Component> components;
85 * @brief Default constructor
95 * @brief Set the format of the buffer
97 * This function takes ownership of the pointer
99 * @param[in] format The format for the VertexBuffer
101 void SetFormat(VertexBuffer::Format* format);
104 * @brief Set the data of the VertexBuffer
106 * This function takes ownership of the pointer
107 * @param[in] data The new data of the VertexBuffer
108 * @param[in] size The new size of the buffer
110 void SetData(Dali::Vector<uint8_t>* data, uint32_t size);
113 * @brief Sets vertex buffer update callback
115 * This function takes ownership over the callback object.
117 * The callback will run during rendering on the update/render thread.
118 * @param[in] callback Valid update callback
120 void SetVertexBufferUpdateCallback(Dali::VertexBufferUpdateCallback* callback);
123 * Perform the upload of the buffer only when required
124 * @param[in] graphicsController The controller
126 bool Update(Graphics::Controller& graphicsController);
129 * @brief Set the divisor of the buffer for instanced drawing
130 * @param[in] divisor The divisor (0 = not instanced, >=1 = instanced)
132 void SetDivisor(uint32_t divisor);
135 * Get the divisor for the vertex buffer
137 [[nodiscard]] uint32_t GetDivisor();
140 * Get the number of attributes present in the buffer
141 * @return The number of attributes stored in this buffer
143 [[nodiscard]] inline uint32_t GetAttributeCount() const
145 DALI_ASSERT_DEBUG(mFormat && "Format should be set ");
146 return static_cast<uint32_t>(mFormat->components.size());
150 * Retrieve the i-essim attribute name
151 * @param[in] index The index of the attribute
152 * @return The name of the attribute
154 [[nodiscard]] inline ConstString GetAttributeName(uint32_t index) const
156 DALI_ASSERT_DEBUG(mFormat && "Format should be set ");
157 return mFormat->components[index].name;
161 * Retrieve the size of the buffer in bytes
162 * @return The total size of the buffer
164 [[nodiscard]] inline uint32_t GetDataSize() const
166 DALI_ASSERT_DEBUG(mFormat && "Format should be set ");
167 return mFormat->size * mSize;
171 * Retrieve the size of one element of the buffer
172 * @return The size of one element
174 [[nodiscard]] inline uint32_t GetElementSize() const
176 DALI_ASSERT_DEBUG(mFormat && "Format should be set ");
177 return mFormat->size;
181 * Retrieve the number of elements in the buffer
182 * @return The total number of elements
184 [[nodiscard]] inline uint32_t GetElementCount() const
190 * Retrieves number of renderable elements when vertex update callback
191 * is used. If there is no callback set the total number of elements
194 [[nodiscard]] inline uint32_t GetRenderableElementCount() const
196 return mVertexBufferUpdateCallback ? mElementCount : mSize;
199 [[nodiscard]] inline const VertexBuffer::Format* GetFormat() const
201 return mFormat.Get();
204 [[nodiscard]] inline const GpuBuffer* GetGpuBuffer() const
206 return mGpuBuffer.Get();
210 OwnerPointer<VertexBuffer::Format> mFormat; ///< Format of the buffer
211 OwnerPointer<Dali::Vector<uint8_t> > mData; ///< Data
212 OwnerPointer<GpuBuffer> mGpuBuffer; ///< Pointer to the GpuBuffer associated with this RenderVertexBuffer
214 uint32_t mSize; ///< Number of Elements in the buffer
215 uint32_t mDivisor{0}; ///< The divisor (0:not instanced, >=1:instanced)
216 uint32_t mElementCount; ///< Number of valid elements in the buffer
217 std::unique_ptr<Dali::VertexBufferUpdateCallback> mVertexBufferUpdateCallback;
220 * Enum values for locking mechanism.
222 * Locking mechanism uses synchronized state machine. From 'UNLOCKED' state
223 * it's either LOCKED_FOR_EVENT or LOCKED_FOR_UPDATE states possible.
224 * Both states can be reverted only to UNLOCKED.
226 enum class VertexBufferSyncState : int
228 UNLOCKED, ///< Currently unlocked
229 LOCKED_FOR_EVENT, ///< Locked for Event thread to access
230 LOCKED_FOR_UPDATE, ///< Locked for Update thread to access
233 StateLock<VertexBufferSyncState> mVertexBufferStateLock{VertexBufferSyncState::UNLOCKED};
235 bool mDataChanged; ///< Flag to know if data has changed in a frame
238 } // namespace Render
240 } // namespace Internal
244 #endif // DALI_INTERNAL_RENDER_VERTEX_BUFFER_H