From: Ferran Sole Date: Fri, 3 Jul 2015 16:26:48 +0000 (+0100) Subject: Allow sharing RenderGeometries across multiple Renderers X-Git-Tag: dali_1.0.49~15 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=13c23d2628ce5e911c432062e7660a36a468d823 Allow sharing RenderGeometries across multiple Renderers Change-Id: I48d337a4d258e067fd5e01ad7075b24984092dcb --- diff --git a/automated-tests/src/dali-devel/utc-Dali-Geometry.cpp b/automated-tests/src/dali-devel/utc-Dali-Geometry.cpp index 5bb2278..7933b06 100644 --- a/automated-tests/src/dali-devel/utc-Dali-Geometry.cpp +++ b/automated-tests/src/dali-devel/utc-Dali-Geometry.cpp @@ -189,10 +189,9 @@ int UtcDaliGeometryAddVertexBuffer(void) const TestGlAbstraction::BufferDataCalls& bufferDataCalls = application.GetGlAbstraction().GetBufferDataCalls(); - DALI_TEST_EQUALS( bufferDataCalls.size(), 2u, TEST_LOCATION ); - + //Check that only the new buffer gets uploaded + DALI_TEST_EQUALS( bufferDataCalls.size(), 1u, TEST_LOCATION ); DALI_TEST_EQUALS( bufferDataCalls[0], 4*sizeof( TexturedQuadVertex ), TEST_LOCATION ); - DALI_TEST_EQUALS( bufferDataCalls[1], 4*sizeof( TexturedQuadVertex ), TEST_LOCATION ); } END_TEST; @@ -301,11 +300,11 @@ int UtcDaliGeometrySetIndexBuffer(void) const TestGlAbstraction::BufferDataCalls& bufferDataCalls = application.GetGlAbstraction().GetBufferDataCalls(); - DALI_TEST_EQUALS( bufferDataCalls.size(), 2u, TEST_LOCATION ); + //Only the index buffer should be uploaded + DALI_TEST_EQUALS( bufferDataCalls.size(), 1u, TEST_LOCATION ); - DALI_TEST_EQUALS( bufferDataCalls[0], 4*sizeof( TexturedQuadVertex ), TEST_LOCATION ); // should be unsigned short instead of unsigned int - DALI_TEST_EQUALS( bufferDataCalls[1], 6*sizeof( unsigned short ), TEST_LOCATION ); + DALI_TEST_EQUALS( bufferDataCalls[0], 6*sizeof( unsigned short ), TEST_LOCATION ); } diff --git a/automated-tests/src/dali-devel/utc-Dali-PropertyBuffer.cpp b/automated-tests/src/dali-devel/utc-Dali-PropertyBuffer.cpp index d1cdd6c..55b3d10 100644 --- a/automated-tests/src/dali-devel/utc-Dali-PropertyBuffer.cpp +++ b/automated-tests/src/dali-devel/utc-Dali-PropertyBuffer.cpp @@ -369,79 +369,78 @@ int UtcDaliPropertyBufferSetData01(void) END_TEST; } -// @todo MESH_REWORK Test case temporarily commented until "RenderGeometry reuse" patch is merged -//int UtcDaliPropertyBufferSetData02(void) -//{ -// TestApplication application; -// -// Property::Map texturedQuadVertexFormat; -// texturedQuadVertexFormat["aPosition"] = Property::VECTOR2; -// texturedQuadVertexFormat["aVertexCoord"] = Property::VECTOR2; -// -// PropertyBuffer propertyBuffer = PropertyBuffer::New( texturedQuadVertexFormat, 4 ); -// DALI_TEST_EQUALS( (bool)propertyBuffer, true, TEST_LOCATION ); -// -// const float halfQuadSize = .5f; -// struct TexturedQuadVertex { Vector2 position; Vector2 textureCoordinates; }; -// TexturedQuadVertex texturedQuadVertexData[4] = { -// { Vector2(-halfQuadSize, -halfQuadSize), Vector2(0.f, 0.f) }, -// { Vector2( halfQuadSize, -halfQuadSize), Vector2(1.f, 0.f) }, -// { Vector2(-halfQuadSize, halfQuadSize), Vector2(0.f, 1.f) }, -// { Vector2( halfQuadSize, halfQuadSize), Vector2(1.f, 1.f) } }; -// -// propertyBuffer.SetData( texturedQuadVertexData ); -// -// Geometry geometry = Geometry::New(); -// geometry.AddVertexBuffer( propertyBuffer ); -// -// Material material = CreateMaterial(1.f); -// Renderer renderer = Renderer::New(geometry, material); -// Actor actor = Actor::New(); -// actor.SetSize(Vector3::ONE * 100.f); -// actor.AddRenderer(renderer); -// Stage::GetCurrent().Add(actor); -// -// application.SendNotification(); -// application.Render(0); -// application.Render(); -// application.SendNotification(); -// -// { -// const TestGlAbstraction::BufferDataCalls& bufferDataCalls = -// application.GetGlAbstraction().GetBufferDataCalls(); -// -// DALI_TEST_EQUALS( bufferDataCalls.size(), 1u, TEST_LOCATION ); -// -// DALI_TEST_EQUALS( bufferDataCalls[0], sizeof(texturedQuadVertexData), TEST_LOCATION ); -// } -// -// // Re-upload the data on the propertyBuffer -// propertyBuffer.SetData( texturedQuadVertexData ); -// -// application.SendNotification(); -// application.Render(0); -// application.Render(); -// application.SendNotification(); -// -// { -// const TestGlAbstraction::BufferSubDataCalls& bufferSubDataCalls = -// application.GetGlAbstraction().GetBufferSubDataCalls(); -// -// const TestGlAbstraction::BufferDataCalls& bufferDataCalls = -// application.GetGlAbstraction().GetBufferDataCalls(); -// -// DALI_TEST_EQUALS( bufferSubDataCalls.size(), 1u, TEST_LOCATION ); -// DALI_TEST_EQUALS( bufferDataCalls.size(), 1u, TEST_LOCATION ); -// -// if ( bufferSubDataCalls.size() ) -// { -// DALI_TEST_EQUALS( bufferSubDataCalls[0], sizeof(texturedQuadVertexData), TEST_LOCATION ); -// -// } -// } -// -// END_TEST; -//} +int UtcDaliPropertyBufferSetData02(void) +{ + TestApplication application; + + Property::Map texturedQuadVertexFormat; + texturedQuadVertexFormat["aPosition"] = Property::VECTOR2; + texturedQuadVertexFormat["aVertexCoord"] = Property::VECTOR2; + + PropertyBuffer propertyBuffer = PropertyBuffer::New( texturedQuadVertexFormat, 4 ); + DALI_TEST_EQUALS( (bool)propertyBuffer, true, TEST_LOCATION ); + + const float halfQuadSize = .5f; + struct TexturedQuadVertex { Vector2 position; Vector2 textureCoordinates; }; + TexturedQuadVertex texturedQuadVertexData[4] = { + { Vector2(-halfQuadSize, -halfQuadSize), Vector2(0.f, 0.f) }, + { Vector2( halfQuadSize, -halfQuadSize), Vector2(1.f, 0.f) }, + { Vector2(-halfQuadSize, halfQuadSize), Vector2(0.f, 1.f) }, + { Vector2( halfQuadSize, halfQuadSize), Vector2(1.f, 1.f) } }; + + propertyBuffer.SetData( texturedQuadVertexData ); + + Geometry geometry = Geometry::New(); + geometry.AddVertexBuffer( propertyBuffer ); + + Material material = CreateMaterial(1.f); + Renderer renderer = Renderer::New(geometry, material); + Actor actor = Actor::New(); + actor.SetSize(Vector3::ONE * 100.f); + actor.AddRenderer(renderer); + Stage::GetCurrent().Add(actor); + + application.SendNotification(); + application.Render(0); + application.Render(); + application.SendNotification(); + + { + const TestGlAbstraction::BufferDataCalls& bufferDataCalls = + application.GetGlAbstraction().GetBufferDataCalls(); + + DALI_TEST_EQUALS( bufferDataCalls.size(), 1u, TEST_LOCATION ); + + DALI_TEST_EQUALS( bufferDataCalls[0], sizeof(texturedQuadVertexData), TEST_LOCATION ); + } + + // Re-upload the data on the propertyBuffer + propertyBuffer.SetData( texturedQuadVertexData ); + + application.SendNotification(); + application.Render(0); + application.Render(); + application.SendNotification(); + + { + const TestGlAbstraction::BufferSubDataCalls& bufferSubDataCalls = + application.GetGlAbstraction().GetBufferSubDataCalls(); + + const TestGlAbstraction::BufferDataCalls& bufferDataCalls = + application.GetGlAbstraction().GetBufferDataCalls(); + + DALI_TEST_EQUALS( bufferSubDataCalls.size(), 1u, TEST_LOCATION ); + DALI_TEST_EQUALS( bufferDataCalls.size(), 1u, TEST_LOCATION ); + + if ( bufferSubDataCalls.size() ) + { + DALI_TEST_EQUALS( bufferSubDataCalls[0], sizeof(texturedQuadVertexData), TEST_LOCATION ); + + } + } + + END_TEST; +} int UtcDaliPropertyBufferSetGetSize01(void) { diff --git a/dali/internal/event/rendering/geometry-impl.cpp b/dali/internal/event/rendering/geometry-impl.cpp index bbed300..60081f2 100644 --- a/dali/internal/event/rendering/geometry-impl.cpp +++ b/dali/internal/event/rendering/geometry-impl.cpp @@ -68,7 +68,7 @@ std::size_t Geometry::AddVertexBuffer( PropertyBuffer& vertexBuffer ) connector.Set( vertexBuffer, OnStage() ); mVertexBufferConnectors.push_back( connector ); - const SceneGraph::PropertyBuffer& sceneGraphPropertyBuffer = dynamic_cast( *vertexBuffer.GetSceneObject() ); + const SceneGraph::PropertyBuffer& sceneGraphPropertyBuffer = static_cast( *vertexBuffer.GetSceneObject() ); SceneGraph::AddVertexBufferMessage( GetEventThreadServices(), *mSceneObject, sceneGraphPropertyBuffer ); @@ -82,6 +82,9 @@ std::size_t Geometry::GetNumberOfVertexBuffers() const void Geometry::RemoveVertexBuffer( std::size_t index ) { + const SceneGraph::PropertyBuffer& sceneGraphPropertyBuffer = static_cast( *(mVertexBufferConnectors[index].Get()->GetSceneObject()) ); + SceneGraph::RemoveVertexBufferMessage( GetEventThreadServices(), *mSceneObject, sceneGraphPropertyBuffer ); + mVertexBufferConnectors.erase( mVertexBufferConnectors.begin() + index ); } diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index a226306..8d6446d 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include // Uncomment the next line to enable frame snapshot logging @@ -71,6 +72,9 @@ namespace SceneGraph typedef OwnerContainer< Renderer* > RendererOwnerContainer; typedef RendererOwnerContainer::Iterator RendererOwnerIter; +typedef OwnerContainer< RenderGeometry* > RenderGeometryOwnerContainer; +typedef RenderGeometryOwnerContainer::Iterator RenderGeometryOwnerIter; + typedef OwnerContainer< RenderTracker* > RenderTrackerContainer; typedef RenderTrackerContainer::Iterator RenderTrackerIter; typedef RenderTrackerContainer::ConstIterator RenderTrackerConstIter; @@ -135,34 +139,35 @@ struct RenderManager::Impl // the order is important for destruction, // programs are owned by context at the moment. - Context context; ///< holds the GL state - RenderQueue renderQueue; ///< A message queue for receiving messages from the update-thread. - TextureCache textureCache; ///< Cache for all GL textures - ResourcePostProcessList& resourcePostProcessQueue; ///< A queue for requesting resource post processing in update thread + Context context; ///< holds the GL state + RenderQueue renderQueue; ///< A message queue for receiving messages from the update-thread. + TextureCache textureCache; ///< Cache for all GL textures + ResourcePostProcessList& resourcePostProcessQueue; ///< A queue for requesting resource post processing in update thread // Render instructions describe what should be rendered during RenderManager::Render() // Owned by RenderManager. Update manager updates instructions for the next frame while we render the current one - RenderInstructionContainer instructions; + RenderInstructionContainer instructions; - Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame. + Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame. - float frameTime; ///< The elapsed time since the previous frame - float lastFrameTime; ///< Last frame delta. + float frameTime; ///< The elapsed time since the previous frame + float lastFrameTime; ///< Last frame delta. - unsigned int frameCount; ///< The current frame count - BufferIndex renderBufferIndex; ///< The index of the buffer to read from; this is opposite of the "update" buffer + unsigned int frameCount; ///< The current frame count + BufferIndex renderBufferIndex; ///< The index of the buffer to read from; this is opposite of the "update" buffer - Rect defaultSurfaceRect; ///< Rectangle for the default surface we are rendering to + Rect defaultSurfaceRect; ///< Rectangle for the default surface we are rendering to - RendererOwnerContainer rendererContainer; ///< List of owned renderers + RendererOwnerContainer rendererContainer; ///< List of owned renderers + RenderGeometryOwnerContainer renderGeometryContainer; ///< List of owned RenderGeometries - bool renderersAdded; + bool renderersAdded; - RenderTrackerContainer mRenderTrackers; ///< List of render trackers + RenderTrackerContainer mRenderTrackers; ///< List of render trackers - bool firstRenderCompleted; ///< False until the first render is done - Shader* defaultShader; ///< Default shader to use - ProgramController programController; ///< Owner of the GL programs + bool firstRenderCompleted; ///< False until the first render is done + Shader* defaultShader; ///< Default shader to use + ProgramController programController; ///< Owner of the GL programs }; RenderManager* RenderManager::New( Integration::GlAbstraction& glAbstraction, ResourcePostProcessList& resourcePostProcessQ ) @@ -277,6 +282,63 @@ void RenderManager::RemoveRenderer( Renderer* renderer ) } } +void RenderManager::AddGeometry( RenderGeometry* renderGeometry ) +{ + mImpl->renderGeometryContainer.PushBack( renderGeometry ); +} + +void RenderManager::RemoveGeometry( RenderGeometry* renderGeometry ) +{ + DALI_ASSERT_DEBUG( NULL != renderGeometry ); + + RenderGeometryOwnerContainer& geometries = mImpl->renderGeometryContainer; + + // Find the renderer + for ( RenderGeometryOwnerIter iter = geometries.Begin(); iter != geometries.End(); ++iter ) + { + if ( *iter == renderGeometry ) + { + geometries.Erase( iter ); // Geometry found; now destroy it + break; + } + } +} + +void RenderManager::AddPropertyBuffer( RenderGeometry* renderGeometry, PropertyBufferDataProvider* propertyBuffer, const GpuBuffer::Target& target, const GpuBuffer::Usage& usage ) +{ + DALI_ASSERT_DEBUG( NULL != renderGeometry ); + + RenderGeometryOwnerContainer& geometries = mImpl->renderGeometryContainer; + + // Find the renderer + for ( RenderGeometryOwnerIter iter = geometries.Begin(); iter != geometries.End(); ++iter ) + { + if ( *iter == renderGeometry ) + { + (*iter)->AddPropertyBuffer( propertyBuffer, target, usage ); + break; + } + } +} + +void RenderManager::RemovePropertyBuffer( RenderGeometry* renderGeometry, PropertyBufferDataProvider* propertyBuffer ) +{ + DALI_ASSERT_DEBUG( NULL != renderGeometry ); + + RenderGeometryOwnerContainer& geometries = mImpl->renderGeometryContainer; + + // Find the renderer + for ( RenderGeometryOwnerIter iter = geometries.Begin(); iter != geometries.End(); ++iter ) + { + if ( *iter == renderGeometry ) + { + (*iter)->RemovePropertyBuffer( propertyBuffer ); + break; + } + } +} + + void RenderManager::AddRenderTracker( RenderTracker* renderTracker ) { mImpl->AddRenderTracker(renderTracker); @@ -385,6 +447,12 @@ bool RenderManager::Render( Integration::RenderStatus& status ) // check if anything has been posted to the update thread bool updateRequired = !mImpl->resourcePostProcessQueue[ mImpl->renderBufferIndex ].empty(); + //Notify RenderGeometries that rendering has finished + for ( RenderGeometryOwnerIter iter = mImpl->renderGeometryContainer.Begin(); iter != mImpl->renderGeometryContainer.End(); ++iter ) + { + (*iter)->OnRenderFinished(); + } + /** * The rendering has finished; swap to the next buffer. * Ideally the update has just finished using this buffer; otherwise the render thread diff --git a/dali/internal/render/common/render-manager.h b/dali/internal/render/common/render-manager.h index 3c86f3a..5ec8b0d 100644 --- a/dali/internal/render/common/render-manager.h +++ b/dali/internal/render/common/render-manager.h @@ -22,6 +22,7 @@ #include #include #include +#include namespace Dali { @@ -48,6 +49,8 @@ class RenderInstruction; class RenderInstructionContainer; class RenderTracker; class Shader; +class RenderGeometry; +class PropertyBufferDataProvider; /** * RenderManager is responsible for rendering the result of the previous "update", which @@ -139,6 +142,37 @@ public: void RemoveRenderer( Renderer* renderer ); /** + * Add a geometry to the render manager. + * @param[in] geometry The geometry to add. + * @post geometry is owned by RenderManager + */ + void AddGeometry( RenderGeometry* geometry ); + + /** + * Remove a geometry from the render manager. + * @param[in] geometry The geometry to remove. + * @post geometry is destroyed. + */ + void RemoveGeometry( RenderGeometry* geometry ); + + /** + * Adds a property buffer to a RenderGeometry from the render manager. + * @param[in] geometry The geometry + * @param[in] propertyBuffer The property buffer to remove. + * @param[in] target Specifies the type of the buffer + * @param[in] usage Specifies how will the buffer be used + */ + void AddPropertyBuffer( RenderGeometry* renderGeometry, PropertyBufferDataProvider* propertyBuffer, const GpuBuffer::Target& target, const GpuBuffer::Usage& usage ); + + /** + * Remove a property buffer from a RenderGeometry from the render manager. + * @param[in] geometry The geometry + * @param[in] propertyBuffer The property buffer to remove. + * @post property buffer is destroyed. + */ + void RemovePropertyBuffer( RenderGeometry* renderGeometry, PropertyBufferDataProvider* propertyBuffer ); + + /** * Adds a render tracker to the RenderManager. RenderManager takes ownership of the * tracker. The lifetime of the tracker is related to the lifetime of the tracked * object, usually an offscreen render task. diff --git a/dali/internal/render/data-providers/property-buffer-data-provider.h b/dali/internal/render/data-providers/property-buffer-data-provider.h index f2a9ba7..61e1e30 100644 --- a/dali/internal/render/data-providers/property-buffer-data-provider.h +++ b/dali/internal/render/data-providers/property-buffer-data-provider.h @@ -123,6 +123,13 @@ public: */ virtual unsigned int GetGpuBufferId( BufferIndex bufferIndex ) const = 0; + /** + * Checks if data in the PropertyBuffer has changed repect previous frame + * @param[in] bufferIndex Index to access double buffered values + * @return true if data has changed, false otherwise + */ + virtual bool HasDataChanged( BufferIndex bufferIndex ) const = 0; + protected: /** * No deletion through this interface diff --git a/dali/internal/render/data-providers/render-data-provider.cpp b/dali/internal/render/data-providers/render-data-provider.cpp index 8b7cf23..f78af39 100644 --- a/dali/internal/render/data-providers/render-data-provider.cpp +++ b/dali/internal/render/data-providers/render-data-provider.cpp @@ -25,11 +25,9 @@ namespace SceneGraph { RenderDataProvider::RenderDataProvider() -: mGeometryDataProvider( NULL ), - mMaterialDataProvider( NULL ), +: mMaterialDataProvider( NULL ), mUniformMapDataProvider( NULL ), - mShader( NULL ), - mIndexBuffer( NULL ) + mShader( NULL ) { } @@ -37,16 +35,6 @@ RenderDataProvider::~RenderDataProvider() { } -void RenderDataProvider::SetGeometry( const GeometryDataProvider& geometryDataProvider ) -{ - mGeometryDataProvider = &geometryDataProvider; -} - -const GeometryDataProvider& RenderDataProvider::GetGeometry() const -{ - return *mGeometryDataProvider; -} - void RenderDataProvider::SetMaterial( const MaterialDataProvider& materialDataProvider ) { mMaterialDataProvider = &materialDataProvider; @@ -77,27 +65,6 @@ Shader& RenderDataProvider::GetShader() const return *mShader; } -void RenderDataProvider::SetIndexBuffer( const PropertyBufferDataProvider* indexBuffer ) -{ - mIndexBuffer = indexBuffer; -} - -const PropertyBufferDataProvider* RenderDataProvider::GetIndexBuffer() const -{ - return mIndexBuffer; -} - -void RenderDataProvider::SetVertexBuffers( const RenderDataProvider::VertexBuffers& vertexBuffers) -{ - DALI_ASSERT_DEBUG( vertexBuffers.Count() > 0 && "Using empty vertex buffer" ); - mVertexBuffers = vertexBuffers; -} - -const RenderDataProvider::VertexBuffers& RenderDataProvider::GetVertexBuffers() const -{ - return mVertexBuffers; -} - void RenderDataProvider::SetSamplers( const RenderDataProvider::Samplers& samplers ) { mSamplers = samplers; diff --git a/dali/internal/render/data-providers/render-data-provider.h b/dali/internal/render/data-providers/render-data-provider.h index ea83092..cf3aeb6 100644 --- a/dali/internal/render/data-providers/render-data-provider.h +++ b/dali/internal/render/data-providers/render-data-provider.h @@ -62,17 +62,6 @@ public: ~RenderDataProvider(); public: - /** - * Set the geometry data provider - * @param[in] geometryDataProvider The geometry data provider - */ - void SetGeometry( const GeometryDataProvider& geometryDataProvider ); - - /** - * Get the geometry data provider - * @return the geometry data provider - */ - const GeometryDataProvider& GetGeometry() const; /** * Set the material data provider @@ -110,30 +99,6 @@ public: Shader& GetShader() const; /** - * Set the index buffer - * @param[in] indexBuffer the index buffer to set - */ - void SetIndexBuffer( const PropertyBufferDataProvider* indexBuffer ); - - /** - * Get the index buffer of the geometry - * @return A const reference to the index buffer - */ - const PropertyBufferDataProvider* GetIndexBuffer() const; - - /** - * Set the vertex buffers - * @param[in] vertexBuffers The vertex buffers - */ - void SetVertexBuffers( const VertexBuffers& vertexBuffers ); - - /** - * Get the vertex buffers of the geometry - * @return A const reference to the vertex buffers - */ - const VertexBuffers& GetVertexBuffers() const; - - /** * Set the sampler data providers * @param[in] samplers The sampler data providers */ @@ -146,12 +111,9 @@ public: const Samplers& GetSamplers() const; private: - const GeometryDataProvider* mGeometryDataProvider; const MaterialDataProvider* mMaterialDataProvider; const UniformMapDataProvider* mUniformMapDataProvider; Shader* mShader; - const PropertyBufferDataProvider* mIndexBuffer; - VertexBuffers mVertexBuffers; Samplers mSamplers; // Give RendererAttachment access to our private data to reduce copying vectors on construction. diff --git a/dali/internal/render/renderers/render-geometry.cpp b/dali/internal/render/renderers/render-geometry.cpp index 808854c..2084329 100644 --- a/dali/internal/render/renderers/render-geometry.cpp +++ b/dali/internal/render/renderers/render-geometry.cpp @@ -31,9 +31,10 @@ namespace Internal namespace SceneGraph { -RenderGeometry::RenderGeometry() -: mDataNeedsUploading( true ), - mShaderChanged( true ) +RenderGeometry::RenderGeometry( const GeometryDataProvider& geometryDataProvider ) +: mGeometryDataProvider( geometryDataProvider ), + mHasBeenUpdated(false), + mAttributesChanged(true) { } @@ -43,149 +44,119 @@ RenderGeometry::~RenderGeometry() void RenderGeometry::GlContextCreated( Context& context ) { - mDataNeedsUploading = true; } void RenderGeometry::GlContextDestroyed() { } -void RenderGeometry::UploadAndDraw( - Context& context, - Program& program, - BufferIndex bufferIndex, - const RenderDataProvider* dataProviders ) +void RenderGeometry::AddPropertyBuffer( const PropertyBufferDataProvider* dataProvider, GpuBuffer::Target gpuBufferTarget, GpuBuffer::Usage gpuBufferUsage ) { - UploadVertexData( context, program, bufferIndex, dataProviders ); - - for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i ) + if( gpuBufferTarget == GpuBuffer::ELEMENT_ARRAY_BUFFER ) { - mVertexBuffers[i]->BindBuffer( context, program ); - mVertexBuffers[i]->EnableVertexAttributes( context, bufferIndex, program ); + RenderPropertyBuffer* renderPropertyBuffer = new RenderPropertyBuffer( *dataProvider, gpuBufferTarget, gpuBufferUsage ); + mIndexBuffer = renderPropertyBuffer; } - - if( mIndexBuffer ) + else if( gpuBufferTarget == GpuBuffer::ARRAY_BUFFER ) { - mIndexBuffer->BindBuffer( context, program ); - } - - Draw( context, bufferIndex, dataProviders ); - - for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i ) - { - mVertexBuffers[i]->DisableVertexAttributes( context, bufferIndex, program ); + RenderPropertyBuffer* renderPropertyBuffer = new RenderPropertyBuffer( *dataProvider, gpuBufferTarget, gpuBufferUsage ); + mVertexBuffers.PushBack( renderPropertyBuffer ); + mAttributesChanged = true; } } -void RenderGeometry::GeometryUpdated() +void RenderGeometry::RemovePropertyBuffer( const PropertyBufferDataProvider* dataProvider ) { - mDataNeedsUploading = true; -} - -void RenderGeometry::UploadVertexData( - Context& context, - Program& program, - BufferIndex bufferIndex, - const RenderDataProvider* dataProviders ) -{ - if( mDataNeedsUploading ) + if( dataProvider == &mIndexBuffer->GetDataProvider() ) { - SetUpPropertyBuffers( context, bufferIndex, dataProviders ); - - for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i ) - { - mVertexBuffers[i]->Upload( context, bufferIndex ); - mVertexBuffers[i]->UpdateAttributeLocations( context, bufferIndex, program ); - } - if( mIndexBuffer ) + mIndexBuffer.Reset(); + } + else + { + for( RenderPropertyBufferIter iter( mVertexBuffers.Begin() ); iter != mVertexBuffers.End(); ++iter ) { - mIndexBuffer->Upload( context, bufferIndex ); + if( dataProvider == &(*iter)->GetDataProvider() ) + { + //This will delete the gpu buffer associated to the RenderPropertyBuffer if there is one + mVertexBuffers.Remove( iter ); + mAttributesChanged = true; + break; + } } - - mDataNeedsUploading = false; } } -void RenderGeometry::SetUpPropertyBuffers( - Context& context, - BufferIndex bufferIndex, - const RenderDataProvider* dataProvider ) +void RenderGeometry::GetAttributeLocationFromProgram( Vector& attributeLocation, Program& program, BufferIndex bufferIndex ) const { - // Vertex buffer - RenderDataProvider::VertexBuffers vertexBuffers = dataProvider->GetVertexBuffers(); + attributeLocation.Clear(); - DALI_ASSERT_DEBUG( vertexBuffers.Count() > 0 && "Need vertex buffers to upload" ); - - mVertexBuffers.Clear(); - for( unsigned int i=0; iGetDataProvider().GetAttributeCount( bufferIndex ); + for( unsigned int j = 0; j < attributeCount; ++j ) + { + const std::string& attributeName = mVertexBuffers[i]->GetDataProvider().GetAttributeName( bufferIndex, j ); + unsigned int index = program.RegisterCustomAttribute( attributeName ); + GLint location = program.GetCustomAttributeLocation( index ); - mVertexBuffers.PushBack( propertyBuffer ); - } + if( -1 == location ) + { + DALI_LOG_WARNING( "Attribute not found in the shader: %s\n", attributeName.c_str() ); + } - // Index buffer - const PropertyBufferDataProvider* indexBuffer = dataProvider->GetIndexBuffer(); - if( indexBuffer ) - { - mIndexBuffer = new RenderPropertyBuffer( - *indexBuffer, - GpuBuffer::ELEMENT_ARRAY_BUFFER, - GpuBuffer::STATIC_DRAW ); // TODO: MESH_REWORK: change this for animated meshes + attributeLocation.PushBack( location ); + } } } -void RenderGeometry::BindBuffers( Context& context, BufferIndex bufferIndex, Program& program ) +void RenderGeometry::OnRenderFinished() { - for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i ) - { - mVertexBuffers[i]->BindBuffer( context, program ); - } - - if( mIndexBuffer ) - { - mIndexBuffer->BindBuffer( context, program ); - } + mHasBeenUpdated = false; + mAttributesChanged = false; } -void RenderGeometry::EnableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& program ) +void RenderGeometry::UploadAndDraw( + Context& context, + BufferIndex bufferIndex, + Vector& attributeLocation ) { - OwnerContainer< RenderPropertyBuffer* >::Iterator it = mVertexBuffers.Begin(); - OwnerContainer< RenderPropertyBuffer* >::ConstIterator end = mVertexBuffers.End(); - for( ; it != end; ++it ) + if( !mHasBeenUpdated ) { - (*it)->EnableVertexAttributes( context, bufferIndex, program ); + //Update buffers + if( mIndexBuffer ) + { + mIndexBuffer->Update( context, bufferIndex ); + } + for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i ) + { + mVertexBuffers[i]->Update( context, bufferIndex ); + } + mHasBeenUpdated = true; } -} -void RenderGeometry::DisableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& program ) -{ - OwnerContainer< RenderPropertyBuffer* >::Iterator it = mVertexBuffers.Begin(); - OwnerContainer< RenderPropertyBuffer* >::ConstIterator end = mVertexBuffers.End(); - for( ; it != end; ++it ) + //Bind buffers to attribute locations + unsigned int base = 0; + for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i ) { - (*it)->DisableVertexAttributes( context, bufferIndex, program ); + mVertexBuffers[i]->BindBuffer( context ); + base += mVertexBuffers[i]->EnableVertexAttributes( context, bufferIndex, attributeLocation, base ); } -} -void RenderGeometry::Draw( Context& context, BufferIndex bufferIndex, const RenderDataProvider* dataProvider ) -{ - const GeometryDataProvider& geometry = dataProvider->GetGeometry(); - const PropertyBufferDataProvider* indexBuffer = dataProvider->GetIndexBuffer(); - - GeometryDataProvider::GeometryType type = geometry.GetGeometryType( bufferIndex ); + if( mIndexBuffer ) + { + mIndexBuffer->BindBuffer( context ); + } - unsigned int numIndices = 0; - if( indexBuffer ) + //Bind index buffer + unsigned int numIndices(0u); + if( mIndexBuffer ) { - numIndices = indexBuffer->GetDataSize(bufferIndex) / indexBuffer->GetElementSize(bufferIndex); + const PropertyBufferDataProvider& indexBuffer = mIndexBuffer->GetDataProvider(); + numIndices = mIndexBuffer->GetDataProvider().GetDataSize(bufferIndex) / indexBuffer.GetElementSize(bufferIndex); } + //Draw call + GeometryDataProvider::GeometryType type = mGeometryDataProvider.GetGeometryType( bufferIndex ); switch(type) { case Dali::Geometry::TRIANGLES: @@ -196,8 +167,8 @@ void RenderGeometry::Draw( Context& context, BufferIndex bufferIndex, const Rend } else { - const PropertyBufferDataProvider* firstVertexBuffer = dataProvider->GetVertexBuffers()[0]; - unsigned int numVertices = firstVertexBuffer->GetElementCount( bufferIndex ); + const PropertyBufferDataProvider& firstVertexBuffer = mVertexBuffers[0]->GetDataProvider(); + unsigned int numVertices = firstVertexBuffer.GetElementCount( bufferIndex ); context.DrawArrays( GL_TRIANGLES, 0, numVertices ); } break; @@ -210,16 +181,16 @@ void RenderGeometry::Draw( Context& context, BufferIndex bufferIndex, const Rend } else { - const PropertyBufferDataProvider* firstVertexBuffer = dataProvider->GetVertexBuffers()[0]; - unsigned int numVertices = firstVertexBuffer->GetElementCount( bufferIndex ); + const PropertyBufferDataProvider& firstVertexBuffer = mVertexBuffers[0]->GetDataProvider(); + unsigned int numVertices = firstVertexBuffer.GetElementCount( bufferIndex ); context.DrawArrays( GL_LINES, 0, numVertices ); } break; } case Dali::Geometry::POINTS: { - const PropertyBufferDataProvider* firstVertexBuffer = dataProvider->GetVertexBuffers()[0]; - unsigned int numVertices = firstVertexBuffer->GetElementCount( bufferIndex ); + const PropertyBufferDataProvider& firstVertexBuffer = mVertexBuffers[0]->GetDataProvider(); + unsigned int numVertices = firstVertexBuffer.GetElementCount( bufferIndex ); context.DrawArrays(GL_POINTS, 0, numVertices ); break; } @@ -229,6 +200,15 @@ void RenderGeometry::Draw( Context& context, BufferIndex bufferIndex, const Rend break; } } + + //Disable atrributes + for( unsigned int i = 0; i < attributeLocation.Count(); ++i ) + { + if( attributeLocation[i] != -1 ) + { + context.DisableVertexAttributeArray( attributeLocation[i] ); + } + } } } // namespace SceneGraph diff --git a/dali/internal/render/renderers/render-geometry.h b/dali/internal/render/renderers/render-geometry.h index cfcf85b..80aba88 100644 --- a/dali/internal/render/renderers/render-geometry.h +++ b/dali/internal/render/renderers/render-geometry.h @@ -38,6 +38,11 @@ namespace SceneGraph class RenderDataProvider; class GeometryDataProvider; +typedef OwnerPointer< RenderPropertyBuffer > RenderPropertyBufferPtr; +typedef OwnerContainer< RenderPropertyBuffer* > RenderPropertyBufferContainer; +typedef RenderPropertyBufferContainer::Iterator RenderPropertyBufferIter; + + /** * This class encapsulates the GPU buffers. It is used to upload vertex data * to it's GPU buffers, to bind all the buffers and to setup/teardown vertex attribute @@ -50,7 +55,7 @@ public: /** * Constructor. Creates a render geometry object with no GPU buffers. */ - RenderGeometry( ); + RenderGeometry( const GeometryDataProvider& geometryDataProvider ); /** * Destructor @@ -68,92 +73,63 @@ public: void GlContextDestroyed(); /** - * Upload the geometry if it has changed, set up the attributes and perform - * the Draw call corresponding to the geometry type - * @param[in] context The GL context - * @param[in] program The shader program to query for attribute locations - * @param[in] bufferIndex The current buffer index - * @param[in] dataProviders The data providers (to fetch geometry from) + * Adds a property buffer to the geometry + * @param[in] dataProvider The PropertyBuffer data provider + * @param[in] gpuBufferTarget target Specifies the type of the buffer + * @param[in] gpuBufferUsage usage Specifies how will the buffer be used */ - void UploadAndDraw(Context& context, - Program& program, - BufferIndex bufferIndex, - const RenderDataProvider* dataProviders ); + void AddPropertyBuffer( const PropertyBufferDataProvider* dataProvider, GpuBuffer::Target gpuBufferTarget, GpuBuffer::Usage gpuBufferUsage ); /** - * Tell the object that the geometry has been updated. - * It will be uploaded on the next UploadAndDraw call. + * Removes a PropertyBuffer from the geometry + * @param[in] dataProvider The property buffer to be removed */ - void GeometryUpdated(); + void RemovePropertyBuffer( const PropertyBufferDataProvider* dataProvider ); /** - * Upload the vertex data if it needs uploading. - * @param[in] context The GL context + * Gets the attribute locations on the shader for the attributes defined in the geometry RenderBuffers + * @param[out] attributeLocation The vector where the attributes locations will be stored + * @param[in] program The program * @param[in] bufferIndex The current buffer index - * @param[in] geometryDataProvider The geometry data provider (to fetch geometry from) */ - void UploadVertexData( Context& context, - Program& program, - BufferIndex bufferIndex, - const RenderDataProvider* dataProviders ); + void GetAttributeLocationFromProgram( Vector& attributeLocation, Program& program, BufferIndex bufferIndex ) const; -private: /** - * Perform the upload of the geometry - * @param[in] context The GL context - * @param[in] bufferIndex The current buffer index - * @param[in] dataProviders The data providers (to fetch geometry from) + * Called from RenderManager to notify the geometry that current rendering pass has finished. */ - void SetUpPropertyBuffers( Context& context, - BufferIndex bufferIndex, - const RenderDataProvider* dataProviders ); + void OnRenderFinished(); /** - * Bind the geometry buffers - * @param[in] context The GL context - * @param[in] bufferIndex The current buffer index - * @param[in] program The shader program to query for attribute locations + * Chack if the attributes for the geometry have changed + * @return True if vertex buffers have been added or removed since last frame, false otherwise */ - void BindBuffers( Context& context, - BufferIndex bufferIndex, - Program& program ); + bool AttributesChanged() const + { + return mAttributesChanged; + } /** - * Enable the vertex attributes for each vertex buffer from the corresponding - * shader program. + * Upload the geometry if it has changed, set up the attributes and perform + * the Draw call corresponding to the geometry type * @param[in] context The GL context * @param[in] bufferIndex The current buffer index - * @param[in] program The shader program to query for attribute locations + * @param[in] attributeLocation The location for the attributes in the shader */ - void EnableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& progam ); + void UploadAndDraw(Context& context, + BufferIndex bufferIndex, + Vector& attributeLocation ); - /** - * Disable the vertex attributes for each vertex buffer from the corresponding - * shader program. - * @param[in] context The GL context - * @param[in] bufferIndex The current buffer index - * @param[in] program The shader program to query for attribute locations - */ - void DisableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& program ); +private: - /** - * Perform the correct draw call corresponding to the geometry type - * @param[in] context The GL context - * @param[in] bufferIndex The current buffer index - * @param[in] dataProviders The data providers (to fetch geometry from) - */ - void Draw( Context& context, - BufferIndex bufferIndex, - const RenderDataProvider* dataProviders ); + const GeometryDataProvider& mGeometryDataProvider; //Reference to update thread object -private: // PropertyBuffers - OwnerPointer< RenderPropertyBuffer > mIndexBuffer; - OwnerContainer< RenderPropertyBuffer* > mVertexBuffers; + RenderPropertyBufferPtr mIndexBuffer; + RenderPropertyBufferContainer mVertexBuffers; // Booleans - bool mDataNeedsUploading; - bool mShaderChanged; + bool mHasBeenUpdated : 1; + bool mAttributesChanged : 1; }; } // namespace SceneGraph diff --git a/dali/internal/render/renderers/render-renderer-property-buffer.cpp b/dali/internal/render/renderers/render-renderer-property-buffer.cpp index 0727a6b..dfceae9 100644 --- a/dali/internal/render/renderers/render-renderer-property-buffer.cpp +++ b/dali/internal/render/renderers/render-renderer-property-buffer.cpp @@ -150,61 +150,57 @@ RenderPropertyBuffer::~RenderPropertyBuffer() { } -void RenderPropertyBuffer::Upload( Context& context, BufferIndex bufferIndex ) +void RenderPropertyBuffer::Update( Context& context, BufferIndex bufferIndex ) { - // Check if we have a gpu-buffer - unsigned int gpuBufferId = 0; // TODO: MESH_REWORK FIX THIS mDataProvider.GetGpuBufferId( bufferIndex ); - if ( ! mGpuBuffer ) + if( !mGpuBuffer || mDataProvider.HasDataChanged( bufferIndex ) ) { - // TODO: MESH_REWORK -// mGpuBuffer /*= gpuBufferCache.GetGpuBuffer( gpuBufferId ) */; - (void )gpuBufferId; - - mGpuBuffer = new GpuBuffer( context, mGpuBufferTarget, mGpuBufferUsage ); - } + if ( ! mGpuBuffer ) + { + mGpuBuffer = new GpuBuffer( context, mGpuBufferTarget, mGpuBufferUsage ); + } - // Update the GpuBuffer - if ( mGpuBuffer ) - { - std::size_t dataSize = mDataProvider.GetDataSize( bufferIndex ); - DALI_ASSERT_DEBUG( dataSize && "No data in the property buffer!" ); + // Update the GpuBuffer + if ( mGpuBuffer ) + { + std::size_t dataSize = mDataProvider.GetDataSize( bufferIndex ); + DALI_ASSERT_DEBUG( dataSize && "No data in the property buffer!" ); - const void *data = &(mDataProvider.GetData( bufferIndex )[0]); - Vector ushortData; + const void *data = &(mDataProvider.GetData( bufferIndex )[0]); + Vector ushortData; - // Index buffer needs to be unsigned short which is not supported by the property system - if( mGpuBufferTarget == GpuBuffer::ELEMENT_ARRAY_BUFFER ) - { - ushortData.Resize( dataSize ); - const unsigned int* unsignedData = static_cast(data); - unsigned int numberOfElements = dataSize / sizeof(unsigned int); - for( unsigned int i = 0; i < numberOfElements; ++i ) + // Index buffer needs to be unsigned short which is not supported by the property system + if( mGpuBufferTarget == GpuBuffer::ELEMENT_ARRAY_BUFFER ) { - ushortData[i] = unsignedData[i]; + ushortData.Resize( dataSize ); + const unsigned int* unsignedData = static_cast(data); + unsigned int numberOfElements = dataSize / sizeof(unsigned int); + for( unsigned int i = 0; i < numberOfElements; ++i ) + { + ushortData[i] = unsignedData[i]; + } + data = &(ushortData[0]); } - data = &(ushortData[0]); - } - mGpuBuffer->UpdateDataBuffer( dataSize, data ); - mGpuBuffer->SetStride( mDataProvider.GetElementSize( bufferIndex ) ); + mGpuBuffer->UpdateDataBuffer( dataSize, data ); + mGpuBuffer->SetStride( mDataProvider.GetElementSize( bufferIndex ) ); + } } } -void RenderPropertyBuffer::BindBuffer( Context& context, Program& progam ) +void RenderPropertyBuffer::BindBuffer( Context& context ) { mGpuBuffer->Bind(); } -void RenderPropertyBuffer::EnableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& program ) +unsigned int RenderPropertyBuffer::EnableVertexAttributes( Context& context, BufferIndex bufferIndex, Vector& vAttributeLocation, unsigned int locationBase ) { unsigned int attributeCount = mDataProvider.GetAttributeCount( bufferIndex ); - DALI_ASSERT_DEBUG( attributeCount == mAttributesLocation.Size() && "Incorrect number of attributes!" ); GLsizei elementSize = mDataProvider.GetElementSize( bufferIndex ); for( unsigned int i = 0; i < attributeCount; ++i ) { - GLint attributeLocation = mAttributesLocation[i]; + GLint attributeLocation = vAttributeLocation[i+locationBase]; if( attributeLocation != -1 ) { context.EnableVertexAttributeArray( attributeLocation ); @@ -221,19 +217,8 @@ void RenderPropertyBuffer::EnableVertexAttributes( Context& context, BufferIndex elementSize ); } } -} -void RenderPropertyBuffer::DisableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& program ) -{ - unsigned int attributeCount = mDataProvider.GetAttributeCount( bufferIndex ); - for( unsigned int i = 0; i < attributeCount; ++i ) - { - GLint attributeLocation = mAttributesLocation[i]; - if( attributeLocation != -1 ) - { - context.DisableVertexAttributeArray( attributeLocation ); - } - } + return attributeCount; } void RenderPropertyBuffer::UpdateAttributeLocations( Context& context, BufferIndex bufferIndex, Program& program ) diff --git a/dali/internal/render/renderers/render-renderer-property-buffer.h b/dali/internal/render/renderers/render-renderer-property-buffer.h index c0cf359..a4966fe 100644 --- a/dali/internal/render/renderers/render-renderer-property-buffer.h +++ b/dali/internal/render/renderers/render-renderer-property-buffer.h @@ -60,18 +60,17 @@ public: ~RenderPropertyBuffer(); /** - * Perform the upload of the buffer + * Perform the upload of the buffer only when requiered * @param[in] context The GL context * @param[in] bufferIndex The current buffer index */ - void Upload( Context& context, BufferIndex bufferIndex ); + void Update( Context& context, BufferIndex bufferIndex ); /** * Bind the geometry buffers * @param[in] context The GL context - * @param[in] program The shader program to query for attribute locations */ - void BindBuffer( Context& context, Program& progam ); + void BindBuffer( Context& context ); /** * Enable the vertex attributes for each vertex buffer from the corresponding @@ -79,17 +78,20 @@ public: * @param[in] context The GL context * @param[in] bufferIndex The current buffer index * @param[in] program The shader program to query for attribute locations + * @param[in] vAttributeLocation Vector containing attributes location for current program + * @param[in] locationBase Index in vAttributeLocation corresponding to the first attribute defined by this buffer */ - void EnableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& program ); + unsigned int EnableVertexAttributes( Context& context, BufferIndex bufferIndex, Vector& vAttributeLocation, unsigned int locationBase); /** - * Disable the vertex attributes for each vertex buffer from the corresponding - * shader program. - * @param[in] context The GL context - * @param[in] bufferIndex The current buffer index - * @param[in] program The shader program to query for attribute locations + * Get the data provider for the buffer */ - void DisableVertexAttributes( Context& context, BufferIndex bufferIndex, Program& program ); + const PropertyBufferDataProvider& GetDataProvider() const + { + return mDataProvider; + } + +private: // implementation /** * Update attribute locations diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index 5477ec2..5783f3e 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -32,16 +32,20 @@ namespace SceneGraph { NewRenderer* NewRenderer::New( NodeDataProvider& nodeDataProvider, - RenderDataProvider* dataProvider ) + RenderDataProvider* dataProvider, + RenderGeometry* renderGeometry ) { - return new NewRenderer(nodeDataProvider, dataProvider); + return new NewRenderer(nodeDataProvider, dataProvider, renderGeometry); } NewRenderer::NewRenderer( NodeDataProvider& nodeDataProvider, - RenderDataProvider* dataProvider ) + RenderDataProvider* dataProvider, + RenderGeometry* renderGeometry ) : Renderer( nodeDataProvider ), - mRenderDataProvider( dataProvider ) + mRenderDataProvider( dataProvider ), + mRenderGeometry( renderGeometry ), + mUpdateAttributesLocation( true ) { } @@ -52,12 +56,13 @@ NewRenderer::~NewRenderer() void NewRenderer::SetRenderDataProvider( RenderDataProvider* dataProvider ) { mRenderDataProvider = dataProvider; - mRenderGeometry.GeometryUpdated(); + mUpdateAttributesLocation = true; } -void NewRenderer::SetGeometryUpdated( ) +void NewRenderer::SetGeometry( RenderGeometry* renderGeometry ) { - mRenderGeometry.GeometryUpdated(); + mRenderGeometry = renderGeometry; + mUpdateAttributesLocation = true; } // Note - this is currently called from UpdateThread, PrepareRenderInstructions, @@ -121,12 +126,18 @@ void NewRenderer::DoRender( Context& context, TextureCache& textureCache, Buffer SetUniforms( bufferIndex, program ); - mRenderGeometry.UploadAndDraw( context, program, bufferIndex, mRenderDataProvider.Get() ); + if( mUpdateAttributesLocation || mRenderGeometry->AttributesChanged() ) + { + mRenderGeometry->GetAttributeLocationFromProgram( mAttributesLocation, program, bufferIndex ); + mUpdateAttributesLocation = false; + } + + mRenderGeometry->UploadAndDraw( context, bufferIndex, mAttributesLocation ); } void NewRenderer::GlContextDestroyed() { - mRenderGeometry.GlContextDestroyed(); + mRenderGeometry->GlContextDestroyed(); } void NewRenderer::GlCleanup() diff --git a/dali/internal/render/renderers/render-renderer.h b/dali/internal/render/renderers/render-renderer.h index 997dba4..4756ea0 100644 --- a/dali/internal/render/renderers/render-renderer.h +++ b/dali/internal/render/renderers/render-renderer.h @@ -49,14 +49,16 @@ public: * Create a new renderer instance * @param[in] nodeDataProvider The node data provider * @param[in] dataProviders The data providers for the renderer + * @param[in] renderGeometry The geometry for the renderer */ - static NewRenderer* New( NodeDataProvider& nodeDataProvider, RenderDataProvider* dataProviders ); + static NewRenderer* New( NodeDataProvider& nodeDataProvider, RenderDataProvider* dataProviders, RenderGeometry* renderGeometry ); /** * Constructor. * @param[in] nodeDataProvider The node data provider * @param[in] dataProviders The data providers for the renderer + * @param[in] renderGeometry The geometry for the renderer */ - NewRenderer( NodeDataProvider& nodeDataProvider, RenderDataProvider* dataProviders ); + NewRenderer( NodeDataProvider& nodeDataProvider, RenderDataProvider* dataProviders, RenderGeometry* renderGeometry ); virtual ~NewRenderer(); @@ -67,9 +69,10 @@ public: void SetRenderDataProvider( RenderDataProvider* dataProviders ); /** - * Set flag that says that Geometry has been updated. + * Change the geometry used by the renderer + * @param[in] renderGeometry The new geometry */ - void SetGeometryUpdated(); + void SetGeometry( RenderGeometry* renderGeometry ); public: // Implementation of Renderer /** @@ -195,7 +198,7 @@ public: //@todo MESH_REWORK make private after merge with SceneGraph::Renderer OwnerPointer< RenderDataProvider > mRenderDataProvider; private: - RenderGeometry mRenderGeometry; + RenderGeometry* mRenderGeometry; struct TextureUnitUniformIndex { @@ -214,6 +217,9 @@ private: typedef Dali::Vector< UniformIndexMap > UniformIndexMappings; UniformIndexMappings mUniformIndexMap; + + Vector mAttributesLocation; + bool mUpdateAttributesLocation; }; diff --git a/dali/internal/update/controllers/render-message-dispatcher.cpp b/dali/internal/update/controllers/render-message-dispatcher.cpp index 4a2d07d..ec1a2eb 100644 --- a/dali/internal/update/controllers/render-message-dispatcher.cpp +++ b/dali/internal/update/controllers/render-message-dispatcher.cpp @@ -65,6 +65,50 @@ void RenderMessageDispatcher::RemoveRenderer( Renderer& renderer ) new (slot) DerivedType( &mRenderManager, &RenderManager::RemoveRenderer, &renderer ); } +void RenderMessageDispatcher::AddGeometry( RenderGeometry& renderGeometry ) +{ + typedef MessageValue1< RenderManager, RenderGeometry* > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mRenderQueue.ReserveMessageSlot( mBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mRenderManager, &RenderManager::AddGeometry, &renderGeometry ); +} + +void RenderMessageDispatcher::RemoveGeometry( RenderGeometry& renderGeometry ) +{ + typedef MessageValue1< RenderManager, RenderGeometry* > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mRenderQueue.ReserveMessageSlot( mBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mRenderManager, &RenderManager::RemoveGeometry, &renderGeometry ); +} + +void RenderMessageDispatcher::AddPropertyBuffer( RenderGeometry& renderGeometry, PropertyBufferDataProvider* propertyBuffer, GpuBuffer::Target target, GpuBuffer::Usage usage ) +{ + typedef MessageValue4< RenderManager, RenderGeometry*, PropertyBufferDataProvider*, GpuBuffer::Target, GpuBuffer::Usage > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mRenderQueue.ReserveMessageSlot( mBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mRenderManager, &RenderManager::AddPropertyBuffer, &renderGeometry, propertyBuffer, target, usage ); +} + +void RenderMessageDispatcher::RemovePropertyBuffer( RenderGeometry& renderGeometry, PropertyBufferDataProvider* propertyBuffer ) +{ + typedef MessageValue2< RenderManager, RenderGeometry*, PropertyBufferDataProvider* > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mRenderQueue.ReserveMessageSlot( mBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mRenderManager, &RenderManager::RemovePropertyBuffer, &renderGeometry, propertyBuffer ); +} + void RenderMessageDispatcher::AddRenderTracker( RenderTracker& renderTracker ) { typedef MessageValue1< RenderManager, RenderTracker* > DerivedType; diff --git a/dali/internal/update/controllers/render-message-dispatcher.h b/dali/internal/update/controllers/render-message-dispatcher.h index 654d7b7..7980606 100644 --- a/dali/internal/update/controllers/render-message-dispatcher.h +++ b/dali/internal/update/controllers/render-message-dispatcher.h @@ -20,6 +20,7 @@ // INTERNAL INCLUDES #include +#include namespace Dali { @@ -34,7 +35,8 @@ class Renderer; class RenderManager; class RenderQueue; class RenderTracker; - +class RenderGeometry; +class PropertyBufferDataProvider; /** * A utility class for sending messages to the render-thread. */ @@ -61,13 +63,43 @@ public: /** * Remove a Renderer. - * @param[in] updateBufferIndex The current buffer index. * @param[in] renderer The renderer to remove. * @post renderer will be destroyed in the next Render. */ void RemoveRenderer( Renderer& renderer ); /** + * Add a Geometry + * @param[in] renderGeometry The geometry to add. + * @post RenderGeometry ownership is transferred. + */ + void AddGeometry( RenderGeometry& renderGeometry ); + + /** + * Remove a Geometry. + * @param[in] renderGeometry The geometry to remove. + * @post RenderGeometry will be destroyed in the next Render. + */ + void RemoveGeometry( RenderGeometry& renderGeometry ); + + /** + * Add a PropertyBuffer. + * @param[in] renderGeometry The geometry + * @param[in] propertyBuffer The PropertyBuffer + * @param[in] target Specifies the type of the buffer + * @param[in] usage Specifies how will the buffer be used + */ + void AddPropertyBuffer( RenderGeometry& renderGeometry, PropertyBufferDataProvider* propertyBuffer, GpuBuffer::Target target, GpuBuffer::Usage usage ); + + /** + * Remove a PropertyBuffer. + * @param[in] renderGeometry The geometry + * @param[in] propertyBuffer The PropertyBuffer + * @post PropertyBuffer will be destroyed in the next Render. + */ + void RemovePropertyBuffer( RenderGeometry& renderGeometry, PropertyBufferDataProvider* propertyBuffer ); + + /** * Add a Render tracker. * @param[in] renderTracker The render tracker to add. * @post ownership is transferred diff --git a/dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp b/dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp index e022fd4..abbe7e1 100644 --- a/dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp +++ b/dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp @@ -69,6 +69,7 @@ RendererAttachment::RendererAttachment() mGeometry(NULL), mRegenerateUniformMap(REGENERATE_UNIFORM_MAP), mResendDataProviders(false), + mResendGeometry(false), mDepthIndex(0) { mUniformMapChanged[0]=false; @@ -111,7 +112,8 @@ void RendererAttachment::ConnectedToSceneGraph() RenderDataProvider* dataProvider = NewRenderDataProvider(); - mRenderer = NewRenderer::New( *mParent, dataProvider ); + RenderGeometry* renderGeometry = mGeometry->GetRenderGeometry(mSceneController); + mRenderer = NewRenderer::New( *mParent, dataProvider, renderGeometry ); mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer ); } @@ -120,6 +122,8 @@ void RendererAttachment::DisconnectedFromSceneGraph() mRegenerateUniformMap = 0; mParent->RemoveUniformMapObserver( *this ); + mGeometry->OnRendererDisconnect(); + DALI_ASSERT_DEBUG( mSceneController ); mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer ); mRenderer = NULL; @@ -144,12 +148,20 @@ Material& RendererAttachment::GetMaterial() void RendererAttachment::SetGeometry( BufferIndex updateBufferIndex, Geometry* geometry) { DALI_ASSERT_DEBUG( geometry != NULL && "Geometry pointer is NULL"); + if( mGeometry) + { + mGeometry->RemoveConnectionObserver(*this); + mGeometry->OnRendererDisconnect(); + } mGeometry = geometry; mGeometry->AddConnectionObserver( *this ); // Observe geometry connections / uniform mapping changes mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; - mResendDataProviders = true; + if( mRenderer ) + { + mResendGeometry = true; + } } Geometry& RendererAttachment::GetGeometry() @@ -372,27 +384,6 @@ void RendererAttachment::DoPrepareRender( BufferIndex updateBufferIndex ) mRegenerateUniformMap--; } - bool geometryDataChanged = false; - if( PropertyBuffer* indexBuffer = mGeometry->GetIndexBuffer() ) - { - geometryDataChanged = indexBuffer->HasDataChanged(updateBufferIndex); - } - Vector& vertexBuffers = mGeometry->GetVertexBuffers(); - Vector::ConstIterator end = vertexBuffers.End(); - for( Vector::Iterator it = vertexBuffers.Begin(); - it != end; - ++it ) - { - geometryDataChanged = geometryDataChanged || (*it)->HasDataChanged(updateBufferIndex); - } - if( geometryDataChanged ) - { - //TODO: MESH_REWORK : use buffer data cache and remove all this - typedef Message< NewRenderer > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &NewRenderer::SetGeometryUpdated ); - } - if( mResendDataProviders ) { RenderDataProvider* dataProvider = NewRenderDataProvider(); @@ -405,6 +396,16 @@ void RendererAttachment::DoPrepareRender( BufferIndex updateBufferIndex ) new (slot) DerivedType( mRenderer, &NewRenderer::SetRenderDataProvider, dataProvider ); mResendDataProviders = false; } + + if( mResendGeometry ) + { + typedef MessageValue1< NewRenderer, RenderGeometry* > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + + new (slot) DerivedType( mRenderer, &NewRenderer::SetGeometry,mGeometry->GetRenderGeometry(mSceneController) ); + mResendGeometry = false; + + } } @@ -489,21 +490,9 @@ RenderDataProvider* RendererAttachment::NewRenderDataProvider() { RenderDataProvider* dataProvider = new RenderDataProvider(); - dataProvider->mGeometryDataProvider = mGeometry; dataProvider->mMaterialDataProvider = mMaterial; dataProvider->mUniformMapDataProvider = this; dataProvider->mShader = mMaterial->GetShader(); - dataProvider->mIndexBuffer = mGeometry->GetIndexBuffer(); - - Vector& vertexBuffers = mGeometry->GetVertexBuffers(); - dataProvider->mVertexBuffers.Reserve( vertexBuffers.Count() ); - - for( Vector::Iterator iter = vertexBuffers.Begin() ; - iter != vertexBuffers.End(); - ++iter ) - { - dataProvider->mVertexBuffers.PushBack(*iter); // Convert from derived type to base type - } Vector& samplers = mMaterial->GetSamplers(); dataProvider->mSamplers.Reserve( samplers.Count() ); diff --git a/dali/internal/update/node-attachments/scene-graph-renderer-attachment.h b/dali/internal/update/node-attachments/scene-graph-renderer-attachment.h index 2c93f40..b7c4e7a 100644 --- a/dali/internal/update/node-attachments/scene-graph-renderer-attachment.h +++ b/dali/internal/update/node-attachments/scene-graph-renderer-attachment.h @@ -230,9 +230,10 @@ private: Geometry* mGeometry; ///< The geometry this renderer uses. (Not owned) CollectedUniformMap mCollectedUniformMap[2]; - int mRegenerateUniformMap; ///< 2 if the map should be regenerated, 1 if it should be copied. - bool mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame - bool mResendDataProviders; ///< True if the data providers should be resent to the renderer + int mRegenerateUniformMap; ///< 2 if the map should be regenerated, 1 if it should be copied. + bool mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame + bool mResendDataProviders : 1; ///< True if the data providers should be resent to the renderer + bool mResendGeometry : 1; ///< True if geometry should be resent to the renderer public: // Properties diff --git a/dali/internal/update/rendering/scene-graph-geometry.cpp b/dali/internal/update/rendering/scene-graph-geometry.cpp index 6dd928d..59c16e8 100644 --- a/dali/internal/update/rendering/scene-graph-geometry.cpp +++ b/dali/internal/update/rendering/scene-graph-geometry.cpp @@ -14,8 +14,14 @@ * limitations under the License. */ +// CLASS HEADER #include "scene-graph-geometry.h" +// INTERNAL HEADERS +#include +#include +#include + namespace Dali { namespace Internal @@ -25,6 +31,9 @@ namespace SceneGraph Geometry::Geometry() : mIndexBuffer( NULL ), + mRenderGeometry(0), + mSceneController(0), + mRendererRefCount(0u), mCenter(), mHalfExtents(), mRadius( 0.0f ), @@ -49,6 +58,11 @@ void Geometry::AddVertexBuffer( PropertyBuffer* vertexBuffer ) CalculateExtents( vertexBuffer ); vertexBuffer->AddUniformMapObserver(*this); mConnectionObservers.ConnectionsChanged(*this); + + if( mRenderGeometry ) + { + mSceneController->GetRenderMessageDispatcher().AddPropertyBuffer( *mRenderGeometry, vertexBuffer, GpuBuffer::ARRAY_BUFFER, GpuBuffer::STATIC_DRAW ); + } } void Geometry::RemoveVertexBuffer( PropertyBuffer* vertexBuffer ) @@ -67,6 +81,11 @@ void Geometry::RemoveVertexBuffer( PropertyBuffer* vertexBuffer ) vertexBuffer->RemoveUniformMapObserver(*this); mVertexBuffers.Erase( match ); mConnectionObservers.ConnectionsChanged(*this); + + if( mRenderGeometry ) + { + mSceneController->GetRenderMessageDispatcher().RemovePropertyBuffer( *mRenderGeometry, vertexBuffer ); + } } } @@ -77,15 +96,24 @@ void Geometry::SetIndexBuffer( PropertyBuffer* indexBuffer ) mIndexBuffer = indexBuffer; indexBuffer->AddUniformMapObserver(*this); mConnectionObservers.ConnectionsChanged(*this); + + if( mRenderGeometry ) + { + mSceneController->GetRenderMessageDispatcher().AddPropertyBuffer( *mRenderGeometry, indexBuffer, GpuBuffer::ELEMENT_ARRAY_BUFFER, GpuBuffer::STATIC_DRAW ); + } } } void Geometry::ClearIndexBuffer() { - // @todo Actually delete, or put on Discard Queue and tell Renderer in render thread? if( mIndexBuffer ) { mIndexBuffer->RemoveUniformMapObserver(*this); + + if( mRenderGeometry ) + { + mSceneController->GetRenderMessageDispatcher().RemovePropertyBuffer( *mRenderGeometry, mIndexBuffer ); + } } mIndexBuffer = 0; mConnectionObservers.ConnectionsChanged(*this); @@ -281,6 +309,47 @@ void Geometry::UniformMappingsChanged( const UniformMap& mappings ) mConnectionObservers.ConnectedUniformMapChanged(); } +RenderGeometry* Geometry::GetRenderGeometry(SceneController* sceneController) +{ + if(!mRenderGeometry) + { + //Create RenderGeometry + mSceneController = sceneController; + mRenderGeometry = new RenderGeometry( *this ); + + size_t vertexBufferCount( mVertexBuffers.Size() ); + for( size_t i(0); iAddPropertyBuffer( mVertexBuffers[i], GpuBuffer::ARRAY_BUFFER, GpuBuffer::STATIC_DRAW ); + } + + if( mIndexBuffer ) + { + mRenderGeometry->AddPropertyBuffer( mIndexBuffer, GpuBuffer::ELEMENT_ARRAY_BUFFER, GpuBuffer::STATIC_DRAW ); + } + + //Transfer ownership to RenderManager + sceneController->GetRenderMessageDispatcher().AddGeometry( *mRenderGeometry ); + } + + ++mRendererRefCount; + return mRenderGeometry; +} + +void Geometry::OnRendererDisconnect() +{ + --mRendererRefCount; + if( mRendererRefCount == 0 ) + { + //Delete the corresponding RenderGeometry via message to RenderManager + mSceneController->GetRenderMessageDispatcher().RemoveGeometry( *mRenderGeometry ); + + mRenderGeometry = 0; + mSceneController = 0; + } +} + + } // namespace SceneGraph } // namespace Internal } // namespace Dali diff --git a/dali/internal/update/rendering/scene-graph-geometry.h b/dali/internal/update/rendering/scene-graph-geometry.h index 6a7911c..5f6d02b 100644 --- a/dali/internal/update/rendering/scene-graph-geometry.h +++ b/dali/internal/update/rendering/scene-graph-geometry.h @@ -37,6 +37,7 @@ namespace Internal namespace SceneGraph { class SceneController; +class RenderGeometry; /** * This scene graph object is a property owner. It describes a geometry using a @@ -129,6 +130,19 @@ public: // UniformMap::Observer */ PropertyBuffer* GetIndexBuffer(); + /** + * Gets the associated RenderGeometry + * @param[in] sceneController The scene controller + * @return The RenderGeometry associated to this Geometry + */ + RenderGeometry* GetRenderGeometry(SceneController* sceneController); + + /** + * Called from renderers using this geometry when they get disconnected from the scenegraph + */ + void OnRendererDisconnect(); + + public: // GeometryDataProvider /** * Get the type of geometry to draw @@ -162,6 +176,10 @@ private: PropertyBuffer* mIndexBuffer; ///< The index buffer if required ConnectionChangePropagator mConnectionObservers; + RenderGeometry* mRenderGeometry; + SceneController* mSceneController; + unsigned int mRendererRefCount; + public: // Properties AnimatableProperty mCenter; AnimatableProperty mHalfExtents;