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