Custom property owning objects
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-manager.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://floralicense.org/license/
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 // CLASS HEADER
18 #include <dali/internal/update/manager/update-manager.h>
19
20 // EXTERNAL INCLUDES
21 #include <set>
22
23 // INTERNAL INCLUDES
24 #include <dali/public-api/common/stage.h>
25
26 #include <dali/integration-api/core.h>
27 #include <dali/integration-api/render-controller.h>
28 #include <dali/integration-api/shader-data.h>
29 #include <dali/integration-api/debug.h>
30 #include <dali/integration-api/dynamics/dynamics-world-settings.h>
31
32 #include <dali/internal/common/core-impl.h>
33 #include <dali/internal/common/owner-container.h>
34 #include <dali/internal/common/message.h>
35
36 #include <dali/internal/event/common/notification-manager.h>
37 #include <dali/internal/event/common/property-notification-impl.h>
38 #include <dali/internal/event/common/property-notifier.h>
39 #include <dali/internal/event/animation/animation-finished-notifier.h>
40 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
41
42 #include <dali/internal/update/animation/scene-graph-animator.h>
43 #include <dali/internal/update/animation/scene-graph-animation.h>
44 #include <dali/internal/update/common/discard-queue.h>
45 #include <dali/internal/update/common/double-buffered.h>
46 #include <dali/internal/update/manager/prepare-render-algorithms.h>
47 #include <dali/internal/update/manager/process-render-tasks.h>
48 #include <dali/internal/update/resources/resource-manager.h>
49 #include <dali/internal/update/resources/complete-status-manager.h>
50 #include <dali/internal/update/common/scene-graph-buffers.h>
51 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
52 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
53 #include <dali/internal/update/manager/sorted-layers.h>
54 #include <dali/internal/update/manager/update-algorithms.h>
55 #include <dali/internal/update/queue/update-message-queue.h>
56 #include <dali/internal/update/manager/update-manager-debug.h>
57 #include <dali/internal/update/controllers/render-message-dispatcher.h>
58 #include <dali/internal/update/controllers/scene-controller-impl.h>
59 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
60 #include <dali/internal/update/modeling/scene-graph-material.h>
61 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
62 #include <dali/internal/update/nodes/node.h>
63 #include <dali/internal/update/nodes/scene-graph-layer.h>
64 #include <dali/internal/update/dynamics/scene-graph-dynamics-world.h>
65 #include <dali/internal/update/touch/touch-resampler.h>
66
67 #include <dali/internal/render/common/render-instruction-container.h>
68 #include <dali/internal/render/common/render-manager.h>
69 #include <dali/internal/render/queue/render-queue.h>
70 #include <dali/internal/render/common/performance-monitor.h>
71 #include <dali/internal/render/gl-resources/texture-cache.h>
72 #include <dali/internal/render/renderers/render-material.h>
73 #include <dali/internal/render/shaders/shader.h>
74
75 // Un-comment to enable node tree debug logging
76 //#define NODE_TREE_LOGGING 1
77
78 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
79 #define SNAPSHOT_NODE_LOGGING \
80 const int FRAME_COUNT_TRIGGER = 16;\
81 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
82   {\
83     if ( NULL != mImpl->root )\
84     {\
85       mImpl->frameCounter = 0;\
86       PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
87     }\
88   }\
89 mImpl->frameCounter++;
90 #else
91 #define SNAPSHOT_NODE_LOGGING
92 #endif
93
94 #if defined(DEBUG_ENABLED)
95 extern Debug::Filter* gRenderTaskLogFilter;
96 #endif
97
98
99 using namespace Dali::Integration;
100 using Dali::Internal::Update::MessageQueue;
101
102 namespace Dali
103 {
104
105 namespace Internal
106 {
107
108 namespace SceneGraph
109 {
110
111 namespace
112 {
113
114 const int DEFAULT_CAMERA_INDEX = -1;
115
116 void DestroyNodeSet( std::set<Node*>& nodeSet )
117 {
118   for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
119   {
120     Node* node( *iter );
121
122     // Call Node::OnDestroy as each node is destroyed
123     node->OnDestroy();
124
125     delete node;
126   }
127   nodeSet.clear();
128 }
129
130 } //namespace
131
132 typedef OwnerContainer< Shader* >              ShaderContainer;
133 typedef ShaderContainer::Iterator              ShaderIter;
134 typedef ShaderContainer::ConstIterator         ShaderConstIter;
135
136 typedef AnimatableMeshContainer::Iterator      AnimatableMeshIter;
137 typedef AnimatableMeshContainer::ConstIterator AnimatableMeshConstIter;
138 typedef MaterialContainer::Iterator            MaterialIter;
139
140 typedef OwnerContainer<PanGesture*>            GestureContainer;
141 typedef GestureContainer::Iterator             GestureIter;
142 typedef GestureContainer::ConstIterator        GestureConstIter;
143
144
145 /**
146  * Structure to contain UpdateManager internal data
147  */
148 struct UpdateManager::Impl
149 {
150   Impl( NotificationManager& notificationManager,
151         GlSyncAbstraction& glSyncAbstraction,
152         AnimationFinishedNotifier& animationFinishedNotifier,
153         PropertyNotifier& propertyNotifier,
154         ResourceManager& resourceManager,
155         DiscardQueue& discardQueue,
156         RenderController& renderController,
157         RenderManager& renderManager,
158         RenderQueue& renderQueue,
159         TextureCache& textureCache,
160         TouchResampler& touchResampler,
161         SceneGraphBuffers& sceneGraphBuffers )
162   :
163     renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
164     notificationManager( notificationManager ),
165     animationFinishedNotifier( animationFinishedNotifier ),
166     propertyNotifier( propertyNotifier ),
167     resourceManager( resourceManager ),
168     discardQueue( discardQueue ),
169     renderController( renderController ),
170     sceneController( NULL ),
171     renderManager( renderManager ),
172     renderQueue( renderQueue ),
173     renderInstructions( renderManager.GetRenderInstructionContainer() ),
174     completeStatusManager( glSyncAbstraction, renderMessageDispatcher, resourceManager ),
175     touchResampler( touchResampler ),
176     backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
177     taskList ( completeStatusManager ),
178     systemLevelTaskList ( completeStatusManager ),
179     root( NULL ),
180     systemLevelRoot( NULL ),
181     defaultShader( NULL ),
182     messageQueue( renderController, sceneGraphBuffers ),
183     dynamicsWorld( NULL ),
184     dynamicsChanged( false ),
185     keepRenderingSeconds( 0.0f ),
186     animationFinishedDuringUpdate( false ),
187     activeConstraints( 0 ),
188     nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
189     previousUpdateScene( false ),
190     frameCounter( 0 ),
191     renderSortingHelper(),
192     renderTaskList( NULL ),
193     renderTaskWaiting( false )
194   {
195     sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
196   }
197
198   ~Impl()
199   {
200     // Disconnect render tasks from nodes, before destroying the nodes
201     RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
202     for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
203     {
204       (*iter)->SetSourceNode( NULL );
205     }
206     // ..repeat for system level RenderTasks
207     RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
208     for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
209     {
210       (*iter)->SetSourceNode( NULL );
211     }
212
213     // UpdateManager owns the Nodes
214     DestroyNodeSet( activeDisconnectedNodes );
215     DestroyNodeSet( connectedNodes );
216     DestroyNodeSet( disconnectedNodes );
217
218     // If there is root, reset it, otherwise do nothing as rendering was never started
219     if( root )
220     {
221       root->OnDestroy();
222
223       delete root;
224       root = NULL;
225     }
226
227     if( systemLevelRoot )
228     {
229       systemLevelRoot->OnDestroy();
230
231       delete systemLevelRoot;
232       systemLevelRoot = NULL;
233     }
234
235     sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
236     delete sceneController;
237   }
238
239   SceneGraphBuffers                   sceneGraphBuffers;             ///< Used to keep track of which buffers are being written or read
240   RenderMessageDispatcher             renderMessageDispatcher;       ///< Used for passing messages to the render-thread
241   NotificationManager&                notificationManager;           ///< Queues notification messages for the event-thread.
242   AnimationFinishedNotifier&          animationFinishedNotifier;     ///< Provides notification to applications when animations are finished.
243   PropertyNotifier&                   propertyNotifier;              ///< Provides notification to applications when properties are modified.
244   ResourceManager&                    resourceManager;               ///< resource manager
245   DiscardQueue&                       discardQueue;                  ///< Nodes are added here when disconnected from the scene-graph.
246   RenderController&                   renderController;              ///< render controller
247   SceneControllerImpl*                sceneController;               ///< scene controller
248   RenderManager&                      renderManager;                 ///< This is responsible for rendering the results of each "update"
249   RenderQueue&                        renderQueue;                   ///< Used to queue messages for the next render
250   RenderInstructionContainer&         renderInstructions;            ///< Used to prepare the render instructions
251   CompleteStatusManager               completeStatusManager;         ///< Complete Status Manager
252   TouchResampler&                     touchResampler;                ///< Used to resample touch events on every update.
253
254   Vector4                             backgroundColor;               ///< The glClear color used at the beginning of each frame.
255
256   RenderTaskList                      taskList;                      ///< The list of scene graph render-tasks
257   RenderTaskList                      systemLevelTaskList;           ///< Separate render-tasks for system-level content
258
259   Layer*                              root;                          ///< The root node (root is a layer)
260   Layer*                              systemLevelRoot;               ///< A separate root-node for system-level content
261   std::set< Node* >                   activeDisconnectedNodes;       ///< A container of new or modified nodes (without parent) owned by UpdateManager
262   std::set< Node* >                   connectedNodes;                ///< A container of connected (with parent) nodes owned by UpdateManager
263   std::set< Node* >                   disconnectedNodes;             ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager
264
265   SortedLayerPointers                 sortedLayers;                  ///< A container of Layer pointers sorted by depth
266   SortedLayerPointers                 systemLevelSortedLayers;       ///< A separate container of system-level Layers
267
268   OwnerContainer< PropertyOwner* >    customObjects;                 ///< A container of owned objects (with custom properties)
269
270   AnimationContainer                  animations;                    ///< A container of owned animations
271   PropertyNotificationContainer       propertyNotifications;         ///< A container of owner property notifications.
272
273   Shader*                             defaultShader;                 ///< The default shader; owned by ShaderContainer
274   ShaderContainer                     shaders;                       ///< A container of owned shaders
275   AnimatableMeshContainer             animatableMeshes;              ///< A container of owned animatable meshes
276   MaterialContainer                   materials;                     ///< A container of owned materials
277
278   MessageQueue                        messageQueue;                  ///< The messages queued from the event-thread
279
280   OwnerPointer<DynamicsWorld>         dynamicsWorld;                 ///< Wrapper for dynamics simulation
281   bool                                dynamicsChanged;               ///< This is set to true if an object is changed in the dynamics simulation tick
282
283   float                               keepRenderingSeconds;          ///< Set via Dali::Stage::KeepRendering
284   bool                                animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
285
286   unsigned int                        activeConstraints;             ///< number of active constraints from previous frame
287   int                                 nodeDirtyFlags;                ///< cumulative node dirty flags from previous frame
288   bool                                previousUpdateScene;           ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
289
290   int                                 frameCounter;                  ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
291   RendererSortingHelper               renderSortingHelper;           ///< helper used to sort transparent renderers
292
293   Internal::RenderTaskList*           renderTaskList;                ///< Stores a pointer to the internal implementation to the render task list.
294   GestureContainer                    gestures;                      ///< A container of owned gesture detectors
295   bool                                renderTaskWaiting;             ///< A REFRESH_ONCE render task is waiting to be rendered
296 };
297
298 UpdateManager::UpdateManager( NotificationManager& notificationManager,
299                               GlSyncAbstraction& glSyncAbstraction,
300                               AnimationFinishedNotifier& animationFinishedNotifier,
301                               PropertyNotifier& propertyNotifier,
302                               ResourceManager& resourceManager,
303                               DiscardQueue& discardQueue,
304                               RenderController& controller,
305                               RenderManager& renderManager,
306                               RenderQueue& renderQueue,
307                               TextureCache& textureCache,
308                               TouchResampler& touchResampler )
309   : mImpl(NULL)
310 {
311   mImpl = new Impl( notificationManager,
312                     glSyncAbstraction,
313                     animationFinishedNotifier,
314                     propertyNotifier,
315                     resourceManager,
316                     discardQueue,
317                     controller,
318                     renderManager,
319                     renderQueue,
320                     textureCache,
321                     touchResampler,
322                     mSceneGraphBuffers );
323
324   textureCache.SetBufferIndices( &mSceneGraphBuffers );
325 }
326
327 UpdateManager::~UpdateManager()
328 {
329   delete mImpl;
330 }
331
332 void UpdateManager::SetRenderTaskList( Internal::RenderTaskList* renderTaskList )
333 {
334   mImpl->renderTaskList = renderTaskList;
335 }
336
337 EventToUpdate& UpdateManager::GetEventToUpdate()
338 {
339   return mImpl->messageQueue;
340 }
341
342 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
343 {
344   DALI_ASSERT_DEBUG( layer->IsLayer() );
345   DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
346
347   if ( !systemLevel )
348   {
349     DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
350     mImpl->root = layer;
351   }
352   else
353   {
354     DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
355     mImpl->systemLevelRoot = layer;
356   }
357
358   layer->SetRoot(true);
359 }
360
361 void UpdateManager::AddNode( Node* node )
362 {
363   DALI_ASSERT_ALWAYS( NULL != node );
364   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
365
366   mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
367 }
368
369 void UpdateManager::ConnectNode( Node* parent, Node* node )
370 {
371   DALI_ASSERT_ALWAYS( NULL != parent );
372   DALI_ASSERT_ALWAYS( NULL != node );
373   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
374
375   // Move from active/disconnectedNodes to connectedNodes
376   std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
377   if( !removed )
378   {
379     removed = mImpl->disconnectedNodes.erase( node );
380     DALI_ASSERT_ALWAYS( removed );
381   }
382   mImpl->connectedNodes.insert( node );
383
384   node->SetActive( true );
385
386   parent->ConnectChild( node );
387 }
388
389 void UpdateManager::DisconnectNode( Node* node )
390 {
391   Node* parent = node->GetParent();
392   DALI_ASSERT_ALWAYS( NULL != parent );
393   parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
394
395   // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
396   parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
397 }
398
399 void UpdateManager::SetNodeActive( Node* node )
400 {
401   DALI_ASSERT_ALWAYS( NULL != node );
402   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
403
404   // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
405   std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
406   DALI_ASSERT_ALWAYS( removed );
407   mImpl->activeDisconnectedNodes.insert( node );
408
409   node->SetActive( true );
410 }
411
412 void UpdateManager::DestroyNode( Node* node )
413 {
414   DALI_ASSERT_ALWAYS( NULL != node );
415   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
416
417   // Transfer ownership from new/disconnectedNodes to the discard queue
418   // This keeps the nodes alive, until the render-thread has finished with them
419   std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
420   if( !removed )
421   {
422     removed = mImpl->disconnectedNodes.erase( node );
423     DALI_ASSERT_ALWAYS( removed );
424   }
425   mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
426
427   // Notify the Node about impending destruction
428   node->OnDestroy();
429 }
430
431 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
432 {
433   DALI_ASSERT_DEBUG( node != NULL );
434   DALI_ASSERT_DEBUG( attachment != NULL );
435
436   // attach node to attachment first so that parent is known by the time attachment is connected
437   node->Attach( *attachment ); // node takes ownership
438   attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
439 }
440
441 void UpdateManager::AddObject( PropertyOwner* object )
442 {
443   DALI_ASSERT_DEBUG( NULL != object );
444
445   mImpl->customObjects.PushBack( object );
446 }
447
448 void UpdateManager::RemoveObject( PropertyOwner* object )
449 {
450   DALI_ASSERT_DEBUG( NULL != object );
451
452   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
453
454   // Find the object and destroy it
455   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
456   {
457     PropertyOwner* current = *iter;
458     if ( current == object )
459     {
460       customObjects.Erase( iter );
461       return;
462     }
463   }
464
465   // Should not reach here
466   DALI_ASSERT_DEBUG(false);
467 }
468
469 void UpdateManager::AddAnimation( Animation* animation )
470 {
471   mImpl->animations.PushBack( animation );
472 }
473
474 void UpdateManager::StopAnimation( Animation* animation )
475 {
476   DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
477
478   bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
479
480   mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
481 }
482
483 void UpdateManager::RemoveAnimation( Animation* animation )
484 {
485   DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
486
487   animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
488
489   DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
490 }
491
492 bool UpdateManager::IsAnimationRunning() const
493 {
494   bool isRunning(false);
495   AnimationContainer& animations = mImpl->animations;
496
497   // Find any animation that isn't stopped or paused
498
499   const AnimationIter endIter = animations.End();
500   for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
501   {
502     const Animation::State state = (*iter)->GetState();
503
504     if (state != Animation::Stopped &&
505         state != Animation::Paused)
506     {
507       isRunning = true;
508     }
509   }
510
511   return isRunning;
512 }
513
514 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
515 {
516   mImpl->propertyNotifications.PushBack( propertyNotification );
517 }
518
519 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
520 {
521   PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
522   PropertyNotificationIter iter = propertyNotifications.Begin();
523
524   while ( iter != propertyNotifications.End() )
525   {
526     if( *iter == propertyNotification )
527     {
528       propertyNotifications.Erase(iter);
529       break;
530     }
531     ++iter;
532   }
533 }
534
535 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
536 {
537   DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
538   propertyNotification->SetNotifyMode( notifyMode );
539 }
540
541 Shader* UpdateManager::GetDefaultShader()
542 {
543   return mImpl->defaultShader;
544 }
545
546 void UpdateManager::AddShader( Shader* shader )
547 {
548   DALI_ASSERT_DEBUG( NULL != shader );
549
550   // Note: The first shader added becomes the default shader
551   if( NULL == mImpl->defaultShader )
552   {
553     mImpl->defaultShader = shader;
554   }
555
556   mImpl->shaders.PushBack( shader );
557
558   // Allows the shader to dispatch texture requests to the cache and "save shader"
559   // requests to the resource manager from the render thread.
560   shader->Initialize( mImpl->renderManager, mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
561 }
562
563 void UpdateManager::RemoveShader(Shader* shader)
564 {
565   DALI_ASSERT_DEBUG(shader != NULL);
566
567   ShaderContainer& shaders = mImpl->shaders;
568
569   // Find the shader and destroy it
570   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
571   {
572     Shader& current = **iter;
573     if ( &current == shader )
574     {
575       // Transfer ownership to the discard queue
576       // This keeps the shader alive, until the render-thread has finished with it
577       mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
578
579       return;
580     }
581   }
582   // Should not reach here
583   DALI_ASSERT_DEBUG(false);
584 }
585
586 void UpdateManager::SetShaderProgram( Shader* shader, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash )
587 {
588   DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash);
589
590   DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
591
592   Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
593   shaderData->SetHashValue( shaderHash );
594
595   if( shaderData )
596   {
597     // This is done in the render thread, to allow GL program compilation
598     // Will trigger a NotifySaveRequest back to updateManager to forward onto ResourceClient
599     typedef MessageValue5< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::ShaderDataPtr, Context* > DerivedType;
600
601     // Reserve some memory inside the render queue
602     unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
603
604     // Construct message in the render queue memory; note that delete should not be called on the return value
605     new (slot) DerivedType( shader, &Shader::SetProgram, geometryType, subType, resourceId, shaderData, &(mImpl->renderManager.GetContext()) );
606   }
607 }
608
609 void UpdateManager::AddAnimatableMesh( AnimatableMesh* animatableMesh )
610 {
611   mImpl->animatableMeshes.PushBack(animatableMesh);
612 }
613
614 void UpdateManager::RemoveAnimatableMesh( AnimatableMesh* animatableMesh )
615 {
616   DALI_ASSERT_DEBUG(animatableMesh != NULL);
617
618   AnimatableMeshContainer& animatableMeshes = mImpl->animatableMeshes;
619
620   // Find the animatableMesh and destroy it
621   for ( AnimatableMeshIter iter = animatableMeshes.Begin(); iter != animatableMeshes.End(); ++iter )
622   {
623     AnimatableMesh& current = **iter;
624     if ( &current == animatableMesh )
625     {
626       animatableMeshes.Erase( iter );
627       break;
628     }
629   }
630 }
631
632 void UpdateManager::AddMaterial( Material* material )
633 {
634   DALI_ASSERT_DEBUG( NULL != material );
635
636   mImpl->materials.PushBack( material );
637   RenderMaterial* renderMaterial = new RenderMaterial();
638
639   typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
640
641   // Reserve some memory inside the render queue
642   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
643
644   // Construct message in the render queue memory; note that delete should not be called on the return value
645   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddRenderMaterial, renderMaterial );
646
647   material->SetRenderMaterial( renderMaterial );
648   material->OnStageConnection( *mImpl->sceneController );
649 }
650
651 void UpdateManager::RemoveMaterial( Material* theMaterial )
652 {
653   // Caused by last reference to material being released (e.g. app or internal mesh-actor)
654
655   for ( MaterialIter iter=mImpl->materials.Begin(), end=mImpl->materials.End() ; iter != end ; ++iter )
656   {
657     const Material* aMaterial = *iter;
658
659     if( aMaterial == theMaterial )
660     {
661       typedef MessageValue1< RenderManager, RenderMaterial* > DerivedType;
662
663       // Reserve some memory inside the render queue
664       unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
665
666       // Construct message in the render queue memory; note that delete should not be called on the return value
667       new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveRenderMaterial, theMaterial->GetRenderMaterial() );
668
669       mImpl->materials.Erase( iter );
670       break;
671     }
672   }
673 }
674
675 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
676 {
677   if ( !systemLevel )
678   {
679     // copy the list, this is only likely to happen once in application life cycle
680     return &(mImpl->taskList);
681   }
682   else
683   {
684     // copy the list, this is only likely to happen once in application life cycle
685     return &(mImpl->systemLevelTaskList);
686   }
687 }
688
689 void UpdateManager::AddGesture( PanGesture* gesture )
690 {
691   DALI_ASSERT_DEBUG( NULL != gesture );
692
693   mImpl->gestures.PushBack( gesture );
694 }
695
696 void UpdateManager::RemoveGesture( PanGesture* gesture )
697 {
698   DALI_ASSERT_DEBUG( gesture != NULL );
699
700   GestureContainer& gestures = mImpl->gestures;
701
702   // Find the gesture and destroy it
703   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
704   {
705     PanGesture& current = **iter;
706     if ( &current == gesture )
707     {
708       mImpl->gestures.Erase( iter );
709       return;
710     }
711   }
712   // Should not reach here
713   DALI_ASSERT_DEBUG(false);
714 }
715
716 void UpdateManager::ResetNodeProperty( Node& node )
717 {
718   node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
719 }
720
721 void UpdateManager::ResetProperties()
722 {
723   PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
724
725   // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
726   mImpl->animationFinishedDuringUpdate = false;
727
728   // Animated properties have to be reset to their original value each frame
729
730   // Reset node properties
731   if ( mImpl->root )
732   {
733     ResetNodeProperty( *mImpl->root );
734   }
735
736   if ( mImpl->systemLevelRoot )
737   {
738     ResetNodeProperty( *mImpl->systemLevelRoot );
739   }
740
741   // Reset the Connected Nodes
742   const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
743   for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
744   {
745     ResetNodeProperty( **iter );
746   }
747
748   // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
749   for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
750   {
751     Node* node = *iter;
752     node->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
753     node->SetActive( false );
754
755     // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
756     mImpl->activeDisconnectedNodes.erase( iter );
757     mImpl->disconnectedNodes.insert( node );
758   }
759
760   // Reset system-level render-task list properties to base values
761   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
762
763   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
764   {
765     (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
766   }
767
768   // Reset render-task list properties to base values.
769   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
770
771   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
772   {
773     (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
774   }
775
776   // Reset custom object properties to base values
777   for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
778   {
779     (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
780   }
781
782   // Reset animatable shader properties to base values
783   for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
784   {
785     (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
786   }
787
788   // Reset animatable animatable mesh properties to base values
789   for ( AnimatableMeshIter iter = mImpl->animatableMeshes.Begin(); iter != mImpl->animatableMeshes.End(); ++iter )
790   {
791     (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
792   }
793
794   PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
795 }
796
797 void UpdateManager::ProcessGestures( unsigned int nextRenderTime )
798 {
799   // constrain gestures... (in construction order)
800   GestureContainer& gestures = mImpl->gestures;
801
802   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
803   {
804     PanGesture& gesture = **iter;
805     gesture.UpdateProperties( nextRenderTime );
806   }
807 }
808
809 void UpdateManager::Animate( float elapsedSeconds )
810 {
811   PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
812
813   AnimationContainer &animations = mImpl->animations;
814   AnimationIter iter = animations.Begin();
815   while ( iter != animations.End() )
816   {
817     Animation* animation = *iter;
818     bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
819
820     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
821
822     // Remove animations that had been destroyed but were still waiting for an update
823     if (animation->GetState() == Animation::Destroyed)
824     {
825       iter = animations.Erase(iter);
826     }
827     else
828     {
829       ++iter;
830     }
831   }
832
833   if ( mImpl->animationFinishedDuringUpdate )
834   {
835     // The application should be notified by NotificationManager, in another thread
836     mImpl->notificationManager.QueueMessage( AnimationFinishedMessage( mImpl->animationFinishedNotifier ) );
837   }
838
839   PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
840 }
841
842 void UpdateManager::ApplyConstraints()
843 {
844   PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
845
846   mImpl->activeConstraints = 0;
847
848   // constrain custom objects... (in construction order)
849   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
850
851   const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
852   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
853   {
854     PropertyOwner& object = **iter;
855     mImpl->activeConstraints += ConstrainPropertyOwner( object, mSceneGraphBuffers.GetUpdateBufferIndex() );
856   }
857
858   // constrain nodes... (in Depth First traversal order)
859   if ( mImpl->root )
860   {
861     mImpl->activeConstraints += ConstrainNodes( *(mImpl->root), mSceneGraphBuffers.GetUpdateBufferIndex() );
862   }
863
864   if ( mImpl->systemLevelRoot )
865   {
866     mImpl->activeConstraints += ConstrainNodes( *(mImpl->systemLevelRoot), mSceneGraphBuffers.GetUpdateBufferIndex() );
867   }
868
869   // constrain other property-owners after nodes as they are more likely to depend on a node's
870   // current frame property than vice versa. They tend to be final constraints (no further
871   // constraints depend on their properties)
872   // e.g. ShaderEffect uniform a function of Actor's position.
873   // Mesh vertex a function of Actor's position or world position.
874
875   // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
876   // they can be all processed in a super-list of property-owners.
877
878   // Constrain system-level render-tasks
879   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
880
881   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
882   {
883     RenderTask& task = **iter;
884     mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
885   }
886
887   // Constrain render-tasks
888   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
889
890   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
891   {
892     RenderTask& task = **iter;
893     mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() );
894   }
895
896   // constrain meshes (in construction order)
897   AnimatableMeshContainer& meshes = mImpl->animatableMeshes;
898   for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
899   {
900     AnimatableMesh& mesh = **iter;
901     mImpl->activeConstraints += ConstrainPropertyOwner( mesh, mSceneGraphBuffers.GetUpdateBufferIndex() );
902   }
903
904   // constrain shaders... (in construction order)
905   ShaderContainer& shaders = mImpl->shaders;
906
907   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
908   {
909     Shader& shader = **iter;
910     mImpl->activeConstraints += ConstrainPropertyOwner( shader, mSceneGraphBuffers.GetUpdateBufferIndex() );
911   }
912
913   PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
914 }
915
916 void UpdateManager::ProcessPropertyNotifications()
917 {
918   PropertyNotificationContainer &notifications = mImpl->propertyNotifications;
919   PropertyNotificationIter iter = notifications.Begin();
920
921   while ( iter != notifications.End() )
922   {
923     PropertyNotification* notification = *iter;
924
925     bool valid = notification->Check( mSceneGraphBuffers.GetUpdateBufferIndex() );
926
927     if(valid)
928     {
929       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
930     }
931     ++iter;
932   }
933 }
934
935 void UpdateManager::UpdateNodes()
936 {
937   mImpl->nodeDirtyFlags = NothingFlag;
938
939   if ( !mImpl->root )
940   {
941     return;
942   }
943
944   PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
945
946   Shader* defaultShader = GetDefaultShader();
947
948   if ( NULL != defaultShader )
949   {
950     // Prepare resources, update shaders, update attachments, for each node
951     // And add the renderers to the sorted layers. Start from root, which is also a layer
952     mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
953                                                        mSceneGraphBuffers.GetUpdateBufferIndex(),
954                                                        mImpl->resourceManager,
955                                                        mImpl->renderQueue,
956                                                        defaultShader );
957
958     if ( mImpl->systemLevelRoot )
959     {
960       mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
961                                                           mSceneGraphBuffers.GetUpdateBufferIndex(),
962                                                           mImpl->resourceManager,
963                                                           mImpl->renderQueue,
964                                                           defaultShader );
965     }
966   }
967
968   PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
969 }
970
971 void UpdateManager::UpdateMeshes( BufferIndex updateBufferIndex, AnimatableMeshContainer& meshes )
972 {
973   for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter )
974   {
975     AnimatableMesh& current = **iter;
976     current.UpdateMesh( updateBufferIndex );
977   }
978 }
979
980 void UpdateManager::UpdateMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
981 {
982   for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
983   {
984     Material* material = *iter;
985     material->PrepareResources( updateBufferIndex, mImpl->resourceManager );
986   }
987 }
988
989 void UpdateManager::PrepareMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials )
990 {
991   for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ )
992   {
993     Material* material = *iter;
994     material->PrepareRender( updateBufferIndex );
995   }
996 }
997
998 unsigned int UpdateManager::Update( float elapsedSeconds, unsigned int lastRenderTime, unsigned int nextRenderTime )
999 {
1000   PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE);   // Mark the End of the last frame
1001   PERF_MONITOR_NEXT_FRAME();             // Prints out performance info for the last frame (if enabled)
1002   PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
1003
1004   // Measure the time spent in UpdateManager::Update
1005   PERF_MONITOR_START(PerformanceMonitor::UPDATE);
1006
1007   // Update the frame time delta on the render thread.
1008   mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
1009
1010   // 1) Clear nodes/resources which were previously discarded
1011   mImpl->discardQueue.Clear( mSceneGraphBuffers.GetUpdateBufferIndex() );
1012
1013   // 2) Grab any loaded resources
1014   bool resourceChanged = mImpl->resourceManager.UpdateCache( mSceneGraphBuffers.GetUpdateBufferIndex() );
1015
1016   const bool updateScene =                                            // The scene-graph requires an update if..
1017       mImpl->activeConstraints != 0 ||                                // ..constraints were active in previous frame OR
1018       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||              // ..nodes were dirty in previous frame OR
1019       IsAnimationRunning() ||                                         // ..at least one animation is running OR
1020       mImpl->dynamicsChanged ||                                       // ..there was a change in the dynamics simulation OR
1021       mImpl->messageQueue.IsSceneUpdateRequired() ||                  // ..a message that modifies the scene graph node tree is queued
1022       resourceChanged;                                                // one or more resources were updated/changed
1023
1024   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1025   // values if the scene was updated in the previous frame.
1026   if( updateScene || mImpl->previousUpdateScene )
1027   {
1028     // 3) Reset properties from the previous update
1029     ResetProperties();
1030   }
1031
1032   // 4) Process the queued scene messages
1033   mImpl->messageQueue.ProcessMessages();
1034
1035   // 5) Post Process Ids of resources updated by renderer
1036   mImpl->resourceManager.PostProcessResources( mSceneGraphBuffers.GetUpdateBufferIndex() );
1037
1038   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1039   // renderer lists if the scene was updated in the previous frame.
1040   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1041   if( updateScene || mImpl->previousUpdateScene )
1042   {
1043     // 6) Process Touches & Gestures
1044     mImpl->touchResampler.Update();
1045     ProcessGestures( nextRenderTime );
1046
1047     // 7) Animate
1048     Animate( elapsedSeconds );
1049
1050     // 8) Apply Constraints
1051     ApplyConstraints();
1052
1053     // 9) Update dynamics simulation
1054     mImpl->dynamicsChanged = false;
1055     if( mImpl->dynamicsWorld )
1056     {
1057       mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1058     }
1059
1060     // 10) Check Property Notifications
1061     ProcessPropertyNotifications();
1062
1063     // 11) Clear the lists of renderable-attachments from the previous update
1064     ClearRenderables( mImpl->sortedLayers );
1065     ClearRenderables( mImpl->systemLevelSortedLayers );
1066
1067     // 12) Update animated meshes
1068     UpdateMeshes( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->animatableMeshes );
1069
1070     // 13) Update materials. Prepares image resources
1071     UpdateMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1072
1073     // 14) Update node hierarchy and perform sorting / culling.
1074     //     This will populate each Layer with a list of renderers which are ready.
1075     UpdateNodes();
1076
1077     // 15) Prepare for the next render
1078     PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1079     PrepareMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1080     PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->sortedLayers );
1081     PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->systemLevelSortedLayers );
1082     PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1083
1084     PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1085
1086     // 16) Process the RenderTasks; this creates the instructions for rendering the next frame.
1087     // reset the update buffer index and make sure there is enough room in the instruction container
1088     mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1089                                                mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1090
1091     if ( NULL != mImpl->root )
1092     {
1093       ProcessRenderTasks(  mSceneGraphBuffers.GetUpdateBufferIndex(),
1094                            mImpl->completeStatusManager,
1095                            mImpl->taskList,
1096                            *mImpl->root,
1097                            mImpl->sortedLayers,
1098                            mImpl->renderSortingHelper,
1099                            mImpl->renderInstructions );
1100
1101       // Process the system-level RenderTasks last
1102       if ( NULL != mImpl->systemLevelRoot )
1103       {
1104         ProcessRenderTasks(  mSceneGraphBuffers.GetUpdateBufferIndex(),
1105                              mImpl->completeStatusManager,
1106                              mImpl->systemLevelTaskList,
1107                              *mImpl->systemLevelRoot,
1108                              mImpl->systemLevelSortedLayers,
1109                              mImpl->renderSortingHelper,
1110                              mImpl->renderInstructions );
1111       }
1112
1113       // if dynamics enabled and active...update matrices for debug drawing
1114       if( mImpl->dynamicsWorld && mImpl->dynamicsChanged )
1115       {
1116         RenderTask* task(mImpl->taskList.GetTasks()[0]);
1117         if( task )
1118         {
1119           mImpl->dynamicsWorld->UpdateMatrices( task->GetProjectionMatrix(mSceneGraphBuffers.GetUpdateBufferIndex()),
1120                                                 task->GetViewMatrix(mSceneGraphBuffers.GetUpdateBufferIndex()) );
1121         }
1122       }
1123     }
1124   }
1125
1126   // check the countdown and notify
1127   bool doRenderOnceNotify = false;
1128   mImpl->renderTaskWaiting = false;
1129   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1130   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1131         endIter != iter; ++iter )
1132   {
1133     RenderTask& renderTask(*(*iter));
1134
1135     if( renderTask.IsWaitingToRender() )
1136     {
1137       mImpl->renderTaskWaiting = true; // keep update/render threads alive
1138     }
1139
1140     if( renderTask.HasRendered() )
1141     {
1142       doRenderOnceNotify = true;
1143     }
1144   }
1145
1146   if( doRenderOnceNotify )
1147   {
1148     DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1149     mImpl->notificationManager.QueueMessage( NotifyFinishedMessage( *mImpl->renderTaskList ) );
1150   }
1151
1152   PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1153
1154   // Macro is undefined in release build.
1155   SNAPSHOT_NODE_LOGGING;
1156
1157   // A ResetProperties() may be required in the next frame
1158   mImpl->previousUpdateScene = updateScene;
1159
1160   // Check whether further updates are required
1161   unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1162
1163 #ifdef PERFORMANCE_MONITOR_ENABLED
1164   // Always keep rendering when measuring FPS
1165   keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1166 #endif
1167
1168   // The update has finished; swap the double-buffering indices
1169   mSceneGraphBuffers.Swap();
1170
1171   PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1172
1173   return keepUpdating;
1174 }
1175
1176 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1177 {
1178   // Update the duration set via Stage::KeepRendering()
1179   if ( mImpl->keepRenderingSeconds > 0.0f )
1180   {
1181     mImpl->keepRenderingSeconds -= elapsedSeconds;
1182   }
1183
1184   unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1185
1186   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1187   // Keep updating until no messages are received and no animations are running.
1188   // If an animation has just finished, update at least once more for Discard end-actions.
1189   // No need to check for renderQueue as there is always a render after update and if that
1190   // render needs another update it will tell the adaptor to call update again
1191
1192   if ( mImpl->keepRenderingSeconds > 0.0f )
1193   {
1194     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1195   }
1196
1197   if ( !mImpl->messageQueue.WasEmpty() )
1198   {
1199     keepUpdatingRequest |= KeepUpdating::INCOMING_MESSAGES;
1200   }
1201
1202   if ( IsAnimationRunning() ||
1203        mImpl->animationFinishedDuringUpdate )
1204   {
1205     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1206   }
1207
1208   if ( mImpl->dynamicsChanged )
1209   {
1210     keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1211   }
1212
1213   if ( mImpl->renderTaskWaiting )
1214   {
1215     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1216   }
1217
1218   return keepUpdatingRequest;
1219 }
1220
1221 void UpdateManager::SetBackgroundColor( const Vector4& color )
1222 {
1223   typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1224
1225   // Reserve some memory inside the render queue
1226   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1227
1228   // Construct message in the render queue memory; note that delete should not be called on the return value
1229   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1230 }
1231
1232 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1233 {
1234   typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1235
1236   // Reserve some memory inside the render queue
1237   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1238
1239   // Construct message in the render queue memory; note that delete should not be called on the return value
1240   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceRect, rect );
1241 }
1242
1243 void UpdateManager::KeepRendering( float durationSeconds )
1244 {
1245   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1246 }
1247
1248 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1249 {
1250   if ( !systemLevel )
1251   {
1252     // just copy the vector of pointers
1253     mImpl->sortedLayers = layers;
1254   }
1255   else
1256   {
1257     mImpl->systemLevelSortedLayers = layers;
1258   }
1259 }
1260
1261 void UpdateManager::InitializeDynamicsWorld( DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings, Shader* debugShader )
1262 {
1263   dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, debugShader, &mSceneGraphBuffers );
1264   mImpl->dynamicsWorld = dynamicsWorld;
1265
1266   typedef MessageValue1< RenderManager, DynamicsDebugRenderer* > DerivedType;
1267
1268   // Reserve some memory inside the render queue
1269   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1270
1271   // Construct message in the render queue memory; note that delete should not be called on the return value
1272   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::InitializeDynamicsDebugRenderer, &dynamicsWorld->GetDebugRenderer() );
1273 }
1274
1275 void UpdateManager::TerminateDynamicsWorld()
1276 {
1277   mImpl->dynamicsWorld.Reset();
1278 }
1279
1280 } // namespace SceneGraph
1281
1282 } // namespace Internal
1283
1284 } // namespace Dali