Fix memory leaks detected by Valgrind
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-manager.cpp
index 9daa1c5..8cd9021 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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/devel-api/common/set-wrapper.h>
+#include <dali/devel-api/common/owner-container.h>
+#include <dali/devel-api/threading/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/common/owner-container.h>
 #include <dali/internal/common/message.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/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/manager/render-task-processor.h>
 #include <dali/internal/update/manager/sorted-layers.h>
 #include <dali/internal/update/manager/update-algorithms.h>
 #include <dali/internal/update/manager/update-manager-debug.h>
-#include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
-#include <dali/internal/update/node-attachments/scene-graph-renderer-attachment.h>
-#include <dali/internal/update/node-attachments/scene-graph-image-attachment.h>
+#include <dali/internal/update/manager/transform-manager.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/update/rendering/scene-graph-texture-set.h>
+#include <dali/internal/update/render-tasks/scene-graph-camera.h>
 
 #include <dali/internal/render/common/render-instruction-container.h>
 #include <dali/internal/render/common/render-manager.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/shaders/scene-graph-shader.h>
 
-#ifdef DALI_DYNAMICS_SUPPORT
-#include <dali/integration-api/dynamics/dynamics-world-settings.h>
-#include <dali/internal/update/dynamics/scene-graph-dynamics-world.h>
-#endif
-
 // Un-comment to enable node tree debug logging
 //#define NODE_TREE_LOGGING 1
 
