a3f8b6e9e4db89f6410b6eeb246aea0dde22ea55
[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 lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
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( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
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,
1000                                     unsigned int lastVSyncTimeMilliseconds,
1001                                     unsigned int nextVSyncTimeMilliseconds )
1002 {
1003   PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE);   // Mark the End of the last frame
1004   PERF_MONITOR_NEXT_FRAME();             // Prints out performance info for the last frame (if enabled)
1005   PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
1006
1007   // Measure the time spent in UpdateManager::Update
1008   PERF_MONITOR_START(PerformanceMonitor::UPDATE);
1009
1010   // Update the frame time delta on the render thread.
1011   mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
1012
1013   // 1) Clear nodes/resources which were previously discarded
1014   mImpl->discardQueue.Clear( mSceneGraphBuffers.GetUpdateBufferIndex() );
1015
1016   // 2) Grab any loaded resources
1017   bool resourceChanged = mImpl->resourceManager.UpdateCache( mSceneGraphBuffers.GetUpdateBufferIndex() );
1018
1019   // 3) Process Touches & Gestures
1020   mImpl->touchResampler.Update();
1021   const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
1022
1023   const bool updateScene =                                            // The scene-graph requires an update if..
1024       mImpl->activeConstraints != 0 ||                                // ..constraints were active in previous frame OR
1025       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||              // ..nodes were dirty in previous frame OR
1026       IsAnimationRunning() ||                                         // ..at least one animation is running OR
1027       mImpl->dynamicsChanged ||                                       // ..there was a change in the dynamics simulation OR
1028       mImpl->messageQueue.IsSceneUpdateRequired() ||                  // ..a message that modifies the scene graph node tree is queued OR
1029       resourceChanged ||                                              // ..one or more resources were updated/changed OR
1030       gestureUpdated;                                                // ..a gesture property was updated
1031
1032   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1033   // values if the scene was updated in the previous frame.
1034   if( updateScene || mImpl->previousUpdateScene )
1035   {
1036     // 4) Reset properties from the previous update
1037     ResetProperties();
1038   }
1039
1040   // 5) Process the queued scene messages
1041   mImpl->messageQueue.ProcessMessages();
1042
1043   // 6) Post Process Ids of resources updated by renderer
1044   mImpl->resourceManager.PostProcessResources( mSceneGraphBuffers.GetUpdateBufferIndex() );
1045
1046   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1047   // renderer lists if the scene was updated in the previous frame.
1048   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1049   if( updateScene || mImpl->previousUpdateScene )
1050   {
1051     // 7) Animate
1052     Animate( elapsedSeconds );
1053
1054     // 8) Apply Constraints
1055     ApplyConstraints();
1056
1057 #ifdef DYNAMICS_SUPPORT
1058     // 9) Update dynamics simulation
1059     mImpl->dynamicsChanged = false;
1060     if( mImpl->dynamicsWorld )
1061     {
1062       mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1063     }
1064 #endif
1065
1066     // 10) Check Property Notifications
1067     ProcessPropertyNotifications();
1068
1069     // 11) Clear the lists of renderable-attachments from the previous update
1070     ClearRenderables( mImpl->sortedLayers );
1071     ClearRenderables( mImpl->systemLevelSortedLayers );
1072
1073     // 12) Update animated meshes
1074     UpdateMeshes( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->animatableMeshes );
1075
1076     // 13) Update materials. Prepares image resources
1077     UpdateMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1078
1079     // 14) Update node hierarchy and perform sorting / culling.
1080     //     This will populate each Layer with a list of renderers which are ready.
1081     UpdateNodes();
1082
1083     // 15) Prepare for the next render
1084     PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1085     PrepareMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials );
1086     PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->sortedLayers );
1087     PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->systemLevelSortedLayers );
1088     PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1089
1090     PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1091
1092     // 16) Process the RenderTasks; this creates the instructions for rendering the next frame.
1093     // reset the update buffer index and make sure there is enough room in the instruction container
1094     mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1095                                                mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1096
1097     if ( NULL != mImpl->root )
1098     {
1099       ProcessRenderTasks(  mSceneGraphBuffers.GetUpdateBufferIndex(),
1100                            mImpl->completeStatusManager,
1101                            mImpl->taskList,
1102                            *mImpl->root,
1103                            mImpl->sortedLayers,
1104                            mImpl->renderSortingHelper,
1105                            mImpl->renderInstructions );
1106
1107       // Process the system-level RenderTasks last
1108       if ( NULL != mImpl->systemLevelRoot )
1109       {
1110         ProcessRenderTasks(  mSceneGraphBuffers.GetUpdateBufferIndex(),
1111                              mImpl->completeStatusManager,
1112                              mImpl->systemLevelTaskList,
1113                              *mImpl->systemLevelRoot,
1114                              mImpl->systemLevelSortedLayers,
1115                              mImpl->renderSortingHelper,
1116                              mImpl->renderInstructions );
1117       }
1118     }
1119   }
1120
1121   // check the countdown and notify
1122   bool doRenderOnceNotify = false;
1123   mImpl->renderTaskWaiting = false;
1124   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1125   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1126         endIter != iter; ++iter )
1127   {
1128     RenderTask& renderTask(*(*iter));
1129
1130     renderTask.UpdateState();
1131
1132     if( renderTask.IsWaitingToRender() &&
1133         renderTask.ReadyToRender(mSceneGraphBuffers.GetUpdateBufferIndex()) /*avoid updating forever when source actor is off-stage*/ )
1134     {
1135       mImpl->renderTaskWaiting = true; // keep update/render threads alive
1136     }
1137
1138     if( renderTask.HasRendered() )
1139     {
1140       doRenderOnceNotify = true;
1141     }
1142   }
1143
1144   if( doRenderOnceNotify )
1145   {
1146     DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1147     mImpl->notificationManager.QueueMessage( NotifyFinishedMessage( *mImpl->renderTaskList ) );
1148   }
1149
1150   PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1151
1152   // Macro is undefined in release build.
1153   SNAPSHOT_NODE_LOGGING;
1154
1155   // A ResetProperties() may be required in the next frame
1156   mImpl->previousUpdateScene = updateScene;
1157
1158   // Check whether further updates are required
1159   unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1160
1161 #ifdef PERFORMANCE_MONITOR_ENABLED
1162   // Always keep rendering when measuring FPS
1163   keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1164 #endif
1165
1166   // The update has finished; swap the double-buffering indices
1167   mSceneGraphBuffers.Swap();
1168
1169   // tell the update manager that we're done so the queue can be given to event thread
1170   mImpl->notificationManager.UpdateCompleted();
1171
1172   PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1173
1174   return keepUpdating;
1175 }
1176
1177 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1178 {
1179   // Update the duration set via Stage::KeepRendering()
1180   if ( mImpl->keepRenderingSeconds > 0.0f )
1181   {
1182     mImpl->keepRenderingSeconds -= elapsedSeconds;
1183   }
1184
1185   unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1186
1187   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1188   // Keep updating until no messages are received and no animations are running.
1189   // If an animation has just finished, update at least once more for Discard end-actions.
1190   // No need to check for renderQueue as there is always a render after update and if that
1191   // render needs another update it will tell the adaptor to call update again
1192
1193   if ( mImpl->keepRenderingSeconds > 0.0f )
1194   {
1195     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1196   }
1197
1198   if ( !mImpl->messageQueue.WasEmpty() )
1199   {
1200     keepUpdatingRequest |= KeepUpdating::INCOMING_MESSAGES;
1201   }
1202
1203   if ( IsAnimationRunning() ||
1204        mImpl->animationFinishedDuringUpdate )
1205   {
1206     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1207   }
1208
1209   if ( mImpl->dynamicsChanged )
1210   {
1211     keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1212   }
1213
1214   if ( mImpl->renderTaskWaiting )
1215   {
1216     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1217   }
1218
1219   return keepUpdatingRequest;
1220 }
1221
1222 void UpdateManager::SetBackgroundColor( const Vector4& color )
1223 {
1224   typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1225
1226   // Reserve some memory inside the render queue
1227   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1228
1229   // Construct message in the render queue memory; note that delete should not be called on the return value
1230   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1231 }
1232
1233 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1234 {
1235   typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1236
1237   // Reserve some memory inside the render queue
1238   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1239
1240   // Construct message in the render queue memory; note that delete should not be called on the return value
1241   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceRect, rect );
1242 }
1243
1244 void UpdateManager::KeepRendering( float durationSeconds )
1245 {
1246   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1247 }
1248
1249 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1250 {
1251   if ( !systemLevel )
1252   {
1253     // just copy the vector of pointers
1254     mImpl->sortedLayers = layers;
1255   }
1256   else
1257   {
1258     mImpl->systemLevelSortedLayers = layers;
1259   }
1260 }
1261
1262 #ifdef DYNAMICS_SUPPORT
1263
1264 void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
1265 {
1266   dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
1267   mImpl->dynamicsWorld = dynamicsWorld;
1268 }
1269
1270 void UpdateManager::TerminateDynamicsWorld()
1271 {
1272   mImpl->dynamicsWorld.Reset();
1273 }
1274
1275 #endif // DYNAMICS_SUPPORT
1276
1277 } // namespace SceneGraph
1278
1279 } // namespace Internal
1280
1281 } // namespace Dali