2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <dali/internal/render/renderers/render-geometry.h>
21 #include <dali/internal/common/buffer-index.h>
22 #include <dali/internal/render/gl-resources/context.h>
23 #include <dali/internal/render/gl-resources/gpu-buffer.h>
24 #include <dali/internal/render/renderers/render-vertex-buffer.h>
25 #include <dali/internal/render/shaders/program.h>
35 mIndexBuffer(nullptr),
36 mGeometryType(Dali::Geometry::TRIANGLES),
37 mIndicesChanged(false),
38 mHasBeenUpdated(false),
39 mAttributesChanged(true)
43 Geometry::~Geometry() = default;
45 void Geometry::GlContextCreated(Context& context)
49 void Geometry::GlContextDestroyed()
53 void Geometry::AddVertexBuffer(Render::VertexBuffer* vertexBuffer)
55 mVertexBuffers.PushBack(vertexBuffer);
56 mAttributesChanged = true;
59 const Vector<Render::VertexBuffer*>& Geometry::GetVertexBuffers() const
61 return mVertexBuffers;
64 void Geometry::SetIndexBuffer(Dali::Vector<uint16_t>& indices)
66 mIndices.Swap(indices);
67 mIndicesChanged = true;
70 void Geometry::RemoveVertexBuffer(const Render::VertexBuffer* vertexBuffer)
72 const auto&& end = mVertexBuffers.End();
73 for(auto&& iter = mVertexBuffers.Begin(); iter != end; ++iter)
75 if(*iter == vertexBuffer)
77 //This will delete the gpu buffer associated to the RenderVertexBuffer if there is one
78 mVertexBuffers.Remove(iter);
79 mAttributesChanged = true;
85 void Geometry::OnRenderFinished()
87 mHasBeenUpdated = false;
88 mAttributesChanged = false;
91 void Geometry::Upload(Graphics::Controller& graphicsController)
100 mIndexBuffer = nullptr;
104 if(mIndexBuffer == nullptr)
106 mIndexBuffer = new GpuBuffer(graphicsController, 0 | Graphics::BufferUsage::INDEX_BUFFER);
109 uint32_t bufferSize = static_cast<uint32_t>(sizeof(uint16_t) * mIndices.Size());
110 mIndexBuffer->UpdateDataBuffer(graphicsController, bufferSize, &mIndices[0]);
113 mIndicesChanged = false;
116 for(auto&& buffer : mVertexBuffers)
118 if(!buffer->Update(graphicsController))
120 //Vertex buffer is not ready ( Size, data or format has not been specified yet )
125 mHasBeenUpdated = true;
130 Graphics::Controller& graphicsController,
131 Graphics::CommandBuffer& commandBuffer,
132 uint32_t elementBufferOffset,
133 uint32_t elementBufferCount)
135 //Bind buffers to attribute locations
136 const uint32_t vertexBufferCount = static_cast<uint32_t>(mVertexBuffers.Count());
138 std::vector<const Graphics::Buffer*> buffers;
139 std::vector<uint32_t> offsets;
141 for(uint32_t i = 0; i < vertexBufferCount; ++i)
143 const GpuBuffer* gpuBuffer = mVertexBuffers[i]->GetGpuBuffer();
146 const Graphics::Buffer* buffer = gpuBuffer->GetGraphicsObject();
150 buffers.push_back(buffer);
151 offsets.push_back(0u);
154 //@todo Figure out why this is being drawn without geometry having been uploaded
156 if(buffers.size() == 0)
161 commandBuffer.BindVertexBuffers(0, buffers, offsets);
163 uint32_t numIndices(0u);
164 intptr_t firstIndexOffset(0u);
167 numIndices = static_cast<uint32_t>(mIndices.Size());
169 if(elementBufferOffset != 0u)
171 elementBufferOffset = (elementBufferOffset >= numIndices) ? numIndices - 1 : elementBufferOffset;
172 firstIndexOffset = elementBufferOffset * sizeof(GLushort);
173 numIndices -= elementBufferOffset;
176 if(elementBufferCount != 0u)
178 numIndices = std::min(elementBufferCount, numIndices);
183 if(mIndexBuffer && mGeometryType != Dali::Geometry::POINTS)
186 const Graphics::Buffer* ibo = mIndexBuffer->GetGraphicsObject();
189 commandBuffer.BindIndexBuffer(*ibo, 0, Graphics::Format::R16_UINT);
192 commandBuffer.DrawIndexed(numIndices, 1, firstIndexOffset, 0, 0);
197 GLsizei numVertices(0u);
198 if(vertexBufferCount > 0)
200 // truncated, no value loss happening in practice
201 numVertices = static_cast<GLsizei>(mVertexBuffers[0]->GetElementCount());
204 commandBuffer.Draw(numVertices, 1, 0, 0);
209 Graphics::PrimitiveTopology Geometry::GetTopology() const
211 Graphics::PrimitiveTopology topology = Graphics::PrimitiveTopology::TRIANGLE_LIST;
213 switch(mGeometryType)
215 case Dali::Geometry::TRIANGLES:
217 topology = Graphics::PrimitiveTopology::TRIANGLE_LIST;
220 case Dali::Geometry::LINES:
222 topology = Graphics::PrimitiveTopology::LINE_LIST;
225 case Dali::Geometry::POINTS:
227 topology = Graphics::PrimitiveTopology::POINT_LIST;
230 case Dali::Geometry::TRIANGLE_STRIP:
232 topology = Graphics::PrimitiveTopology::TRIANGLE_STRIP;
235 case Dali::Geometry::TRIANGLE_FAN:
237 topology = Graphics::PrimitiveTopology::TRIANGLE_FAN;
240 case Dali::Geometry::LINE_LOOP:
242 topology = Graphics::PrimitiveTopology::LINE_LOOP;
245 case Dali::Geometry::LINE_STRIP:
247 topology = Graphics::PrimitiveTopology::LINE_STRIP;
254 } // namespace Render
255 } // namespace Internal