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