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