/*
- * Copyright (c) 2018 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-property-buffer.h>
+#include <dali/internal/render/renderers/render-vertex-buffer.h>
#include <dali/internal/render/shaders/program.h>
namespace Dali
{
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(NULL),
- mGeometryType( Dali::Geometry::TRIANGLES ),
+ mIndexBuffer(nullptr),
+ mIndexType(Dali::Graphics::Format::R16_UINT),
+ mGeometryType(Dali::Geometry::TRIANGLES),
mIndicesChanged(false),
mHasBeenUpdated(false),
mAttributesChanged(true)
{
}
-Geometry::~Geometry()
-{
-}
+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::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
+void Geometry::SetIndexBuffer(Uint16ContainerType& indices)
{
- mVertexBuffers.PushBack( propertyBuffer );
- 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::RemovePropertyBuffer( const Render::PropertyBuffer* propertyBuffer )
+void Geometry::RemoveVertexBuffer(const Render::VertexBuffer* vertexBuffer)
{
const auto&& end = mVertexBuffers.End();
- for( auto&& iter = mVertexBuffers.Begin(); iter != end; ++iter )
+ for(auto&& iter = mVertexBuffers.Begin(); iter != end; ++iter)
{
- if( *iter == propertyBuffer )
+ if(*iter == vertexBuffer)
{
- //This will delete the gpu buffer associated to the RenderPropertyBuffer if there is one
- mVertexBuffers.Remove( iter );
+ //This will delete the gpu buffer associated to the RenderVertexBuffer if there is one
+ mVertexBuffers.Remove(iter);
mAttributesChanged = true;
break;
}
}
}
-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 )
- {
- const std::string& 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.c_str() );
- }
-
- attributeLocation.PushBack( location );
- }
- }
-}
-
void Geometry::OnRenderFinished()
{
- mHasBeenUpdated = false;
+ mHasBeenUpdated = false;
mAttributesChanged = false;
}
-void Geometry::UploadAndDraw(
- Context& context,
- BufferIndex bufferIndex,
- Vector<GLint>& attributeLocation,
- uint32_t elementBufferOffset,
- uint32_t elementBufferCount )
+void Geometry::Upload(Graphics::Controller& graphicsController)
{
- if( !mHasBeenUpdated )
+ if(!mHasBeenUpdated)
{
// Update buffers
- if( mIndicesChanged )
+ if(mIndicesChanged)
{
- if( mIndices.Empty() )
+ if(mIndices.Empty())
{
- mIndexBuffer = NULL;
+ mIndexBuffer = nullptr;
}
else
{
- if ( mIndexBuffer == NULL )
+ if(mIndexBuffer == nullptr)
{
- mIndexBuffer = new GpuBuffer( context );
+ mIndexBuffer = new GpuBuffer(graphicsController, 0 | Graphics::BufferUsage::INDEX_BUFFER);
}
- uint32_t bufferSize = static_cast<uint32_t>( sizeof( uint16_t ) * mIndices.Size() );
- mIndexBuffer->UpdateDataBuffer( bufferSize, &mIndices[0], GpuBuffer::STATIC_DRAW, GpuBuffer::ELEMENT_ARRAY_BUFFER );
+ uint32_t bufferSize = static_cast<uint32_t>(sizeof(uint16_t) * mIndices.Size());
+ mIndexBuffer->UpdateDataBuffer(graphicsController, bufferSize, &mIndices[0]);
}
mIndicesChanged = false;
}
- for( auto&& buffer : mVertexBuffers )
+ 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;
mHasBeenUpdated = true;
}
+}
+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() );
- for( uint32_t i = 0; i < vertexBufferCount; ++i )
+ 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)
+ {
+ 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())
{
- mVertexBuffers[i]->BindBuffer( GpuBuffer::ARRAY_BUFFER );
- base += mVertexBuffers[i]->EnableVertexAttributes( context, attributeLocation, base );
+ 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 )
+ if(mIndexBuffer)
{
- numIndices = static_cast<uint32_t>( mIndices.Size() );
+ std::size_t sizeOfIndex = GetSizeOfIndexFromIndexType(mIndexType);
- if( elementBufferOffset != 0u )
+ numIndices = static_cast<uint32_t>(mIndices.Size() * sizeof(uint16_t) / sizeOfIndex);
+
+ if(elementBufferOffset != 0u)
{
- elementBufferOffset = (elementBufferOffset >= numIndices ) ? numIndices - 1 : elementBufferOffset;
- firstIndexOffset = elementBufferOffset * sizeof(GLushort);
+ elementBufferOffset = (elementBufferOffset >= numIndices) ? numIndices - 1 : elementBufferOffset;
+ firstIndexOffset = intptr_t(elementBufferOffset * sizeOfIndex);
numIndices -= elementBufferOffset;
}
- if( elementBufferCount != 0u )
+ if(elementBufferCount != 0u)
+ {
+ numIndices = std::min(elementBufferCount, numIndices);
+ }
+ }
+
+ //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, 1, firstIndexOffset, 0, 0);
+ }
+ else
+ {
+ // Un-indexed draw call
+ uint32_t numVertices(0u);
+
+ if(mVertexBuffers.Count() > 0)
{
- numIndices = std::min( elementBufferCount, numIndices );
+ // truncated, no value loss happening in practice
+ numVertices = static_cast<uint32_t>(mVertexBuffers[0]->GetElementCount());
}
+
+ commandBuffer.Draw(numVertices, 1, 0, 0);
}
+ return true;
+}
+
+Graphics::PrimitiveTopology Geometry::GetTopology() const
+{
+ Graphics::PrimitiveTopology topology = Graphics::PrimitiveTopology::TRIANGLE_LIST;
- GLenum geometryGLType(GL_NONE);
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( 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 SceneGraph
+} // namespace Render
} // namespace Internal
} // namespace Dali