Merge "Allow multiple renderers per Actor and sharing renderers between actors" into...
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-manager.cpp
index 6806a55..b74f4fd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 // INTERNAL INCLUDES
 #include <dali/public-api/common/stage.h>
-#include <dali/public-api/common/set-wrapper.h>
+#include <dali/devel-api/common/set-wrapper.h>
+#include <dali/devel-api/common/mutex.h>
 
 #include <dali/integration-api/core.h>
 #include <dali/integration-api/render-controller.h>
-#include <dali/integration-api/shader-data.h>
+#include <dali/internal/common/shader-data.h>
 #include <dali/integration-api/debug.h>
 
 #include <dali/internal/common/core-impl.h>
 #include <dali/internal/event/common/notification-manager.h>
 #include <dali/internal/event/common/property-notification-impl.h>
 #include <dali/internal/event/common/property-notifier.h>
+#include <dali/internal/event/effects/shader-factory.h>
 
 #include <dali/internal/update/animation/scene-graph-animator.h>
 #include <dali/internal/update/animation/scene-graph-animation.h>
 #include <dali/internal/update/common/discard-queue.h>
-#include <dali/internal/update/common/double-buffered.h>
+#include <dali/internal/update/common/scene-graph-buffers.h>
+#include <dali/internal/update/common/scene-graph-property-buffer.h>
+#include <dali/internal/update/controllers/render-message-dispatcher.h>
+#include <dali/internal/update/controllers/scene-controller-impl.h>
+#include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
+#include <dali/internal/update/manager/object-owner-container.h>
 #include <dali/internal/update/manager/prepare-render-algorithms.h>
 #include <dali/internal/update/manager/process-render-tasks.h>
-#include <dali/internal/update/resources/resource-manager.h>
-#include <dali/internal/update/resources/complete-status-manager.h>
-#include <dali/internal/update/common/scene-graph-buffers.h>
-#include <dali/internal/update/render-tasks/scene-graph-render-task.h>
-#include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
 #include <dali/internal/update/manager/sorted-layers.h>
 #include <dali/internal/update/manager/update-algorithms.h>
-#include <dali/internal/update/queue/update-message-queue.h>
 #include <dali/internal/update/manager/update-manager-debug.h>
-#include <dali/internal/update/controllers/render-message-dispatcher.h>
-#include <dali/internal/update/controllers/scene-controller-impl.h>
-#include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
-#include <dali/internal/update/modeling/scene-graph-material.h>
 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
+#include <dali/internal/update/node-attachments/scene-graph-image-attachment.h>
 #include <dali/internal/update/nodes/node.h>
 #include <dali/internal/update/nodes/scene-graph-layer.h>
+#include <dali/internal/update/queue/update-message-queue.h>
+#include <dali/internal/update/render-tasks/scene-graph-render-task.h>
+#include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
+#include <dali/internal/update/rendering/scene-graph-material.h>
+#include <dali/internal/update/rendering/scene-graph-sampler.h>
+#include <dali/internal/update/rendering/scene-graph-geometry.h>
+#include <dali/internal/update/resources/resource-manager.h>
+#include <dali/internal/update/resources/complete-status-manager.h>
 #include <dali/internal/update/touch/touch-resampler.h>
 
 #include <dali/internal/render/common/render-instruction-container.h>
 #include <dali/internal/render/queue/render-queue.h>
 #include <dali/internal/render/common/performance-monitor.h>
 #include <dali/internal/render/gl-resources/texture-cache.h>
-#include <dali/internal/render/renderers/render-material.h>
-#include <dali/internal/render/shaders/shader.h>
-
-#ifdef DYNAMICS_SUPPORT
-#include <dali/integration-api/dynamics/dynamics-world-settings.h>
-#include <dali/internal/update/dynamics/scene-graph-dynamics-world.h>
-#endif
+#include <dali/internal/render/shaders/scene-graph-shader.h>
 
 // Un-comment to enable node tree debug logging
 //#define NODE_TREE_LOGGING 1