@@ -112,33 +99,19 @@ namespace Internal
 namespace SceneGraph
 {
 
-namespace
-{
-
-void DestroyNodeSet( std::set<Node*>& nodeSet )
-{
-  for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
-  {
-    Node* node( *iter );
-
-    // Call Node::OnDestroy as each node is destroyed
-    node->OnDestroy();
-
-    delete node;
-  }
-  nodeSet.clear();
-}
-
-} //namespace
-
 typedef OwnerContainer< Shader* >              ShaderContainer;
 typedef ShaderContainer::Iterator              ShaderIter;
 typedef ShaderContainer::ConstIterator         ShaderConstIter;
 
+typedef std::vector<Internal::ShaderDataPtr>   ShaderDataBinaryQueue;
+
 typedef OwnerContainer<PanGesture*>            GestureContainer;
 typedef GestureContainer::Iterator             GestureIter;
 typedef GestureContainer::ConstIterator        GestureConstIter;
 
+typedef OwnerContainer< TextureSet* >          TextureSetContainer;
+typedef TextureSetContainer::Iterator          TextureSetIter;
+typedef TextureSetContainer::ConstIterator     TextureSetConstIter;
 
 /**
  * Structure to contain UpdateManager internal data
@@ -146,56 +119,48 @@ typedef GestureContainer::ConstIterator        GestureConstIter;
 struct UpdateManager::Impl
 {
   Impl( NotificationManager& notificationManager,
-        GlSyncAbstraction& glSyncAbstraction,
         CompleteNotificationInterface& animationFinishedNotifier,
         PropertyNotifier& propertyNotifier,
-        ResourceManager& resourceManager,
         DiscardQueue& discardQueue,
         RenderController& renderController,
         RenderManager& renderManager,
         RenderQueue& renderQueue,
-        TextureCache& textureCache,
-        TouchResampler& touchResampler,
-        SceneGraphBuffers& sceneGraphBuffers )
-  :
-    renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
+        SceneGraphBuffers& sceneGraphBuffers,
+        RenderTaskProcessor& renderTaskProcessor )
+  : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
     notificationManager( notificationManager ),
+    transformManager(),
     animationFinishedNotifier( animationFinishedNotifier ),
     propertyNotifier( propertyNotifier ),
-    resourceManager( resourceManager ),
+    shaderSaver( NULL ),
     discardQueue( discardQueue ),
     renderController( renderController ),
     sceneController( NULL ),
     renderManager( renderManager ),
     renderQueue( renderQueue ),
     renderInstructions( renderManager.GetRenderInstructionContainer() ),
-    completeStatusManager( glSyncAbstraction, renderMessageDispatcher, resourceManager ),
-    touchResampler( touchResampler ),
+    renderTaskProcessor( renderTaskProcessor ),
     backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
-    taskList ( completeStatusManager ),
-    systemLevelTaskList ( completeStatusManager ),
+    taskList( renderMessageDispatcher ),
+    systemLevelTaskList( renderMessageDispatcher ),
     root( NULL ),
     systemLevelRoot( NULL ),
-    geometries(  sceneGraphBuffers, discardQueue ),
-    materials( sceneGraphBuffers, discardQueue ),
-    samplers( sceneGraphBuffers, discardQueue ),
-    propertyBuffers( sceneGraphBuffers, discardQueue ),
+    renderers( sceneGraphBuffers, discardQueue ),
+    textureSets(),
     messageQueue( renderController, sceneGraphBuffers ),
-    dynamicsChanged( false ),
     keepRenderingSeconds( 0.0f ),
     animationFinishedDuringUpdate( false ),
     nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
     previousUpdateScene( false ),
     frameCounter( 0 ),
-    renderSortingHelper(),
     renderTaskWaiting( false )
   {
-    sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
+    sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
 
-    geometries.SetSceneController( *sceneController );
-    materials.SetSceneController( *sceneController );
-    propertyBuffers.SetSceneController( *sceneController );
-    samplers.SetSceneController( *sceneController );
+    renderers.SetSceneController( *sceneController );
+
+    // create first 'dummy' node
+    nodes.PushBack(0u);
   }
 
   ~Impl()
@@ -214,16 +179,20 @@ struct UpdateManager::Impl
     }
 
     // UpdateManager owns the Nodes
-    DestroyNodeSet( activeDisconnectedNodes );
-    DestroyNodeSet( connectedNodes );
-    DestroyNodeSet( disconnectedNodes );
+    Vector<Node*>::Iterator iter = nodes.Begin()+1;
+    Vector<Node*>::Iterator endIter = nodes.End();
+    for(;iter!=endIter;++iter)
+    {
+      (*iter)->OnDestroy();
+      Node::Delete(*iter);
+    }
 
     // If there is root, reset it, otherwise do nothing as rendering was never started
     if( root )
     {
       root->OnDestroy();
 
-      delete root;
+      Node::Delete( root );
       root = NULL;
     }
 
@@ -231,28 +200,27 @@ struct UpdateManager::Impl
     {
       systemLevelRoot->OnDestroy();
 
-      delete systemLevelRoot;
+      Node::Delete( systemLevelRoot );
       systemLevelRoot = NULL;
     }
 
-    sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
     delete sceneController;
   }
 
   SceneGraphBuffers                   sceneGraphBuffers;             ///< Used to keep track of which buffers are being written or read
   RenderMessageDispatcher             renderMessageDispatcher;       ///< Used for passing messages to the render-thread
   NotificationManager&                notificationManager;           ///< Queues notification messages for the event-thread.
+  TransformManager                    transformManager;              ///< Used to update the transformation matrices of the nodes
   CompleteNotificationInterface&      animationFinishedNotifier;     ///< Provides notification to applications when animations are finished.
   PropertyNotifier&                   propertyNotifier;              ///< Provides notification to applications when properties are modified.
-  ResourceManager&                    resourceManager;               ///< resource manager
+  ShaderSaver*                        shaderSaver;                   ///< Saves shader binaries.
   DiscardQueue&                       discardQueue;                  ///< Nodes are added here when disconnected from the scene-graph.
   RenderController&                   renderController;              ///< render controller
   SceneControllerImpl*                sceneController;               ///< scene controller
   RenderManager&                      renderManager;                 ///< This is responsible for rendering the results of each "update"
   RenderQueue&                        renderQueue;                   ///< Used to queue messages for the next render
   RenderInstructionContainer&         renderInstructions;            ///< Used to prepare the render instructions
-  CompleteStatusManager               completeStatusManager;         ///< Complete Status Manager
-  TouchResampler&                     touchResampler;                ///< Used to resample touch events on every update.
+  RenderTaskProcessor&                renderTaskProcessor;           ///< Handles RenderTasks and RenderInstrucitons
 
   Vector4                             backgroundColor;               ///< The glClear color used at the beginning of each frame.
 
@@ -261,31 +229,27 @@ struct UpdateManager::Impl
 
   Layer*                              root;                          ///< The root node (root is a layer)
   Layer*                              systemLevelRoot;               ///< A separate root-node for system-level content
-  std::set< Node* >                   activeDisconnectedNodes;       ///< A container of new or modified nodes (without parent) owned by UpdateManager
-  std::set< Node* >                   connectedNodes;                ///< A container of connected (with parent) nodes owned by UpdateManager
-  std::set< Node* >                   disconnectedNodes;             ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager
+
+  Vector<Node*>                       nodes;                         ///< A container of all instantiated nodes
 
   SortedLayerPointers                 sortedLayers;                  ///< A container of Layer pointers sorted by depth
   SortedLayerPointers                 systemLevelSortedLayers;       ///< A separate container of system-level Layers
 
+  OwnerContainer< Camera* >           cameras;                       ///< A container of cameras
   OwnerContainer< PropertyOwner* >    customObjects;                 ///< A container of owned objects (with custom properties)
 
   AnimationContainer                  animations;                    ///< A container of owned animations
   PropertyNotificationContainer       propertyNotifications;         ///< A container of owner property notifications.
 
-  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
+  ObjectOwnerContainer<Renderer>      renderers;
+  TextureSetContainer                 textureSets;                   ///< A container of texture sets
 
   ShaderContainer                     shaders;                       ///< A container of owned shaders
 
   MessageQueue                        messageQueue;                  ///< The messages queued from the event-thread
-
-#ifdef DALI_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()
@@ -294,39 +258,36 @@ struct UpdateManager::Impl
   bool                                previousUpdateScene;           ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
 
   int                                 frameCounter;                  ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
-  RendererSortingHelper               renderSortingHelper;           ///< helper used to sort transparent renderers
 
   GestureContainer                    gestures;                      ///< A container of owned gesture detectors
   bool                                renderTaskWaiting;             ///< A REFRESH_ONCE render task is waiting to be rendered
+
+private:
+
+  Impl( const Impl& ); ///< Undefined
+  Impl& operator=( const Impl& ); ///< Undefined
 };
 
 UpdateManager::UpdateManager( NotificationManager& notificationManager,
-                              GlSyncAbstraction& glSyncAbstraction,
                               CompleteNotificationInterface& animationFinishedNotifier,
                               PropertyNotifier& propertyNotifier,
-                              ResourceManager& resourceManager,
                               DiscardQueue& discardQueue,
                               RenderController& controller,
                               RenderManager& renderManager,
                               RenderQueue& renderQueue,
-                              TextureCache& textureCache,
-                              TouchResampler& touchResampler )
+                              RenderTaskProcessor& renderTaskProcessor )
   : mImpl(NULL)
 {
   mImpl = new Impl( notificationManager,
-                    glSyncAbstraction,
                     animationFinishedNotifier,
                     propertyNotifier,
-                    resourceManager,
                     discardQueue,
                     controller,
                     renderManager,
                     renderQueue,
-                    textureCache,
-                    touchResampler,
-                    mSceneGraphBuffers );
+                    mSceneGraphBuffers,
+                    renderTaskProcessor );
 
-  textureCache.SetBufferIndices( &mSceneGraphBuffers );
 }
 
 UpdateManager::~UpdateManager()
@@ -343,11 +304,13 @@ void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
   {
     DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
     mImpl->root = layer;
+    mImpl->root->CreateTransform( &mImpl->transformManager );
   }
   else
   {
     DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
     mImpl->systemLevelRoot = layer;
+    mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager );
   }
 
   layer->SetRoot(true);
@@ -358,27 +321,26 @@ void UpdateManager::AddNode( Node* node )
   DALI_ASSERT_ALWAYS( NULL != node );
   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
 
-  mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
+  // Nodes must be sorted by pointer
+  Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
+  for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
+  {
+    if(node > (*iter))
+    {
+      mImpl->nodes.Insert((iter+1), node);
+      node->CreateTransform( &mImpl->transformManager );
+      break;
+    }
+  }
 }
 
-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 );
   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
 
-  // Move from active/disconnectedNodes to connectedNodes
-  std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
-  if( !removed )
-  {
-    removed = mImpl->disconnectedNodes.erase( node );
-    DALI_ASSERT_ALWAYS( removed );
-  }
-  mImpl->connectedNodes.insert( node );
-
-  node->SetActive( true );
-
-  parent->ConnectChild( node, index );
+  parent->ConnectChild( node );
 }
 
 void UpdateManager::DisconnectNode( Node* node )
@@ -387,21 +349,7 @@ void UpdateManager::DisconnectNode( Node* node )
   DALI_ASSERT_ALWAYS( NULL != parent );
   parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
 
-  // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
-  parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
-}
-
-void UpdateManager::SetNodeActive( Node* node )
-{
-  DALI_ASSERT_ALWAYS( NULL != node );
-  DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
-
-  // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
-  std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
-  DALI_ASSERT_ALWAYS( removed );
-  mImpl->activeDisconnectedNodes.insert( node );
-
-  node->SetActive( true );
+  parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
 }
 
 void UpdateManager::DestroyNode( Node* node )
@@ -409,42 +357,47 @@ void UpdateManager::DestroyNode( Node* node )
   DALI_ASSERT_ALWAYS( NULL != node );
   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
 
-  // Transfer ownership from new/disconnectedNodes to the discard queue
-  // This keeps the nodes alive, until the render-thread has finished with them
-  std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
-  if( !removed )
+  Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
+  Vector<Node*>::Iterator endIter = mImpl->nodes.End();
+  for(;iter!=endIter;++iter)
   {
-    removed = mImpl->disconnectedNodes.erase( node );
-    DALI_ASSERT_ALWAYS( removed );
+    if((*iter) == node)
+    {
+      mImpl->nodes.Erase(iter);
+      break;
+    }
   }
+
   mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
 
   // Notify the Node about impending destruction
   node->OnDestroy();
 }
 
-//@todo MESH_REWORK Extend to allow arbitrary scene objects to connect to each other
-void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
+void UpdateManager::AddCamera( Camera* camera )
 {
-  DALI_ASSERT_DEBUG( node != NULL );
-  DALI_ASSERT_DEBUG( attachment != NULL );
-
-  // attach node to attachment first so that parent is known by the time attachment is connected
-  node->Attach( *attachment ); // node takes ownership
+  DALI_ASSERT_DEBUG( camera != NULL );
 
-  // @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() );
-  }
+  mImpl->cameras.PushBack( camera ); // takes ownership
 }
 
-void UpdateManager::AttachToSceneGraph( RendererAttachment* renderer )
+void UpdateManager::RemoveCamera( const Camera* camera )
 {
-  // @todo MESH_REWORK Take ownership of this object after merge with SceneGraph::RenderableAttachment
+  // Find the camera
+  OwnerContainer<Camera*>::Iterator iter = mImpl->cameras.Begin();
+  OwnerContainer<Camera*>::ConstIterator end = mImpl->cameras.End();
+  for ( ; iter != end; ++iter )
+  {
+    Camera* value = *iter;
+    if ( camera == value )
+    {
+      // Transfer ownership to the discard queue
+      mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) );
+
+      return;
+    }
+  }
 
-  SceneGraph::NodeAttachment* attachment = static_cast<SceneGraph::NodeAttachment*>(renderer);
-  attachment->Initialize( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
 }
 
 void UpdateManager::AddObject( PropertyOwner* object )
@@ -547,24 +500,9 @@ void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propert
   propertyNotification->SetNotifyMode( notifyMode );
 }
 
-ObjectOwnerContainer<Geometry>& UpdateManager::GetGeometryOwner()
-{
-  return mImpl->geometries;
-}
-
-ObjectOwnerContainer<Material>& UpdateManager::GetMaterialOwner()
-{
-  return mImpl->materials;
-}
-
-ObjectOwnerContainer<Sampler>& UpdateManager::GetSamplerOwner()
-{
-  return mImpl->samplers;
-}
-
-ObjectOwnerContainer<PropertyBuffer>& UpdateManager::GetPropertyBufferOwner()
+ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
 {
-  return mImpl->propertyBuffers;
+  return mImpl->renderers;
 }
 
 void UpdateManager::AddShader( Shader* shader )
@@ -585,9 +523,6 @@ void UpdateManager::AddShader( Shader* shader )
   }
 
   mImpl->shaders.PushBack( shader );
-
-  // Allows the shader to dispatch texture requests to the cache
-  shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
 }
 
 void UpdateManager::RemoveShader( Shader* shader )
@@ -614,25 +549,29 @@ void UpdateManager::RemoveShader( Shader* shader )
 }
 
 void UpdateManager::SetShaderProgram( Shader* shader,
-                                      ResourceId resourceId, size_t shaderHash, bool modifiesGeometry )
+                                      Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
 {
-  DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (id:%d hash:%d)\n", resourceId, shaderHash);
-
-  DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
-
-  Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
   if( shaderData )
   {
-    shaderData->SetHashValue( shaderHash );
-    shaderData->SetResourceId( resourceId );
 
-    typedef MessageValue4< Shader, Integration::ResourceId, Integration::ShaderDataPtr, ProgramCache*, 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, resourceId, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
+    new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
+  }
+}
+
+void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
+{
+  DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
+  DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
+  {
+    // lock as update might be sending previously compiled shaders to event thread
+    Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
+    mImpl->renderCompiledShaders.push_back( shaderData );
   }
 }
 
@@ -677,6 +616,26 @@ void UpdateManager::RemoveGesture( PanGesture* gesture )
   DALI_ASSERT_DEBUG(false);
 }
 
+void UpdateManager::AddTextureSet( TextureSet* textureSet )
+{
+  DALI_ASSERT_DEBUG( NULL != textureSet );
+  mImpl->textureSets.PushBack( textureSet );
+}
+
+void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
+{
+  DALI_ASSERT_DEBUG(textureSet != NULL);
+  size_t textureSetCount( mImpl->textureSets.Size() );
+  for( size_t i(0); i<textureSetCount; ++i )
+  {
+    if( textureSet == mImpl->textureSets[i] )
+    {
+      mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i );
+      return;
+    }
+  }
+}
+
 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
 {
   return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
@@ -692,52 +651,29 @@ bool UpdateManager::FlushQueue()
   return mImpl->messageQueue.FlushQueue();
 }
 
-void UpdateManager::ResetNodeProperty( Node& node )
+void UpdateManager::ResetProperties( BufferIndex bufferIndex )
 {
-  BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
-
-  node.ResetToBaseValues( bufferIndex );
-}
-
-void UpdateManager::ResetProperties()
-{
-  PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
-
-  BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
-
   // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
   mImpl->animationFinishedDuringUpdate = false;
 
   // 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 );
-  }
-
-  // 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 );
+    mImpl->systemLevelRoot->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() )
+  // Reset all the nodes
+  Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
+  Vector<Node*>::Iterator endIter = mImpl->nodes.End();
+  for(;iter != endIter; ++iter)
   {
-    Node* node = *iter;
-    node->ResetToBaseValues( bufferIndex );
-    node->SetActive( false );
-
-    // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
-    mImpl->activeDisconnectedNodes.erase( iter );
-    mImpl->disconnectedNodes.insert( node );
+    (*iter)->ResetToBaseValues( bufferIndex );
   }
 
   // Reset system-level render-task list properties to base values
@@ -762,22 +698,16 @@ void UpdateManager::ResetProperties()
     (*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( 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 );
 
@@ -787,25 +717,27 @@ 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);
-
   AnimationContainer &animations = mImpl->animations;
   AnimationIter iter = animations.Begin();
+  bool animationLooped = false;
   while ( iter != animations.End() )
   {
     Animation* animation = *iter;
-    bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
+    bool finished = false;
+    bool looped = false;
+    animation->Update( bufferIndex, elapsedSeconds, looped, finished );
 
     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
+    animationLooped = animationLooped || looped;
 
     // Remove animations that had been destroyed but were still waiting for an update
     if (animation->GetState() == Animation::Destroyed)
@@ -818,54 +750,30 @@ void UpdateManager::Animate( float elapsedSeconds )
     }
   }
 
-  if ( mImpl->animationFinishedDuringUpdate )
+  // queue the notification on finished or looped (to update loop count)
+  if ( mImpl->animationFinishedDuringUpdate || animationLooped )
   {
     // The application should be notified by NotificationManager, in another thread
     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
   }
-
-  PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
 }
 
-void UpdateManager::ApplyConstraints()
+void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
 {
-  PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
-
-  BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
-
-  // constrain custom objects... (in construction order)
+  //Constrain custom objects (in construction order)
   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
-
   const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
   {
     PropertyOwner& object = **iter;
     ConstrainPropertyOwner( object, bufferIndex );
   }
+}
 
-  // constrain nodes... (in Depth First traversal order)
-  if ( mImpl->root )
-  {
-    ConstrainNodes( *(mImpl->root), bufferIndex );
-  }
-
-  if ( mImpl->systemLevelRoot )
-  {
-    ConstrainNodes( *(mImpl->systemLevelRoot), bufferIndex );
-  }
-
-  // constrain other property-owners after nodes as they are more likely to depend on a node's
-  // current frame property than vice versa. They tend to be final constraints (no further
-  // constraints depend on their properties)
-  // e.g. ShaderEffect uniform a function of Actor's position.
-  // Mesh vertex a function of Actor's position or world position.
-
-  // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
-  // they can be all processed in a super-list of property-owners.
-
+void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
+{
   // Constrain system-level render-tasks
   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
-
   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
   {
     RenderTask& task = **iter;
@@ -874,38 +782,29 @@ void UpdateManager::ApplyConstraints()
 
   // Constrain render-tasks
   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
-
   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
   {
     RenderTask& task = **iter;
     ConstrainPropertyOwner( task, bufferIndex );
   }
+}
 
-  // Constrain Materials and geometries
-  mImpl->materials.ConstrainObjects( bufferIndex );
-  mImpl->geometries.ConstrainObjects( bufferIndex );
-  mImpl->samplers.ConstrainObjects( bufferIndex );
-  mImpl->propertyBuffers.ConstrainObjects( bufferIndex );
-
+void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
+{
   // constrain shaders... (in construction order)
   ShaderContainer& shaders = mImpl->shaders;
-
   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
   {
     Shader& shader = **iter;
     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();
 
-  BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
-
   while ( iter != notifications.End() )
   {
     PropertyNotification* notification = *iter;
@@ -918,7 +817,47 @@ 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 OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
+  unsigned int rendererCount( rendererContainer.Size() );
+  for( unsigned int i(0); i<rendererCount; ++i )
+  {
+    //Apply constraints
+    ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
+
+    rendererContainer[i]->PrepareRender( bufferIndex );
+  }
+}
+
+void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
 {
   mImpl->nodeDirtyFlags = NothingFlag;
 
@@ -927,139 +866,114 @@ void UpdateManager::UpdateNodes()
     return;
   }
 
-  PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
-
-  // Prepare resources, update shaders, update attachments, for each node
+  // Prepare resources, update shaders, 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(),
-                                                     mImpl->resourceManager,
-                                                     mImpl->renderQueue );
+  mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
+                                          bufferIndex,
+                                          mImpl->renderQueue );
 
   if ( mImpl->systemLevelRoot )
   {
-    mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
-                                                        mSceneGraphBuffers.GetUpdateBufferIndex(),
-                                                        mImpl->resourceManager,
-                                                        mImpl->renderQueue );
+    mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
+                                             bufferIndex,
+                                             mImpl->renderQueue );
   }
-
-  PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
 }
 
 unsigned int UpdateManager::Update( float elapsedSeconds,
                                     unsigned int lastVSyncTimeMilliseconds,
                                     unsigned int nextVSyncTimeMilliseconds )
 {
-  PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE);   // Mark the End of the last frame
-  PERF_MONITOR_NEXT_FRAME();             // Prints out performance info for the last frame (if enabled)
-  PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
-
-  // Measure the time spent in UpdateManager::Update
-  PERF_MONITOR_START(PerformanceMonitor::UPDATE);
+  const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
 
-  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
+  //Clear nodes/resources which were previously discarded
   mImpl->discardQueue.Clear( bufferIndex );
 
-  // 2) Grab any loaded resources
-  bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
+  //Process Touches & Gestures
+  const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
 
-  // 3) Process Touches & Gestures
-  mImpl->touchResampler.Update();
-  const bool gestureUpdated = ProcessGestures( 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
+      gestureUpdated;                                       // ..a gesture property was updated
 
-  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->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();
+    //Reset properties from the previous update
+    ResetProperties( bufferIndex );
+    mImpl->transformManager.ResetToBaseValue();
   }
 
-  // 5) Process the queued scene messages
-  mImpl->messageQueue.ProcessMessages();
+  //Process the queued scene messages
+  mImpl->messageQueue.ProcessMessages( bufferIndex );
 
-  // 6) Post Process Ids of resources updated by renderer
-  mImpl->resourceManager.PostProcessResources( bufferIndex );
+  //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.
   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
   if( updateScene || mImpl->previousUpdateScene )
   {
-    // 7) Animate
-    Animate( elapsedSeconds );
+    //Animate
+    Animate( bufferIndex, elapsedSeconds );
 
-    // 8) Apply Constraints
-    ApplyConstraints();
+    //Constraint custom objects
+    ConstrainCustomObjects( bufferIndex );
 
-#ifdef DALI_DYNAMICS_SUPPORT
-    // 9) Update dynamics simulation
-    mImpl->dynamicsChanged = false;
-    if( mImpl->dynamicsWorld )
+    //Clear the lists of renderers from the previous update
+    for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
     {
-      mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
+      mImpl->sortedLayers[i]->ClearRenderables();
     }
-#endif
 
-    // 10) Check Property Notifications
-    ProcessPropertyNotifications();
+    for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
+    {
+      mImpl->systemLevelSortedLayers[i]->ClearRenderables();
+    }
 
-    // 11) Clear the lists of renderable-attachments from the previous update
-    ClearRenderables( mImpl->sortedLayers );
-    ClearRenderables( mImpl->systemLevelSortedLayers );
+    //Update node hierarchy, apply constraints and perform sorting / culling.
+    //This will populate each Layer with a list of renderers which are ready.
+    UpdateNodes( bufferIndex );
 
-    // 12) Update node hierarchy and perform sorting / culling.
-    //     This will populate each Layer with a list of renderers which are ready.
-    UpdateNodes();
+    //Apply constraints to RenderTasks, shaders
+    ConstrainRenderTasks( bufferIndex );
+    ConstrainShaders( bufferIndex );
 
-    // 13) Prepare for the next render
-    PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
+    //Update renderers and apply constraints
+    UpdateRenderers( bufferIndex );
 
-    PrepareRenderables( bufferIndex, mImpl->sortedLayers );
-    PrepareRenderables( bufferIndex, mImpl->systemLevelSortedLayers );
-    PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
+    //Update the trnasformations of all the nodes
+    mImpl->transformManager.Update();
 
-    PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
+    //Process Property Notifications
+    ProcessPropertyNotifications( bufferIndex );
 
-    // 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(),
+    //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( bufferIndex,
                                                mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
 
     if ( NULL != mImpl->root )
     {
-      ProcessRenderTasks(  bufferIndex,
-                           mImpl->completeStatusManager,
-                           mImpl->taskList,
-                           *mImpl->root,
-                           mImpl->sortedLayers,
-                           mImpl->renderSortingHelper,
-                           mImpl->renderInstructions );
+      mImpl->renderTaskProcessor.Process( bufferIndex,
+                                        mImpl->taskList,
+                                        *mImpl->root,
+                                        mImpl->sortedLayers,
+                                        mImpl->renderInstructions );
 
       // Process the system-level RenderTasks last
       if ( NULL != mImpl->systemLevelRoot )
       {
-        ProcessRenderTasks(  bufferIndex,
-                             mImpl->completeStatusManager,
-                             mImpl->systemLevelTaskList,
-                             *mImpl->systemLevelRoot,
-                             mImpl->systemLevelSortedLayers,
-                             mImpl->renderSortingHelper,
-                             mImpl->renderInstructions );
+        mImpl->renderTaskProcessor.Process( bufferIndex,
+                                          mImpl->systemLevelTaskList,
+                                          *mImpl->systemLevelRoot,
+                                          mImpl->systemLevelSortedLayers,
+                                          mImpl->renderInstructions );
       }
     }
   }
@@ -1093,8 +1007,6 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
     mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
   }
 
-  PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
-
   // Macro is undefined in release build.
   SNAPSHOT_NODE_LOGGING;
 
@@ -1104,18 +1016,11 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
   // Check whether further updates are required
   unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
 
-#ifdef PERFORMANCE_MONITOR_ENABLED
-  // Always keep rendering when measuring FPS
-  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();
 
-  PERF_MONITOR_END(PerformanceMonitor::UPDATE);
+  // The update has finished; swap the double-buffering indices
+  mSceneGraphBuffers.Swap();
 
   return keepUpdating;
 }
@@ -1147,11 +1052,6 @@ unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
   }
 
-  if ( mImpl->dynamicsChanged )
-  {
-    keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
-  }
-
   if ( mImpl->renderTaskWaiting )
   {
     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
@@ -1200,20 +1100,247 @@ void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool syst
   }
 }
 
-#ifdef DALI_DYNAMICS_SUPPORT
+void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
+{
+  mImpl->shaderSaver = &upstream;
+}
+
+void UpdateManager::AddSampler( Render::Sampler* sampler )
+{
+  // Message has ownership of Sampler while in transit from update to render
+  typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > 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::AddSampler, sampler );
+}
+
+void UpdateManager::RemoveSampler( Render::Sampler* sampler )
+{
+  typedef MessageValue1< RenderManager, Render::Sampler* > 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::RemoveSampler, sampler );
+}
+
+void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
+{
+  typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > 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::SetFilterMode, sampler, minFilterMode, magFilterMode );
+}
+
+void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
+{
+  typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > 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::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
+}
+
+void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
+{
+  // Message has ownership of format while in transit from update -> render
+  typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > 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::AddPropertyBuffer, propertyBuffer );
+}
+
+void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
+{
+  typedef MessageValue1< RenderManager, Render::PropertyBuffer* > 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::RemovePropertyBuffer, propertyBuffer );
+}
+
+void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
+{
+  // Message has ownership of format while in transit from update -> render
+  typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > 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::SetPropertyBufferFormat, propertyBuffer, format );
+}
+
+void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
+{
+  // Message has ownership of format while in transit from update -> render
+  typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<char> >, size_t > 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::SetPropertyBufferData, propertyBuffer, data, size );
+}
+
+void UpdateManager::AddGeometry( Render::Geometry* geometry )
+{
+  // Message has ownership of format while in transit from update -> render
+  typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > 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::AddGeometry, geometry );
+}
+
+void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
+{
+  typedef MessageValue1< RenderManager, Render::Geometry* > 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::RemoveGeometry, geometry );
+}
 
-void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
+void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
 {
-  dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
-  mImpl->dynamicsWorld = dynamicsWorld;
+  typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > 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::SetGeometryType, geometry, geometryType );
+}
+
+void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
+{
+  typedef IndexBufferMessage< RenderManager > 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, geometry, indices );
+}
+
+void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
+{
+  typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > 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::RemoveVertexBuffer, geometry, propertyBuffer );
+}
+
+void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
+{
+  typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > 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::AddVertexBuffer, geometry, propertyBuffer );
 }
 
-void UpdateManager::TerminateDynamicsWorld()
+void UpdateManager::AddTexture( Render::Texture* texture )
 {
-  mImpl->dynamicsWorld.Reset();
+  // Message has ownership of Texture while in transit from update -> render
+  typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > 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::AddTexture, texture );
 }
 
-#endif // DALI_DYNAMICS_SUPPORT
+void UpdateManager::RemoveTexture( Render::Texture* texture)
+{
+  typedef MessageValue1< RenderManager, Render::Texture* > 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::RemoveTexture, texture );
+}
+
+void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
+{
+  typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
+}
+
+void UpdateManager::GenerateMipmaps( Render::Texture* texture )
+{
+  typedef MessageValue1< RenderManager, Render::Texture* > 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::GenerateMipmaps, texture );
+}
+
+void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
+{
+  typedef MessageValue1< RenderManager, Render::FrameBuffer* > 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::AddFrameBuffer, frameBuffer );
+}
+
+void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
+{
+  typedef MessageValue1< RenderManager, Render::FrameBuffer* > 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::RemoveFrameBuffer, frameBuffer );
+}
+
+void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, unsigned int mipmapLevel, unsigned int layer )
+{
+  typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, unsigned int, unsigned int > 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::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
+}
 
 } // namespace SceneGraph