[dali_2.3.45] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-vertex-buffer.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/render/renderers/render-vertex-buffer.h>
20
21 // INTERNAL HEADERS
22 #include <dali/internal/event/rendering/vertex-buffer-impl.h> // Dali::Internal::VertexBuffer
23
24 namespace Dali
25 {
26 namespace Internal
27 {
28 namespace Render
29 {
30 VertexBuffer::VertexBuffer()
31 : mFormat(nullptr),
32   mData(nullptr),
33   mGpuBuffer(nullptr),
34   mSize(0),
35   mElementCount(0),
36   mDataChanged(true)
37 {
38 }
39
40 VertexBuffer::~VertexBuffer() = default;
41
42 void VertexBuffer::SetFormat(VertexBuffer::Format* format)
43 {
44   mFormat      = format;
45   mDataChanged = true;
46 }
47
48 void VertexBuffer::SetData(Dali::Vector<uint8_t>* data, uint32_t size)
49 {
50   mData        = data;
51   mSize        = size;
52   mDataChanged = true;
53 }
54
55 void VertexBuffer::SetVertexBufferUpdateCallback(Dali::VertexBufferUpdateCallback* callback)
56 {
57   mVertexBufferStateLock.ChangeState(VertexBufferSyncState::UNLOCKED, VertexBufferSyncState::LOCKED_FOR_EVENT);
58   mVertexBufferUpdateCallback.reset(callback);
59   mVertexBufferStateLock.ChangeState(VertexBufferSyncState::LOCKED_FOR_EVENT, VertexBufferSyncState::UNLOCKED);
60 }
61
62 bool VertexBuffer::Update(Graphics::Controller& graphicsController)
63 {
64   if(!mFormat || !mSize)
65   {
66     return false;
67   }
68
69   if(!mVertexBufferUpdateCallback && !mData)
70   {
71     return false;
72   }
73
74   if(!mGpuBuffer || mDataChanged)
75   {
76     if(!mGpuBuffer)
77     {
78       mGpuBuffer = new GpuBuffer(graphicsController, 0 | Graphics::BufferUsage::VERTEX_BUFFER, GpuBuffer::WritePolicy::DISCARD);
79     }
80
81     // Update the GpuBuffer
82     if(mGpuBuffer && mData)
83     {
84       DALI_ASSERT_DEBUG(mSize && "No data in the property buffer!");
85       mGpuBuffer->UpdateDataBuffer(graphicsController, GetDataSize(), &((*mData)[0]));
86     }
87
88     mElementCount = mSize;
89
90     mDataChanged = false;
91   }
92
93   // To execute the callback the buffer must be already initialized.
94   mVertexBufferStateLock.ChangeState(VertexBufferSyncState::UNLOCKED, VertexBufferSyncState::LOCKED_FOR_UPDATE);
95   if(mVertexBufferUpdateCallback && mGpuBuffer)
96   {
97     // If running callback, we may end up with less elements in the buffer
98     // of the same capacity
99     uint32_t updatedSize = mSize * mFormat->size;
100     mGpuBuffer->UpdateDataBufferWithCallback(graphicsController, mVertexBufferUpdateCallback.get(), updatedSize);
101     mElementCount = updatedSize / mFormat->size;
102   }
103   mVertexBufferStateLock.ChangeState(VertexBufferSyncState::LOCKED_FOR_UPDATE, VertexBufferSyncState::UNLOCKED);
104   return true;
105 }
106
107 void VertexBuffer::SetDivisor(uint32_t divisor)
108 {
109   mDivisor = divisor;
110 }
111
112 uint32_t VertexBuffer::GetDivisor()
113 {
114   return mDivisor;
115 }
116
117 } // namespace Render
118 } // namespace Internal
119 } // namespace Dali