@@ -111,8 +111,6 @@ namespace SceneGraph
 namespace
 {
 
-const int DEFAULT_CAMERA_INDEX = -1;
-
 void DestroyNodeSet( std::set<Node*>& nodeSet )
 {
   for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
@@ -133,9 +131,7 @@ typedef OwnerContainer< Shader* >              ShaderContainer;
 typedef ShaderContainer::Iterator              ShaderIter;
 typedef ShaderContainer::ConstIterator         ShaderConstIter;
 
-typedef AnimatableMeshContainer::Iterator      AnimatableMeshIter;
-typedef AnimatableMeshContainer::ConstIterator AnimatableMeshConstIter;
-typedef MaterialContainer::Iterator            MaterialIter;
+typedef std::vector<Internal::ShaderDataPtr>   ShaderDataBinaryQueue;
 
 typedef OwnerContainer<PanGesture*>            GestureContainer;
 typedef GestureContainer::Iterator             GestureIter;
@@ -164,6 +160,7 @@ struct UpdateManager::Impl
     notificationManager( notificationManager ),
     animationFinishedNotifier( animationFinishedNotifier ),
     propertyNotifier( propertyNotifier ),
+    shaderSaver( NULL ),
     resourceManager( resourceManager ),
     discardQueue( discardQueue ),
     renderController( renderController ),
@@ -178,11 +175,14 @@ struct UpdateManager::Impl
     systemLevelTaskList ( completeStatusManager ),
     root( NULL ),
     systemLevelRoot( NULL ),
+    renderers( sceneGraphBuffers, discardQueue ),
+    geometries( sceneGraphBuffers, discardQueue ),
+    materials( sceneGraphBuffers, discardQueue ),
+    samplers( sceneGraphBuffers, discardQueue ),
+    propertyBuffers( sceneGraphBuffers, discardQueue ),
     messageQueue( renderController, sceneGraphBuffers ),
-    dynamicsChanged( false ),
     keepRenderingSeconds( 0.0f ),
     animationFinishedDuringUpdate( false ),
-    activeConstraints( 0 ),
     nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
     previousUpdateScene( false ),
     frameCounter( 0 ),
@@ -190,6 +190,12 @@ struct UpdateManager::Impl
     renderTaskWaiting( false )
   {
     sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
+
+    renderers.SetSceneController( *sceneController );
+    geometries.SetSceneController( *sceneController );
+    materials.SetSceneController( *sceneController );
+    propertyBuffers.SetSceneController( *sceneController );
+    samplers.SetSceneController( *sceneController );
   }
 
   ~Impl()
@@ -238,6 +244,7 @@ struct UpdateManager::Impl
   NotificationManager&                notificationManager;           ///< Queues notification messages for the event-thread.
   CompleteNotificationInterface&      animationFinishedNotifier;     ///< Provides notification to applications when animations are finished.
   PropertyNotifier&                   propertyNotifier;              ///< Provides notification to applications when properties are modified.
+  ShaderSaver*                        shaderSaver;                   ///< Saves shader binaries.
   ResourceManager&                    resourceManager;               ///< resource manager
   DiscardQueue&                       discardQueue;                  ///< Nodes are added here when disconnected from the scene-graph.
   RenderController&                   renderController;              ///< render controller
@@ -267,21 +274,22 @@ struct UpdateManager::Impl
   AnimationContainer                  animations;                    ///< A container of owned animations
   PropertyNotificationContainer       propertyNotifications;         ///< A container of owner property notifications.
 
+  ObjectOwnerContainer<Renderer>      renderers;
+  ObjectOwnerContainer<Geometry>      geometries;                    ///< A container of geometries
+  ObjectOwnerContainer<Material>      materials;                     ///< A container of materials
+  ObjectOwnerContainer<Sampler>       samplers;                      ///< A container of samplers
+  ObjectOwnerContainer<PropertyBuffer> propertyBuffers;              ///< A container of property buffers
+
   ShaderContainer                     shaders;                       ///< A container of owned shaders
-  AnimatableMeshContainer             animatableMeshes;              ///< A container of owned animatable meshes
-  MaterialContainer                   materials;                     ///< A container of owned materials
 
   MessageQueue                        messageQueue;                  ///< The messages queued from the event-thread
-
-#ifdef DYNAMICS_SUPPORT
-  OwnerPointer<DynamicsWorld>         dynamicsWorld;                 ///< Wrapper for dynamics simulation
-#endif
-  bool                                dynamicsChanged;               ///< This is set to true if an object is changed in the dynamics simulation tick
+  ShaderDataBinaryQueue               renderCompiledShaders;         ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
+  ShaderDataBinaryQueue               updateCompiledShaders;         ///< Shaders to be sent from Update to Event
+  Mutex                               compiledShaderMutex;           ///< lock to ensure no corruption on the renderCompiledShaders
 
   float                               keepRenderingSeconds;          ///< Set via Dali::Stage::KeepRendering
   bool                                animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
 
-  unsigned int                        activeConstraints;             ///< number of active constraints from previous frame
   int                                 nodeDirtyFlags;                ///< cumulative node dirty flags from previous frame
   bool                                previousUpdateScene;           ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
 
@@ -326,11 +334,6 @@ UpdateManager::~UpdateManager()
   delete mImpl;
 }
 
-EventToUpdate& UpdateManager::GetEventToUpdate()
-{
-  return mImpl->messageQueue;
-}
-
 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
 {
   DALI_ASSERT_DEBUG( layer->IsLayer() );
@@ -358,7 +361,7 @@ void UpdateManager::AddNode( Node* node )
   mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
 }
 
-void UpdateManager::ConnectNode( Node* parent, Node* node, int index )
+void UpdateManager::ConnectNode( Node* parent, Node* node )
 {
   DALI_ASSERT_ALWAYS( NULL != parent );
   DALI_ASSERT_ALWAYS( NULL != node );
@@ -375,7 +378,7 @@ void UpdateManager::ConnectNode( Node* parent, Node* node, int index )
 
   node->SetActive( true );
 
-  parent->ConnectChild( node, index );
+  parent->ConnectChild( node );
 }
 
 void UpdateManager::DisconnectNode( Node* node )
@@ -420,6 +423,7 @@ void UpdateManager::DestroyNode( Node* node )
   node->OnDestroy();
 }
 
