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