X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=dali%2Finternal%2Frender%2Frenderers%2Frender-geometry.cpp;h=b407b6f9fac49a5ac8adcb4e9fef84c039259f9c;hb=a513234144a775134eff3a24144983a5e374d1d5;hp=2084329cfec64481ac58e0a2bcd3ada89d2d3924;hpb=6e611d3be935ab4de2f4cfecc5082295260b6a30;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/render/renderers/render-geometry.cpp b/dali/internal/render/renderers/render-geometry.cpp index 2084329..b407b6f 100644 --- a/dali/internal/render/renderers/render-geometry.cpp +++ b/dali/internal/render/renderers/render-geometry.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 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. @@ -14,203 +14,274 @@ * limitations under the License. */ +// CLASS HEADER #include +// INTERNAL INCLUDES #include -#include -#include -#include -#include -#include +#include #include namespace Dali { namespace Internal { -namespace SceneGraph +namespace Render { - -RenderGeometry::RenderGeometry( const GeometryDataProvider& geometryDataProvider ) -: mGeometryDataProvider( geometryDataProvider ), +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), mAttributesChanged(true) { } -RenderGeometry::~RenderGeometry() +Geometry::~Geometry() = default; + +void Geometry::AddVertexBuffer(Render::VertexBuffer* vertexBuffer) { + mVertexBuffers.PushBack(vertexBuffer); + mAttributesChanged = true; } -void RenderGeometry::GlContextCreated( Context& context ) +const Vector& Geometry::GetVertexBuffers() const { + return mVertexBuffers; } -void RenderGeometry::GlContextDestroyed() +void Geometry::SetIndexBuffer(Uint16ContainerType& indices) { + mIndices.Swap(indices); + mIndicesChanged = true; + mIndexType = Graphics::Format::R16_UINT; } -void RenderGeometry::AddPropertyBuffer( const PropertyBufferDataProvider* dataProvider, GpuBuffer::Target gpuBufferTarget, GpuBuffer::Usage gpuBufferUsage ) +void Geometry::SetIndexBuffer(Uint32ContainerType& indices) { - if( gpuBufferTarget == GpuBuffer::ELEMENT_ARRAY_BUFFER ) - { - RenderPropertyBuffer* renderPropertyBuffer = new RenderPropertyBuffer( *dataProvider, gpuBufferTarget, gpuBufferUsage ); - mIndexBuffer = renderPropertyBuffer; - } - else if( gpuBufferTarget == GpuBuffer::ARRAY_BUFFER ) - { - RenderPropertyBuffer* renderPropertyBuffer = new RenderPropertyBuffer( *dataProvider, gpuBufferTarget, gpuBufferUsage ); - mVertexBuffers.PushBack( renderPropertyBuffer ); - mAttributesChanged = true; - } + // 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 RenderGeometry::RemovePropertyBuffer( const PropertyBufferDataProvider* dataProvider ) +void Geometry::RemoveVertexBuffer(const Render::VertexBuffer* vertexBuffer) { - if( dataProvider == &mIndexBuffer->GetDataProvider() ) + const auto&& end = mVertexBuffers.End(); + for(auto&& iter = mVertexBuffers.Begin(); iter != end; ++iter) { - mIndexBuffer.Reset(); + if(*iter == vertexBuffer) + { + //This will delete the gpu buffer associated to the RenderVertexBuffer if there is one + mVertexBuffers.Remove(iter); + mAttributesChanged = true; + break; + } } - else +} + +void Geometry::OnRenderFinished() +{ + mHasBeenUpdated = false; + mAttributesChanged = false; +} + +void Geometry::Upload(Graphics::Controller& graphicsController) +{ + if(!mHasBeenUpdated) { - for( RenderPropertyBufferIter iter( mVertexBuffers.Begin() ); iter != mVertexBuffers.End(); ++iter ) + // Update buffers + if(mIndicesChanged) { - if( dataProvider == &(*iter)->GetDataProvider() ) + if(mIndices.Empty()) { - //This will delete the gpu buffer associated to the RenderPropertyBuffer if there is one - mVertexBuffers.Remove( iter ); - mAttributesChanged = true; - break; + mIndexBuffer = nullptr; } + else + { + if(mIndexBuffer == nullptr) + { + mIndexBuffer = new GpuBuffer(graphicsController, 0 | Graphics::BufferUsage::INDEX_BUFFER); + } + + uint32_t bufferSize = static_cast(sizeof(uint16_t) * mIndices.Size()); + mIndexBuffer->UpdateDataBuffer(graphicsController, bufferSize, &mIndices[0]); + } + + mIndicesChanged = false; } + + for(auto&& buffer : mVertexBuffers) + { + if(!buffer->Update(graphicsController)) + { + //Vertex buffer is not ready ( Size, data or format has not been specified yet ) + return; + } + } + + mHasBeenUpdated = true; } } -void RenderGeometry::GetAttributeLocationFromProgram( Vector& attributeLocation, Program& program, BufferIndex bufferIndex ) const +bool Geometry::BindVertexAttributes(Graphics::CommandBuffer& commandBuffer) { - attributeLocation.Clear(); + //Bind buffers to attribute locations + const auto vertexBufferCount = static_cast(mVertexBuffers.Count()); + + std::vector buffers; + std::vector offsets; - for( size_t i(0); i< mVertexBuffers.Size(); ++i ) + for(uint32_t i = 0; i < vertexBufferCount; ++i) { - unsigned int attributeCount = mVertexBuffers[i]->GetDataProvider().GetAttributeCount( bufferIndex ); - for( unsigned int j = 0; j < attributeCount; ++j ) + const GpuBuffer* gpuBuffer = mVertexBuffers[i]->GetGpuBuffer(); + if(gpuBuffer) { - const std::string& attributeName = mVertexBuffers[i]->GetDataProvider().GetAttributeName( bufferIndex, j ); - unsigned int index = program.RegisterCustomAttribute( attributeName ); - GLint location = program.GetCustomAttributeLocation( index ); + const Graphics::Buffer* buffer = gpuBuffer->GetGraphicsObject(); - if( -1 == location ) + if(buffer) { - DALI_LOG_WARNING( "Attribute not found in the shader: %s\n", attributeName.c_str() ); + buffers.push_back(buffer); + offsets.push_back(0u); } - - attributeLocation.PushBack( location ); } + //@todo Figure out why this is being drawn without geometry having been uploaded + } + if(buffers.empty()) + { + return false; } -} -void RenderGeometry::OnRenderFinished() -{ - mHasBeenUpdated = false; - mAttributesChanged = false; + commandBuffer.BindVertexBuffers(0, buffers, offsets); + + return true; } -void RenderGeometry::UploadAndDraw( - Context& context, - BufferIndex bufferIndex, - Vector& attributeLocation ) +bool Geometry::Draw( + Graphics::Controller& graphicsController, + Graphics::CommandBuffer& commandBuffer, + uint32_t elementBufferOffset, + uint32_t elementBufferCount) { - if( !mHasBeenUpdated ) + uint32_t numIndices(0u); + intptr_t firstIndexOffset(0u); + if(mIndexBuffer) { - //Update buffers - if( mIndexBuffer ) + std::size_t sizeOfIndex = GetSizeOfIndexFromIndexType(mIndexType); + + numIndices = static_cast(mIndices.Size() * sizeof(uint16_t) / sizeOfIndex); + + if(elementBufferOffset != 0u) { - mIndexBuffer->Update( context, bufferIndex ); + elementBufferOffset = (elementBufferOffset >= numIndices) ? numIndices - 1 : elementBufferOffset; + firstIndexOffset = intptr_t(elementBufferOffset * sizeOfIndex); + numIndices -= elementBufferOffset; } - for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i ) + + if(elementBufferCount != 0u) { - mVertexBuffers[i]->Update( context, bufferIndex ); + numIndices = std::min(elementBufferCount, numIndices); } - mHasBeenUpdated = true; } - //Bind buffers to attribute locations - unsigned int base = 0; - for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i ) + //Draw call + if(mIndexBuffer && mGeometryType != Dali::Geometry::POINTS) { - mVertexBuffers[i]->BindBuffer( context ); - base += mVertexBuffers[i]->EnableVertexAttributes( context, bufferIndex, attributeLocation, base ); - } + //Indexed draw call + const Graphics::Buffer* ibo = mIndexBuffer->GetGraphicsObject(); + if(ibo) + { + commandBuffer.BindIndexBuffer(*ibo, 0, mIndexType); + } - if( mIndexBuffer ) - { - mIndexBuffer->BindBuffer( context ); + commandBuffer.DrawIndexed(numIndices, 1, firstIndexOffset, 0, 0); } - - //Bind index buffer - unsigned int numIndices(0u); - if( mIndexBuffer ) + else { - const PropertyBufferDataProvider& indexBuffer = mIndexBuffer->GetDataProvider(); - numIndices = mIndexBuffer->GetDataProvider().GetDataSize(bufferIndex) / indexBuffer.GetElementSize(bufferIndex); + // Un-indexed draw call + uint32_t numVertices(0u); + + if(mVertexBuffers.Count() > 0) + { + // truncated, no value loss happening in practice + numVertices = static_cast(mVertexBuffers[0]->GetElementCount()); + } + + commandBuffer.Draw(numVertices, 1, 0, 0); } + return true; +} - //Draw call - GeometryDataProvider::GeometryType type = mGeometryDataProvider.GetGeometryType( bufferIndex ); - switch(type) +Graphics::PrimitiveTopology Geometry::GetTopology() const +{ + Graphics::PrimitiveTopology topology = Graphics::PrimitiveTopology::TRIANGLE_LIST; + + switch(mGeometryType) { case Dali::Geometry::TRIANGLES: { - if( numIndices ) - { - context.DrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0); - } - else - { - const PropertyBufferDataProvider& firstVertexBuffer = mVertexBuffers[0]->GetDataProvider(); - unsigned int numVertices = firstVertexBuffer.GetElementCount( bufferIndex ); - context.DrawArrays( GL_TRIANGLES, 0, numVertices ); - } + topology = Graphics::PrimitiveTopology::TRIANGLE_LIST; break; } case Dali::Geometry::LINES: { - if( numIndices ) - { - context.DrawElements(GL_LINES, numIndices, GL_UNSIGNED_SHORT, 0); - } - else - { - const PropertyBufferDataProvider& firstVertexBuffer = mVertexBuffers[0]->GetDataProvider(); - unsigned int numVertices = firstVertexBuffer.GetElementCount( bufferIndex ); - context.DrawArrays( GL_LINES, 0, numVertices ); - } + topology = Graphics::PrimitiveTopology::LINE_LIST; break; } case Dali::Geometry::POINTS: { - const PropertyBufferDataProvider& firstVertexBuffer = mVertexBuffers[0]->GetDataProvider(); - unsigned int numVertices = firstVertexBuffer.GetElementCount( bufferIndex ); - context.DrawArrays(GL_POINTS, 0, numVertices ); + topology = Graphics::PrimitiveTopology::POINT_LIST; break; } - default: + case Dali::Geometry::TRIANGLE_STRIP: { - DALI_ASSERT_ALWAYS( 0 && "Geometry type not supported (yet)" ); + topology = Graphics::PrimitiveTopology::TRIANGLE_STRIP; break; } - } - - //Disable atrributes - for( unsigned int i = 0; i < attributeLocation.Count(); ++i ) - { - if( attributeLocation[i] != -1 ) + case Dali::Geometry::TRIANGLE_FAN: { - context.DisableVertexAttributeArray( attributeLocation[i] ); + topology = Graphics::PrimitiveTopology::TRIANGLE_FAN; + break; + } + case Dali::Geometry::LINE_LOOP: + { + topology = Graphics::PrimitiveTopology::LINE_LOOP; + break; + } + case Dali::Geometry::LINE_STRIP: + { + topology = Graphics::PrimitiveTopology::LINE_STRIP; + break; } } + return topology; } -} // namespace SceneGraph +} // namespace Render } // namespace Internal } // namespace Dali