+//@todo MESH_REWORK Extend to allow arbitrary scene objects to connect to each other
 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
 {
   DALI_ASSERT_DEBUG( node != NULL );
@@ -427,7 +431,12 @@ void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
 
   // attach node to attachment first so that parent is known by the time attachment is connected
   node->Attach( *attachment ); // node takes ownership
-  attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
+
+  // @todo MESH_REWORK Remove after merge of SceneGraph::RenderableAttachment and SceneGraph::RendererAttachment
+  if( dynamic_cast<SceneGraph::ImageAttachment*>( attachment ) != NULL )
+  {
+    attachment->Initialize( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
+  }
 }
 
 void UpdateManager::AddObject( PropertyOwner* object )
@@ -530,6 +539,32 @@ void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propert
   propertyNotification->SetNotifyMode( notifyMode );
 }
 
+ObjectOwnerContainer<Geometry>& UpdateManager::GetGeometryOwner()
+{
+  return mImpl->geometries;
+}
+
+ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
+{
+  return mImpl->renderers;
+}
+
+
+ObjectOwnerContainer<Material>& UpdateManager::GetMaterialOwner()
+{
+  return mImpl->materials;
+}
+
+ObjectOwnerContainer<Sampler>& UpdateManager::GetSamplerOwner()
+{
+  return mImpl->samplers;
+}
+
+ObjectOwnerContainer<PropertyBuffer>& UpdateManager::GetPropertyBufferOwner()
+{
+  return mImpl->propertyBuffers;
+}
+
 void UpdateManager::AddShader( Shader* shader )
 {
   DALI_ASSERT_DEBUG( NULL != shader );
@@ -549,12 +584,11 @@ void UpdateManager::AddShader( Shader* shader )
 
   mImpl->shaders.PushBack( shader );
 
-  // Allows the shader to dispatch texture requests to the cache and "save shader"
-  // requests to the resource manager from the render thread.
-  shader->Initialize( mImpl->renderManager, mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
+  // Allows the shader to dispatch texture requests to the cache
+  shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
 }
 
-void UpdateManager::RemoveShader(Shader* shader)
+void UpdateManager::RemoveShader( Shader* shader )
 {
   DALI_ASSERT_DEBUG(shader != NULL);
 
@@ -577,92 +611,30 @@ void UpdateManager::RemoveShader(Shader* shader)
   DALI_ASSERT_DEBUG(false);
 }
 
-void UpdateManager::SetShaderProgram( Shader* shader, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash, bool modifiesGeometry )
+void UpdateManager::SetShaderProgram( Shader* shader,
+                                      Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
 {
-  DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash);
-
-  DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
-
-  Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
-  shaderData->SetHashValue( shaderHash );
-
   if( shaderData )
   {
-    // This is done in the render thread, to allow GL program compilation
-    // Will trigger a NotifySaveRequest back to updateManager to forward onto ResourceClient
-    typedef MessageValue6< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::ShaderDataPtr, Context*, bool> DerivedType;
+
+    typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
 
     // Reserve some memory inside the render queue
     unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
 
     // Construct message in the render queue memory; note that delete should not be called on the return value
-    new (slot) DerivedType( shader, &Shader::SetProgram, geometryType, subType, resourceId, shaderData, &(mImpl->renderManager.GetContext()), modifiesGeometry );
-  }
-}
-
-void UpdateManager::AddAnimatableMesh( AnimatableMesh* animatableMesh )
-{
-  mImpl->animatableMeshes.PushBack(animatableMesh);
-}
-
-void UpdateManager::RemoveAnimatableMesh( AnimatableMesh* animatableMesh )
-{
-  DALI_ASSERT_DEBUG(animatableMesh != NULL);
-
-  AnimatableMeshContainer& animatableMeshes = mImpl->animatableMeshes;
-
-  // Find the animatableMesh and destroy it
-  for ( AnimatableMeshIter iter = animatableMeshes.Begin(); iter != animatableMeshes.End(); ++iter )
-  {
-    AnimatableMesh& current = **iter;
-    if ( &current == animatableMesh )
-    {
-      animatableMeshes.Erase( iter );
-      break;
-    }
+    new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
   }
 }
 
-void UpdateManager::AddMaterial( Material* material )
-{
-  DALI_ASSERT_DEBUG( NULL != material );
-
-  mImpl->materials.PushBack( material );
-  RenderMaterial* renderMaterial = new RenderMaterial();
-
-  typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
-
-  // Reserve some memory inside the render queue
-  unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
-
-  // Construct message in the render queue memory; note that delete should not be called on the return value
-  new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddRenderMaterial, renderMaterial );
-
-  material->SetRenderMaterial( renderMaterial );
-  material->OnStageConnection( *mImpl->sceneController );
-}
-
-void UpdateManager::RemoveMaterial( Material* theMaterial )
+void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
 {
-  // Caused by last reference to material being released (e.g. app or internal mesh-actor)
-
-  for ( MaterialIter iter=mImpl->materials.Begin(), end=mImpl->materials.End() ; iter != end ; ++iter )
+  DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
+  DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
   {
-    const Material* aMaterial = *iter;
-
-    if( aMaterial == theMaterial )
-    {
-      typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
-
-      // Reserve some memory inside the render queue
-      unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
-
-      // Construct message in the render queue memory; note that delete should not be called on the return value
-      new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveRenderMaterial, theMaterial->GetRenderMaterial() );
-
-      mImpl->materials.Erase( iter );
-      break;
-    }
+    // lock as update might be sending previously compiled shaders to event thread
+    Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
+    mImpl->renderCompiledShaders.push_back( shaderData );
   }
 }
 
