Allow sharing RenderGeometries across multiple Renderers
[platform/core/uifw/dali-core.git] / dali / internal / update / rendering / scene-graph-geometry.cpp
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