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