Allow sharing RenderGeometries across multiple Renderers 03/42903/6
authorFerran Sole <ferran.sole@samsung.com>
Fri, 3 Jul 2015 16:26:48 +0000 (17:26 +0100)
committerFerran Sole <ferran.sole@samsung.com>
Fri, 10 Jul 2015 13:25:56 +0000 (06:25 -0700)
Change-Id: I48d337a4d258e067fd5e01ad7075b24984092dcb

20 files changed:
automated-tests/src/dali-devel/utc-Dali-Geometry.cpp
automated-tests/src/dali-devel/utc-Dali-PropertyBuffer.cpp
dali/internal/event/rendering/geometry-impl.cpp
dali/internal/render/common/render-manager.cpp
dali/internal/render/common/render-manager.h
dali/internal/render/data-providers/property-buffer-data-provider.h
dali/internal/render/data-providers/render-data-provider.cpp
dali/internal/render/data-providers/render-data-provider.h
dali/internal/render/renderers/render-geometry.cpp
dali/internal/render/renderers/render-geometry.h
dali/internal/render/renderers/render-renderer-property-buffer.cpp
dali/internal/render/renderers/render-renderer-property-buffer.h
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-renderer.h
dali/internal/update/controllers/render-message-dispatcher.cpp
dali/internal/update/controllers/render-message-dispatcher.h
dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp
dali/internal/update/node-attachments/scene-graph-renderer-attachment.h
dali/internal/update/rendering/scene-graph-geometry.cpp
dali/internal/update/rendering/scene-graph-geometry.h

index 5bb2278..7933b06 100644 (file)
@@ -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 );
   }
 
 
index d1cdd6c..55b3d10 100644 (file)
@@ -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)
 {
index bbed300..60081f2 100644 (file)
@@ -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<const SceneGraph::PropertyBuffer&>( *vertexBuffer.GetSceneObject() );
+  const SceneGraph::PropertyBuffer& sceneGraphPropertyBuffer = static_cast<const SceneGraph::PropertyBuffer&>( *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<const SceneGraph::PropertyBuffer&>( *(mVertexBufferConnectors[index].Get()->GetSceneObject()) );
+  SceneGraph::RemoveVertexBufferMessage( GetEventThreadServices(), *mSceneObject, sceneGraphPropertyBuffer );
+
   mVertexBufferConnectors.erase( mVertexBufferConnectors.begin() + index );
 }
 
index a226306..8d6446d 100644 (file)
@@ -36,6 +36,7 @@
 #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
@@ -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<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 )
@@ -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
index 3c86f3a..5ec8b0d 100644 (file)
@@ -22,6 +22,7 @@
 #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
 {
@@ -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.
index f2a9ba7..61e1e30 100644 (file)
@@ -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
index 8b7cf23..f78af39 100644 (file)
@@ -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;
index ea83092..cf3aeb6 100644 (file)
@@ -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.
index 808854c..2084329 100644 (file)
@@ -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<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:
@@ -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
index cfcf85b..80aba88 100644 (file)
@@ -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<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
index 0727a6b..dfceae9 100644 (file)
@@ -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<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 );
@@ -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 )
index c0cf359..a4966fe 100644 (file)
@@ -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<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
index 5477ec2..5783f3e 100644 (file)
@@ -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()
index 997dba4..4756ea0 100644 (file)
@@ -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<GLint> mAttributesLocation;
+  bool mUpdateAttributesLocation;
 };
 
 
index 4a2d07d..ec1a2eb 100644 (file)
@@ -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;
index 654d7b7..7980606 100644 (file)
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/internal/update/common/scene-graph-buffers.h>
+#include <dali/internal/render/gl-resources/gpu-buffer.h>
 
 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
index e022fd4..abbe7e1 100644 (file)
@@ -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<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();
@@ -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<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() );
index 2c93f40..b7c4e7a 100644 (file)
@@ -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
 
index 6dd928d..59c16e8 100644 (file)
  * 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
@@ -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); 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
index 6a7911c..5f6d02b 100644 (file)
@@ -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<Vector3>   mCenter;
   AnimatableProperty<Vector3>   mHalfExtents;