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