@@ -707,12 +679,22 @@ void UpdateManager::RemoveGesture( PanGesture* gesture )
   DALI_ASSERT_DEBUG(false);
 }
 
-void UpdateManager::ResetNodeProperty( Node& node )
+unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
+{
+  return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
+}
+
+void UpdateManager::EventProcessingStarted()
 {
-  node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
+  mImpl->messageQueue.EventProcessingStarted();
 }
 
-void UpdateManager::ResetProperties()
+bool UpdateManager::FlushQueue()
+{
+  return mImpl->messageQueue.FlushQueue();
+}
+
+void UpdateManager::ResetProperties( BufferIndex bufferIndex )
 {
   PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
 
@@ -721,29 +703,28 @@ void UpdateManager::ResetProperties()
 
   // Animated properties have to be reset to their original value each frame
 
-  // Reset node properties
+  // Reset root properties
   if ( mImpl->root )
   {
-    ResetNodeProperty( *mImpl->root );
+    mImpl->root->ResetToBaseValues( bufferIndex );
   }
-
   if ( mImpl->systemLevelRoot )
   {
-    ResetNodeProperty( *mImpl->systemLevelRoot );
+    mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
   }
 
   // Reset the Connected Nodes
   const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
   for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
   {
-    ResetNodeProperty( **iter );
+    (*iter)->ResetToBaseValues( bufferIndex );
   }
 
   // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
   for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
   {
     Node* node = *iter;
-    node->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
+    node->ResetToBaseValues( bufferIndex );
     node->SetActive( false );
 
     // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
@@ -756,7 +737,7 @@ void UpdateManager::ResetProperties()
 
   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
   {
-    (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
+    (*iter)->ResetToBaseValues( bufferIndex );
   }
 
   // Reset render-task list properties to base values.
@@ -764,31 +745,32 @@ void UpdateManager::ResetProperties()
 
   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
   {
-    (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
+    (*iter)->ResetToBaseValues( bufferIndex );
   }
 
   // Reset custom object properties to base values
   for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
   {
-    (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
+    (*iter)->ResetToBaseValues( bufferIndex );
   }
 
+  mImpl->materials.ResetToBaseValues( bufferIndex );
+  mImpl->geometries.ResetToBaseValues( bufferIndex );
+  mImpl->propertyBuffers.ResetToBaseValues( bufferIndex );
+  mImpl->samplers.ResetToBaseValues( bufferIndex );
+  mImpl->renderers.ResetToBaseValues( bufferIndex );
+
+
   // Reset animatable shader properties to base values
   for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
   {
-    (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
-  }
-
-  // Reset animatable mesh properties to base values
-  for ( AnimatableMeshIter iter = mImpl->animatableMeshes.Begin(); iter != mImpl->animatableMeshes.End(); ++iter )
-  {
-    (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
+    (*iter)->ResetToBaseValues( bufferIndex );
   }
 
   PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
 }
 
-bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
+bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
 {
   bool gestureUpdated( false );
 
@@ -798,14 +780,14 @@ bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, uns
   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
   {
     PanGesture& gesture = **iter;
-    gesture.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
+    gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
     gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
   }
 
   return gestureUpdated;
 }
 
-void UpdateManager::Animate( float elapsedSeconds )
+void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
 {
   PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
 
@@ -814,7 +796,7 @@ void UpdateManager::Animate( float elapsedSeconds )
   while ( iter != animations.End() )
   {
     Animation* animation = *iter;
-    bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
+    bool finished = animation->Update( bufferIndex, elapsedSeconds );
 
     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
 
@@ -838,12 +820,10 @@ void UpdateManager::Animate( float elapsedSeconds )
   PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
 }
 
-void UpdateManager::ApplyConstraints()
+void UpdateManager::ApplyConstraints( BufferIndex bufferIndex )
 {
   PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
 
-  mImpl->activeConstraints = 0;
-
   // constrain custom objects... (in construction order)
   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
 
@@ -851,18 +831,18 @@ void UpdateManager::ApplyConstraints()
   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
   {
     PropertyOwner& object = **iter;
-    mImpl->activeConstraints += ConstrainPropertyOwner( object, mSceneGraphBuffers.GetUpdateBufferIndex() );
+    ConstrainPropertyOwner( object, bufferIndex );
   }
 
   // constrain nodes... (in Depth First traversal order)
   if ( mImpl->root )
   {
-    mImpl->activeConstraints += ConstrainNodes( *(mImpl->root), mSceneGraphBuffers.GetUpdateBufferIndex() );
+    ConstrainNodes( *(mImpl->root), bufferIndex );
   }
 
   if ( mImpl->systemLevelRoot )
   {
-    mImpl->activeConstraints += ConstrainNodes( *(mImpl->systemLevelRoot), mSceneGraphBuffers.GetUpdateBufferIndex() );
+    ConstrainNodes( *(mImpl->systemLevelRoot), bufferIndex );
   }
 
   // constrain other property-owners after nodes as they are more likely to depend on a node's
@@ -880,7 +860,7 @@ void UpdateManager::ApplyConstraints()
   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
   {
     RenderTask& task = **iter;
-    mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
+    ConstrainPropertyOwner( task, bufferIndex );
   }
 
   // Constrain render-tasks
@@ -889,16 +869,15 @@ void UpdateManager::ApplyConstraints()
   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
   {
     RenderTask& task = **iter;
-    mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
+    ConstrainPropertyOwner( task, bufferIndex );
   }
 
-  // constrain meshes (in construction order)
-  AnimatableMeshContainer& meshes = mImpl->animatableMeshes;
-  for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
-  {
-    AnimatableMesh& mesh = **iter;
-    mImpl->activeConstraints += ConstrainPropertyOwner( mesh, mSceneGraphBuffers.GetUpdateBufferIndex() );
-  }
+  // Constrain Materials and geometries
+  mImpl->materials.ConstrainObjects( bufferIndex );
+  mImpl->geometries.ConstrainObjects( bufferIndex );
+  mImpl->samplers.ConstrainObjects( bufferIndex );
+  mImpl->propertyBuffers.ConstrainObjects( bufferIndex );
+  mImpl->renderers.ConstrainObjects( bufferIndex );
 
   // constrain shaders... (in construction order)
   ShaderContainer& shaders = mImpl->shaders;
@@ -906,13 +885,13 @@ void UpdateManager::ApplyConstraints()
   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
   {
     Shader& shader = **iter;
-    mImpl->activeConstraints += ConstrainPropertyOwner( shader, mSceneGraphBuffers.GetUpdateBufferIndex() );
+    ConstrainPropertyOwner( shader, bufferIndex );
   }
 
   PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
 }
 
-void UpdateManager::ProcessPropertyNotifications()
+void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
 {
   PropertyNotificationContainer &notifications = mImpl->propertyNotifications;
   PropertyNotificationIter iter = notifications.Begin();
@@ -920,9 +899,7 @@ void UpdateManager::ProcessPropertyNotifications()
   while ( iter != notifications.End() )
   {
     PropertyNotification* notification = *iter;
-
-    bool valid = notification->Check( mSceneGraphBuffers.GetUpdateBufferIndex() );
-
+    bool valid = notification->Check( bufferIndex );
     if(valid)
     {
       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
@@ -931,7 +908,48 @@ void UpdateManager::ProcessPropertyNotifications()
   }
 }
 
-void UpdateManager::UpdateNodes()
+void UpdateManager::ForwardCompiledShadersToEventThread()
+{
+  DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
+  if( mImpl->shaderSaver )
+  {
+    // lock and swap the queues
+    {
+      // render might be attempting to send us more binaries at the same time
+      Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
+      mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
+    }
+
+    if( mImpl->updateCompiledShaders.size() > 0 )
+    {
+      ShaderSaver& factory = *mImpl->shaderSaver;
+      ShaderDataBinaryQueue::iterator i   = mImpl->updateCompiledShaders.begin();
+      ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
+      for( ; i != end; ++i )
+      {
+        mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
+      }
+      // we don't need them in update anymore
+      mImpl->updateCompiledShaders.clear();
+    }
+  }
+}
+
+void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
+{
+  const Internal::OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
+  unsigned int rendererCount( rendererContainer.Size() );
+  for( unsigned int i(0); i<rendererCount; ++i )
+  {
+    if( rendererContainer[i]->IsReferenced() )
+    {
+      rendererContainer[i]->PrepareResources(bufferIndex, mImpl->resourceManager);
+      rendererContainer[i]->PrepareRender( bufferIndex );
+    }
+  }
+}
+
+void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
 {
   mImpl->nodeDirtyFlags = NothingFlag;
 
@@ -945,14 +963,14 @@ void UpdateManager::UpdateNodes()
   // Prepare resources, update shaders, update attachments, for each node
   // And add the renderers to the sorted layers. Start from root, which is also a layer
   mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
-                                                     mSceneGraphBuffers.GetUpdateBufferIndex(),
+                                                     bufferIndex,
                                                      mImpl->resourceManager,
                                                      mImpl->renderQueue );
 
   if ( mImpl->systemLevelRoot )
   {
     mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
-                                                        mSceneGraphBuffers.GetUpdateBufferIndex(),
+                                                        bufferIndex,
                                                         mImpl->resourceManager,
                                                         mImpl->renderQueue );
   }
@@ -960,33 +978,6 @@ void UpdateManager::UpdateNodes()
   PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
 }
 
-void UpdateManager::UpdateMeshes( BufferIndex updateBufferIndex, AnimatableMeshContainer& meshes )
-{
-  for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
-  {
-    AnimatableMesh& current = **iter;
-    current.UpdateMesh( updateBufferIndex );
-  }
-}
-
-void UpdateManager::UpdateMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
-{
-  for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
-  {
-    Material* material = *iter;
-    material->PrepareResources( updateBufferIndex, mImpl->resourceManager );
-  }
-}
-
-void UpdateManager::PrepareMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
-{
-  for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
-  {
-    Material* material = *iter;
-    material->PrepareRender( updateBufferIndex );
-  }
-}
-
 unsigned int UpdateManager::Update( float elapsedSeconds,
                                     unsigned int lastVSyncTimeMilliseconds,
                                     unsigned int nextVSyncTimeMilliseconds )
@@ -998,41 +989,45 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
   // Measure the time spent in UpdateManager::Update
   PERF_MONITOR_START(PerformanceMonitor::UPDATE);
 
+  const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
+
   // Update the frame time delta on the render thread.
   mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
 
   // 1) Clear nodes/resources which were previously discarded
-  mImpl->discardQueue.Clear( mSceneGraphBuffers.GetUpdateBufferIndex() );
+  mImpl->discardQueue.Clear( bufferIndex );
 
   // 2) Grab any loaded resources
-  bool resourceChanged = mImpl->resourceManager.UpdateCache( mSceneGraphBuffers.GetUpdateBufferIndex() );
+  bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
 
   // 3) Process Touches & Gestures
   mImpl->touchResampler.Update();
-  const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
+  const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
+
+  const bool updateScene =                                  // The scene-graph requires an update if..
+      (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||    // ..nodes were dirty in previous frame OR
+      IsAnimationRunning()                            ||    // ..at least one animation is running OR
+      mImpl->messageQueue.IsSceneUpdateRequired()     ||    // ..a message that modifies the scene graph node tree is queued OR
+      resourceChanged                                 ||    // ..one or more resources were updated/changed OR
+      gestureUpdated;                                       // ..a gesture property was updated
 
-  const bool updateScene =                                            // The scene-graph requires an update if..
-      mImpl->activeConstraints != 0 ||                                // ..constraints were active in previous frame OR
-      (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||              // ..nodes were dirty in previous frame OR
-      IsAnimationRunning() ||                                         // ..at least one animation is running OR
-      mImpl->dynamicsChanged ||                                       // ..there was a change in the dynamics simulation OR
-      mImpl->messageQueue.IsSceneUpdateRequired() ||                  // ..a message that modifies the scene graph node tree is queued OR
-      resourceChanged ||                                              // ..one or more resources were updated/changed OR
-      gestureUpdated;                                                // ..a gesture property was updated
 
   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
   // values if the scene was updated in the previous frame.
   if( updateScene || mImpl->previousUpdateScene )
   {
     // 4) Reset properties from the previous update
-    ResetProperties();
+    ResetProperties( bufferIndex );
   }
 
   // 5) Process the queued scene messages
-  mImpl->messageQueue.ProcessMessages();
+  mImpl->messageQueue.ProcessMessages( bufferIndex );
 
   // 6) Post Process Ids of resources updated by renderer
-  mImpl->resourceManager.PostProcessResources( mSceneGraphBuffers.GetUpdateBufferIndex() );
+  mImpl->resourceManager.PostProcessResources( bufferIndex );
+
+  // 6.1) Forward compiled shader programs to event thread for saving
+  ForwardCompiledShadersToEventThread();
 
   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
   // renderer lists if the scene was updated in the previous frame.
@@ -1040,54 +1035,41 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
   if( updateScene || mImpl->previousUpdateScene )
   {
     // 7) Animate
-    Animate( elapsedSeconds );
+    Animate( bufferIndex, elapsedSeconds );
 
     // 8) Apply Constraints
-    ApplyConstraints();
+    ApplyConstraints( bufferIndex );
 
-#ifdef DYNAMICS_SUPPORT
-    // 9) Update dynamics simulation
-    mImpl->dynamicsChanged = false;
-    if( mImpl->dynamicsWorld )
-    {
-      mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
-    }
-#endif
+    // 9) Check Property Notifications
+    ProcessPropertyNotifications( bufferIndex );
 
-    // 10) Check Property Notifications
-    ProcessPropertyNotifications();
-
-    // 11) Clear the lists of renderable-attachments from the previous update
+    // 10) Clear the lists of renderable-attachments from the previous update
     ClearRenderables( mImpl->sortedLayers );
     ClearRenderables( mImpl->systemLevelSortedLayers );
 
-    // 12) Update animated meshes
-    UpdateMeshes( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->animatableMeshes );
-
-    // 13) Update materials. Prepares image resources
-    UpdateMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
-
-    // 14) Update node hierarchy and perform sorting / culling.
+    // 11) Update node hierarchy and perform sorting / culling.
     //     This will populate each Layer with a list of renderers which are ready.
-    UpdateNodes();
+    UpdateNodes( bufferIndex );
+    UpdateRenderers( bufferIndex );
+
 
-    // 15) Prepare for the next render
+    // 12) Prepare for the next render
     PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
-    PrepareMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
-    PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->sortedLayers );
-    PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->systemLevelSortedLayers );
+
+    PrepareRenderables( bufferIndex, mImpl->sortedLayers );
+    PrepareRenderables( bufferIndex, mImpl->systemLevelSortedLayers );
     PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
 
     PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
 
-    // 16) Process the RenderTasks; this creates the instructions for rendering the next frame.
+    // 14) Process the RenderTasks; this creates the instructions for rendering the next frame.
     // reset the update buffer index and make sure there is enough room in the instruction container
-    mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
+    mImpl->renderInstructions.ResetAndReserve( bufferIndex,
                                                mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
 
     if ( NULL != mImpl->root )
     {
-      ProcessRenderTasks(  mSceneGraphBuffers.GetUpdateBufferIndex(),
+      ProcessRenderTasks(  bufferIndex,
                            mImpl->completeStatusManager,
                            mImpl->taskList,
                            *mImpl->root,
@@ -1098,7 +1080,7 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
       // Process the system-level RenderTasks last
       if ( NULL != mImpl->systemLevelRoot )
       {
-        ProcessRenderTasks(  mSceneGraphBuffers.GetUpdateBufferIndex(),
+        ProcessRenderTasks(  bufferIndex,
                              mImpl->completeStatusManager,
                              mImpl->systemLevelTaskList,
                              *mImpl->systemLevelRoot,
@@ -1121,7 +1103,7 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
     renderTask.UpdateState();
 
     if( renderTask.IsWaitingToRender() &&
-        renderTask.ReadyToRender(mSceneGraphBuffers.GetUpdateBufferIndex()) /*avoid updating forever when source actor is off-stage*/ )
+        renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
     {
       mImpl->renderTaskWaiting = true; // keep update/render threads alive
     }
@@ -1154,12 +1136,12 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
   keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
 #endif
 
-  // The update has finished; swap the double-buffering indices
-  mSceneGraphBuffers.Swap();
-
   // tell the update manager that we're done so the queue can be given to event thread
   mImpl->notificationManager.UpdateCompleted();
 
+  // The update has finished; swap the double-buffering indices
+  mSceneGraphBuffers.Swap();
+
   PERF_MONITOR_END(PerformanceMonitor::UPDATE);
 
   return keepUpdating;
@@ -1186,22 +1168,12 @@ unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
   }
 
-  if ( !mImpl->messageQueue.WasEmpty() )
-  {
-    keepUpdatingRequest |= KeepUpdating::INCOMING_MESSAGES;
-  }
-
   if ( IsAnimationRunning() ||
        mImpl->animationFinishedDuringUpdate )
   {
     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
   }
 
-  if ( mImpl->dynamicsChanged )
-  {
-    keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
-  }
-
   if ( mImpl->renderTaskWaiting )
   {
     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
@@ -1250,21 +1222,11 @@ void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool syst
   }
 }
 
-#ifdef DYNAMICS_SUPPORT
-
-void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
+void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
 {
-  dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
-  mImpl->dynamicsWorld = dynamicsWorld;
+  mImpl->shaderSaver = &upstream;
 }
 
-void UpdateManager::TerminateDynamicsWorld()
-{
-  mImpl->dynamicsWorld.Reset();
-}
-
-#endif // DYNAMICS_SUPPORT
-
 } // namespace SceneGraph
 
 } // namespace Internal