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