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