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