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