Merge "Move shader program creation from update side to render side" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-vertex-buffer.cpp
1 /*
2  * Copyright (c) 2021 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 #include <dali/internal/event/rendering/vertex-buffer-impl.h> // Dali::Internal::VertexBuffer
19 #include <dali/internal/render/renderers/render-vertex-buffer.h>
20
21 namespace
22 {
23 using Dali::Property;
24 using Dali::Internal::PropertyImplementationType;
25
26 Dali::GLenum GetPropertyImplementationGlType(Property::Type propertyType)
27 {
28   Dali::GLenum type = GL_BYTE;
29
30   switch(propertyType)
31   {
32     case Property::NONE:
33     case Property::STRING:
34     case Property::ARRAY:
35     case Property::MAP:
36     case Property::EXTENTS:
37     case Property::RECTANGLE:
38     case Property::ROTATION:
39     {
40       // types not supported by gl
41       break;
42     }
43     case Property::BOOLEAN:
44     {
45       type = GL_BYTE;
46       break;
47     }
48     case Property::INTEGER:
49     {
50       type = GL_SHORT;
51       break;
52     }
53     case Property::FLOAT:
54     case Property::VECTOR2:
55     case Property::VECTOR3:
56     case Property::VECTOR4:
57     case Property::MATRIX3:
58     case Property::MATRIX:
59     {
60       type = GL_FLOAT;
61       break;
62     }
63   }
64
65   return type;
66 }
67
68 Dali::GLint GetPropertyImplementationGlSize(Property::Type propertyType)
69 {
70   Dali::GLint size = 1u;
71
72   switch(propertyType)
73   {
74     case Property::NONE:
75     case Property::STRING:
76     case Property::ARRAY:
77     case Property::MAP:
78     case Property::EXTENTS:
79     case Property::RECTANGLE:
80     case Property::ROTATION:
81     {
82       // types not supported by gl
83       break;
84     }
85     case Property::BOOLEAN:
86     {
87       size = 1u;
88       break;
89     }
90     case Property::INTEGER:
91     {
92       size = 2u;
93       break;
94     }
95     case Property::FLOAT:
96     case Property::VECTOR2:
97     case Property::VECTOR3:
98     case Property::VECTOR4:
99     case Property::MATRIX3:
100     case Property::MATRIX:
101     {
102       size = 4u;
103       break;
104     }
105   }
106
107   return size;
108 }
109 } //Unnamed namespace
110
111 namespace Dali
112 {
113 namespace Internal
114 {
115 namespace Render
116 {
117 VertexBuffer::VertexBuffer()
118 : mFormat(nullptr),
119   mData(nullptr),
120   mGpuBuffer(nullptr),
121   mSize(0),
122   mDataChanged(true)
123 {
124 }
125
126 VertexBuffer::~VertexBuffer() = default;
127
128 void VertexBuffer::SetFormat(VertexBuffer::Format* format)
129 {
130   mFormat      = format;
131   mDataChanged = true;
132 }
133
134 void VertexBuffer::SetData(Dali::Vector<uint8_t>* data, uint32_t size)
135 {
136   mData        = data;
137   mSize        = size;
138   mDataChanged = true;
139 }
140
141 bool VertexBuffer::Update(Context& context)
142 {
143   if(!mData || !mFormat || !mSize)
144   {
145     return false;
146   }
147
148   if(!mGpuBuffer || mDataChanged)
149   {
150     if(!mGpuBuffer)
151     {
152       mGpuBuffer = new GpuBuffer(context);
153     }
154
155     // Update the GpuBuffer
156     if(mGpuBuffer)
157     {
158       DALI_ASSERT_DEBUG(mSize && "No data in the property buffer!");
159       mGpuBuffer->UpdateDataBuffer(context, GetDataSize(), &((*mData)[0]), GpuBuffer::STATIC_DRAW, GpuBuffer::ARRAY_BUFFER);
160     }
161
162     mDataChanged = false;
163   }
164
165   return true;
166 }
167
168 void VertexBuffer::BindBuffer(Context& context, GpuBuffer::Target target)
169 {
170   if(mGpuBuffer)
171   {
172     mGpuBuffer->Bind(context, target);
173   }
174 }
175
176 uint32_t VertexBuffer::EnableVertexAttributes(Context& context, Vector<GLint>& vAttributeLocation, uint32_t locationBase)
177 {
178   const uint32_t attributeCount = static_cast<uint32_t>(mFormat->components.size());
179
180   GLsizei elementSize = mFormat->size;
181
182   for(uint32_t i = 0; i < attributeCount; ++i)
183   {
184     GLint attributeLocation = vAttributeLocation[i + locationBase];
185     if(attributeLocation != -1)
186     {
187       context.EnableVertexAttributeArray(attributeLocation);
188
189       const GLint          attributeSize   = mFormat->components[i].size;
190       uint32_t             attributeOffset = mFormat->components[i].offset;
191       const Property::Type attributeType   = mFormat->components[i].type;
192
193       context.VertexAttribPointer(attributeLocation,
194                                   attributeSize / GetPropertyImplementationGlSize(attributeType),
195                                   GetPropertyImplementationGlType(attributeType),
196                                   GL_FALSE, // Not normalized
197                                   elementSize,
198                                   reinterpret_cast<void*>(attributeOffset));
199     }
200   }
201
202   return attributeCount;
203 }
204
205 } // namespace Render
206 } // namespace Internal
207 } // namespace Dali