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