/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// INTERNAL INCLUDES
#include <dali/internal/common/buffer-index.h>
-#include <dali/internal/render/gl-resources/context.h>
-#include <dali/internal/render/gl-resources/gpu-buffer.h>
#include <dali/internal/render/renderers/render-vertex-buffer.h>
#include <dali/internal/render/shaders/program.h>
{
namespace Render
{
+namespace
+{
+inline constexpr size_t GetSizeOfIndexFromIndexType(Dali::Graphics::Format graphicsFormat)
+{
+ switch(graphicsFormat)
+ {
+ case Dali::Graphics::Format::R16_UINT:
+ {
+ return sizeof(uint16_t);
+ }
+ case Dali::Graphics::Format::R32_UINT:
+ {
+ return sizeof(uint32_t);
+ }
+ default:
+ {
+ // TODO : Not implmeneted.
+ return sizeof(uint16_t);
+ }
+ }
+}
+} // unnamed namespace
Geometry::Geometry()
: mIndices(),
mIndexBuffer(nullptr),
+ mIndexType(Dali::Graphics::Format::R16_UINT),
mGeometryType(Dali::Geometry::TRIANGLES),
mIndicesChanged(false),
mHasBeenUpdated(false),
Geometry::~Geometry() = default;
-void Geometry::GlContextCreated(Context& context)
+void Geometry::AddVertexBuffer(Render::VertexBuffer* vertexBuffer)
{
+ mVertexBuffers.PushBack(vertexBuffer);
+ mAttributesChanged = true;
}
-void Geometry::GlContextDestroyed()
+const Vector<Render::VertexBuffer*>& Geometry::GetVertexBuffers() const
{
+ return mVertexBuffers;
}
-void Geometry::AddVertexBuffer(Render::VertexBuffer* vertexBuffer)
+void Geometry::SetIndexBuffer(Uint16ContainerType& indices)
{
- mVertexBuffers.PushBack(vertexBuffer);
- mAttributesChanged = true;
+ mIndices.Swap(indices);
+ mIndicesChanged = true;
+ mIndexType = Graphics::Format::R16_UINT;
}
-void Geometry::SetIndexBuffer(Dali::Vector<uint16_t>& indices)
+void Geometry::SetIndexBuffer(Uint32ContainerType& indices)
{
- mIndices.Swap(indices);
+ // mIndices type is not matched with indices. Copy memory hardly.
+ mIndices.ResizeUninitialized(indices.Count() * 2);
+ memcpy(mIndices.Begin(), indices.Begin(), indices.Count() * sizeof(uint32_t));
mIndicesChanged = true;
+ mIndexType = Graphics::Format::R32_UINT;
}
void Geometry::RemoveVertexBuffer(const Render::VertexBuffer* vertexBuffer)
{
const auto&& end = mVertexBuffers.End();
+ // @todo if this buffer is the only instance buffer, reduce instance count to 1.
for(auto&& iter = mVertexBuffers.Begin(); iter != end; ++iter)
{
if(*iter == vertexBuffer)
}
}
-void Geometry::GetAttributeLocationFromProgram(Vector<GLint>& attributeLocation, Program& program, BufferIndex bufferIndex) const
-{
- attributeLocation.Clear();
-
- for(auto&& vertexBuffer : mVertexBuffers)
- {
- const uint32_t attributeCount = vertexBuffer->GetAttributeCount();
- for(uint32_t j = 0; j < attributeCount; ++j)
- {
- auto attributeName = vertexBuffer->GetAttributeName(j);
- uint32_t index = program.RegisterCustomAttribute(attributeName);
- GLint location = program.GetCustomAttributeLocation(index);
-
- if(-1 == location)
- {
- DALI_LOG_WARNING("Attribute not found in the shader: %s\n", attributeName.GetCString());
- }
-
- attributeLocation.PushBack(location);
- }
- }
-}
-
void Geometry::OnRenderFinished()
{
mHasBeenUpdated = false;
mAttributesChanged = false;
}
-void Geometry::Upload(Context& context)
+void Geometry::Upload(Graphics::Controller& graphicsController)
{
if(!mHasBeenUpdated)
{
{
if(mIndexBuffer == nullptr)
{
- mIndexBuffer = new GpuBuffer(context);
+ // Currently we are unable to reuse index buffer so the write policy is to preserve current content
+ mIndexBuffer = new GpuBuffer(graphicsController, 0 | Graphics::BufferUsage::INDEX_BUFFER, GpuBuffer::WritePolicy::RETAIN);
}
uint32_t bufferSize = static_cast<uint32_t>(sizeof(uint16_t) * mIndices.Size());
- mIndexBuffer->UpdateDataBuffer(context, bufferSize, &mIndices[0], GpuBuffer::STATIC_DRAW, GpuBuffer::ELEMENT_ARRAY_BUFFER);
+ mIndexBuffer->UpdateDataBuffer(graphicsController, bufferSize, &mIndices[0]);
}
mIndicesChanged = false;
for(auto&& buffer : mVertexBuffers)
{
- if(!buffer->Update(context))
+ if(!buffer->Update(graphicsController))
{
//Vertex buffer is not ready ( Size, data or format has not been specified yet )
return;
}
}
-void Geometry::Draw(
- Context& context,
- BufferIndex bufferIndex,
- Vector<GLint>& attributeLocation,
- uint32_t elementBufferOffset,
- uint32_t elementBufferCount)
+bool Geometry::BindVertexAttributes(Graphics::CommandBuffer& commandBuffer)
{
//Bind buffers to attribute locations
- uint32_t base = 0u;
- const uint32_t vertexBufferCount = static_cast<uint32_t>(mVertexBuffers.Count());
+ const auto vertexBufferCount = static_cast<uint32_t>(mVertexBuffers.Count());
+
+ std::vector<const Graphics::Buffer*> buffers;
+ std::vector<uint32_t> offsets;
+
for(uint32_t i = 0; i < vertexBufferCount; ++i)
{
- mVertexBuffers[i]->BindBuffer(context, GpuBuffer::ARRAY_BUFFER);
- base += mVertexBuffers[i]->EnableVertexAttributes(context, attributeLocation, base);
+ if(mVertexBuffers[i]->GetDivisor() > 0)
+ {
+ mInstanceCount = mVertexBuffers[i]->GetElementCount();
+ }
+
+ const GpuBuffer* gpuBuffer = mVertexBuffers[i]->GetGpuBuffer();
+ if(gpuBuffer)
+ {
+ const Graphics::Buffer* buffer = gpuBuffer->GetGraphicsObject();
+
+ if(buffer)
+ {
+ buffers.push_back(buffer);
+ offsets.push_back(0u);
+ }
+ }
+ //@todo Figure out why this is being drawn without geometry having been uploaded
}
+ if(buffers.empty())
+ {
+ return false;
+ }
+
+ commandBuffer.BindVertexBuffers(0, buffers, offsets);
+
+ return true;
+}
+bool Geometry::Draw(
+ Graphics::Controller& graphicsController,
+ Graphics::CommandBuffer& commandBuffer,
+ uint32_t elementBufferOffset,
+ uint32_t elementBufferCount)
+{
uint32_t numIndices(0u);
intptr_t firstIndexOffset(0u);
if(mIndexBuffer)
{
- numIndices = static_cast<uint32_t>(mIndices.Size());
+ std::size_t sizeOfIndex = GetSizeOfIndexFromIndexType(mIndexType);
+
+ numIndices = static_cast<uint32_t>(mIndices.Size() * sizeof(uint16_t) / sizeOfIndex);
if(elementBufferOffset != 0u)
{
elementBufferOffset = (elementBufferOffset >= numIndices) ? numIndices - 1 : elementBufferOffset;
- firstIndexOffset = elementBufferOffset * sizeof(GLushort);
+ firstIndexOffset = intptr_t(elementBufferOffset * sizeOfIndex);
numIndices -= elementBufferOffset;
}
}
}
- GLenum geometryGLType(GL_NONE);
+ //Draw call
+ if(mIndexBuffer && mGeometryType != Dali::Geometry::POINTS)
+ {
+ //Indexed draw call
+ const Graphics::Buffer* ibo = mIndexBuffer->GetGraphicsObject();
+ if(ibo)
+ {
+ commandBuffer.BindIndexBuffer(*ibo, 0, mIndexType);
+ }
+
+ commandBuffer.DrawIndexed(numIndices, mInstanceCount, firstIndexOffset, 0, 0);
+ }
+ else
+ {
+ // Un-indexed draw call
+ uint32_t numVertices(0u);
+
+ if(mVertexBuffers.Count() > 0)
+ {
+ // truncated, no value loss happening in practice
+ numVertices = static_cast<uint32_t>(mVertexBuffers[0]->GetElementCount());
+ }
+
+ commandBuffer.Draw(numVertices, mInstanceCount, 0, 0);
+ }
+ return true;
+}
+
+Graphics::PrimitiveTopology Geometry::GetTopology() const
+{
+ Graphics::PrimitiveTopology topology = Graphics::PrimitiveTopology::TRIANGLE_LIST;
+
switch(mGeometryType)
{
case Dali::Geometry::TRIANGLES:
{
- geometryGLType = GL_TRIANGLES;
+ topology = Graphics::PrimitiveTopology::TRIANGLE_LIST;
break;
}
case Dali::Geometry::LINES:
{
- geometryGLType = GL_LINES;
+ topology = Graphics::PrimitiveTopology::LINE_LIST;
break;
}
case Dali::Geometry::POINTS:
{
- geometryGLType = GL_POINTS;
+ topology = Graphics::PrimitiveTopology::POINT_LIST;
break;
}
case Dali::Geometry::TRIANGLE_STRIP:
{
- geometryGLType = GL_TRIANGLE_STRIP;
+ topology = Graphics::PrimitiveTopology::TRIANGLE_STRIP;
break;
}
case Dali::Geometry::TRIANGLE_FAN:
{
- geometryGLType = GL_TRIANGLE_FAN;
+ topology = Graphics::PrimitiveTopology::TRIANGLE_FAN;
break;
}
case Dali::Geometry::LINE_LOOP:
{
- geometryGLType = GL_LINE_LOOP;
+ topology = Graphics::PrimitiveTopology::LINE_LOOP;
break;
}
case Dali::Geometry::LINE_STRIP:
{
- geometryGLType = GL_LINE_STRIP;
+ topology = Graphics::PrimitiveTopology::LINE_STRIP;
break;
}
}
-
- //Draw call
- if(mIndexBuffer && geometryGLType != GL_POINTS)
- {
- //Indexed draw call
- mIndexBuffer->Bind(context, GpuBuffer::ELEMENT_ARRAY_BUFFER);
- // numIndices truncated, no value loss happening in practice
- context.DrawElements(geometryGLType, static_cast<GLsizei>(numIndices), GL_UNSIGNED_SHORT, reinterpret_cast<void*>(firstIndexOffset));
- }
- else
- {
- //Unindex draw call
- GLsizei numVertices(0u);
- if(vertexBufferCount > 0)
- {
- // truncated, no value loss happening in practice
- numVertices = static_cast<GLsizei>(mVertexBuffers[0]->GetElementCount());
- }
-
- context.DrawArrays(geometryGLType, 0, numVertices);
- }
-
- //Disable attributes
- for(auto&& attribute : attributeLocation)
- {
- if(attribute != -1)
- {
- context.DisableVertexAttributeArray(static_cast<GLuint>(attribute));
- }
- }
+ return topology;
}
} // namespace Render