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