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