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