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;
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 );
}
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)
{
connector.Set( vertexBuffer, OnStage() );
mVertexBufferConnectors.push_back( connector );
- const SceneGraph::PropertyBuffer& sceneGraphPropertyBuffer = dynamic_cast<const SceneGraph::PropertyBuffer&>( *vertexBuffer.GetSceneObject() );
+ const SceneGraph::PropertyBuffer& sceneGraphPropertyBuffer = static_cast<const SceneGraph::PropertyBuffer&>( *vertexBuffer.GetSceneObject() );
SceneGraph::AddVertexBufferMessage( GetEventThreadServices(), *mSceneObject, sceneGraphPropertyBuffer );
void Geometry::RemoveVertexBuffer( std::size_t index )
{
+ const SceneGraph::PropertyBuffer& sceneGraphPropertyBuffer = static_cast<const SceneGraph::PropertyBuffer&>( *(mVertexBufferConnectors[index].Get()->GetSceneObject()) );
+ SceneGraph::RemoveVertexBufferMessage( GetEventThreadServices(), *mSceneObject, sceneGraphPropertyBuffer );
+
mVertexBufferConnectors.erase( mVertexBufferConnectors.begin() + index );
}
#include <dali/internal/render/gl-resources/native-frame-buffer-texture.h>
#include <dali/internal/render/gl-resources/texture-cache.h>
#include <dali/internal/render/renderers/scene-graph-renderer.h>
+#include <dali/internal/render/renderers/render-geometry.h>
#include <dali/internal/render/shaders/program-controller.h>
// Uncomment the next line to enable frame snapshot logging
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;
// 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<int> defaultSurfaceRect; ///< Rectangle for the default surface we are rendering to
+ Rect<int> 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 )
}
}
+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);
// 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
#include <dali/public-api/math/rect.h>
#include <dali/internal/render/common/post-process-resource-dispatcher.h>
#include <dali/internal/update/resources/resource-manager-declarations.h>
+#include <dali/internal/render/gl-resources/gpu-buffer.h>
namespace Dali
{
class RenderInstructionContainer;
class RenderTracker;
class Shader;
+class RenderGeometry;
+class PropertyBufferDataProvider;
/**
* RenderManager is responsible for rendering the result of the previous "update", which
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.
*/
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
{
RenderDataProvider::RenderDataProvider()
-: mGeometryDataProvider( NULL ),
- mMaterialDataProvider( NULL ),
+: mMaterialDataProvider( NULL ),
mUniformMapDataProvider( NULL ),
- mShader( NULL ),
- mIndexBuffer( NULL )
+ mShader( NULL )
{
}
{
}
-void RenderDataProvider::SetGeometry( const GeometryDataProvider& geometryDataProvider )
-{
- mGeometryDataProvider = &geometryDataProvider;
-}
-
-const GeometryDataProvider& RenderDataProvider::GetGeometry() const
-{
- return *mGeometryDataProvider;
-}
-
void RenderDataProvider::SetMaterial( const MaterialDataProvider& materialDataProvider )
{
mMaterialDataProvider = &materialDataProvider;
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;
~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
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
*/
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.
namespace SceneGraph
{
-RenderGeometry::RenderGeometry()
-: mDataNeedsUploading( true ),
- mShaderChanged( true )
+RenderGeometry::RenderGeometry( const GeometryDataProvider& geometryDataProvider )
+: mGeometryDataProvider( geometryDataProvider ),
+ mHasBeenUpdated(false),
+ mAttributesChanged(true)
{
}
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<GLint>& 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; i<vertexBuffers.Count(); ++i)
+ for( size_t i(0); i< mVertexBuffers.Size(); ++i )
{
- const PropertyBufferDataProvider* vertexBuffer = vertexBuffers[i];
-
- RenderPropertyBuffer* propertyBuffer = new RenderPropertyBuffer(
- *vertexBuffer,
- GpuBuffer::ARRAY_BUFFER,
- GpuBuffer::STATIC_DRAW ); // TODO: MESH_REWORK: change this for animated meshes
+ unsigned int attributeCount = mVertexBuffers[i]->GetDataProvider().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<GLint>& 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:
}
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;
}
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;
}
break;
}
}
+
+ //Disable atrributes
+ for( unsigned int i = 0; i < attributeLocation.Count(); ++i )
+ {
+ if( attributeLocation[i] != -1 )
+ {
+ context.DisableVertexAttributeArray( attributeLocation[i] );
+ }
+ }
}
} // 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
/**
* Constructor. Creates a render geometry object with no GPU buffers.
*/
- RenderGeometry( );
+ RenderGeometry( const GeometryDataProvider& geometryDataProvider );
/**
* Destructor
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<GLint>& 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<GLint>& 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
{
}
-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<unsigned short> ushortData;
+ const void *data = &(mDataProvider.GetData( bufferIndex )[0]);
+ Vector<unsigned short> 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<const unsigned int*>(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<const unsigned int*>(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<GLint>& 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 );
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 )
~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
* @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<GLint>& 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
{
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 )
{
}
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,
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()
* 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();
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
/**
OwnerPointer< RenderDataProvider > mRenderDataProvider;
private:
- RenderGeometry mRenderGeometry;
+ RenderGeometry* mRenderGeometry;
struct TextureUnitUniformIndex
{
typedef Dali::Vector< UniformIndexMap > UniformIndexMappings;
UniformIndexMappings mUniformIndexMap;
+
+ Vector<GLint> mAttributesLocation;
+ bool mUpdateAttributesLocation;
};
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;
// INTERNAL INCLUDES
#include <dali/internal/update/common/scene-graph-buffers.h>
+#include <dali/internal/render/gl-resources/gpu-buffer.h>
namespace Dali
{
class RenderManager;
class RenderQueue;
class RenderTracker;
-
+class RenderGeometry;
+class PropertyBufferDataProvider;
/**
* A utility class for sending messages to the render-thread.
*/
/**
* 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
mGeometry(NULL),
mRegenerateUniformMap(REGENERATE_UNIFORM_MAP),
mResendDataProviders(false),
+ mResendGeometry(false),
mDepthIndex(0)
{
mUniformMapChanged[0]=false;
RenderDataProvider* dataProvider = NewRenderDataProvider();
- mRenderer = NewRenderer::New( *mParent, dataProvider );
+ RenderGeometry* renderGeometry = mGeometry->GetRenderGeometry(mSceneController);
+ mRenderer = NewRenderer::New( *mParent, dataProvider, renderGeometry );
mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer );
}
mRegenerateUniformMap = 0;
mParent->RemoveUniformMapObserver( *this );
+ mGeometry->OnRendererDisconnect();
+
DALI_ASSERT_DEBUG( mSceneController );
mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer );
mRenderer = NULL;
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()
mRegenerateUniformMap--;
}
- bool geometryDataChanged = false;
- if( PropertyBuffer* indexBuffer = mGeometry->GetIndexBuffer() )
- {
- geometryDataChanged = indexBuffer->HasDataChanged(updateBufferIndex);
- }
- Vector<PropertyBuffer*>& vertexBuffers = mGeometry->GetVertexBuffers();
- Vector<PropertyBuffer*>::ConstIterator end = vertexBuffers.End();
- for( Vector<PropertyBuffer*>::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();
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;
+
+ }
}
{
RenderDataProvider* dataProvider = new RenderDataProvider();
- dataProvider->mGeometryDataProvider = mGeometry;
dataProvider->mMaterialDataProvider = mMaterial;
dataProvider->mUniformMapDataProvider = this;
dataProvider->mShader = mMaterial->GetShader();
- dataProvider->mIndexBuffer = mGeometry->GetIndexBuffer();
-
- Vector<PropertyBuffer*>& vertexBuffers = mGeometry->GetVertexBuffers();
- dataProvider->mVertexBuffers.Reserve( vertexBuffers.Count() );
-
- for( Vector<PropertyBuffer*>::Iterator iter = vertexBuffers.Begin() ;
- iter != vertexBuffers.End();
- ++iter )
- {
- dataProvider->mVertexBuffers.PushBack(*iter); // Convert from derived type to base type
- }
Vector<Sampler*>& samplers = mMaterial->GetSamplers();
dataProvider->mSamplers.Reserve( samplers.Count() );
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
* limitations under the License.
*/
+// CLASS HEADER
#include "scene-graph-geometry.h"
+// INTERNAL HEADERS
+#include <dali/internal/update/controllers/scene-controller.h>
+#include <dali/internal/render/renderers/render-geometry.h>
+#include <dali/internal/update/controllers/render-message-dispatcher.h>
+
namespace Dali
{
namespace Internal
Geometry::Geometry()
: mIndexBuffer( NULL ),
+ mRenderGeometry(0),
+ mSceneController(0),
+ mRendererRefCount(0u),
mCenter(),
mHalfExtents(),
mRadius( 0.0f ),
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 )
vertexBuffer->RemoveUniformMapObserver(*this);
mVertexBuffers.Erase( match );
mConnectionObservers.ConnectionsChanged(*this);
+
+ if( mRenderGeometry )
+ {
+ mSceneController->GetRenderMessageDispatcher().RemovePropertyBuffer( *mRenderGeometry, vertexBuffer );
+ }
}
}
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);
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); i<vertexBufferCount; ++i )
+ {
+ mRenderGeometry->AddPropertyBuffer( 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
namespace SceneGraph
{
class SceneController;
+class RenderGeometry;
/**
* This scene graph object is a property owner. It describes a geometry using a
*/
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
PropertyBuffer* mIndexBuffer; ///< The index buffer if required
ConnectionChangePropagator mConnectionObservers;
+ RenderGeometry* mRenderGeometry;
+ SceneController* mSceneController;
+ unsigned int mRendererRefCount;
+
public: // Properties
AnimatableProperty<Vector3> mCenter;
AnimatableProperty<Vector3> mHalfExtents;