Merge remote-tracking branch 'origin/tizen' into devel/new_mesh
[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/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/effects/scene-graph-material.h>
46 #include <dali/internal/update/effects/scene-graph-sampler.h>
47 #include <dali/internal/update/geometry/scene-graph-geometry.h>
48 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
49 #include <dali/internal/update/manager/object-owner-container.h>
50 #include <dali/internal/update/manager/prepare-render-algorithms.h>
51 #include <dali/internal/update/manager/process-render-tasks.h>
52 #include <dali/internal/update/manager/sorted-layers.h>
53 #include <dali/internal/update/manager/update-algorithms.h>
54 #include <dali/internal/update/manager/update-manager-debug.h>
55 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
56 #include <dali/internal/update/node-attachments/scene-graph-renderer-attachment.h>
57 #include <dali/internal/update/node-attachments/scene-graph-image-attachment.h>
58 #include <dali/internal/update/nodes/node.h>
59 #include <dali/internal/update/nodes/scene-graph-layer.h>
60 #include <dali/internal/update/queue/update-message-queue.h>
61 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
62 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.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, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash, bool modifiesGeometry )
617 {
618   DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash);
619
620   DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" );
621
622   Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) );
623   if( shaderData )
624   {
625     shaderData->SetHashValue( shaderHash );
626     shaderData->SetResourceId( resourceId );
627
628     typedef MessageValue6< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::ShaderDataPtr, ProgramCache*, bool> DerivedType;
629
630     // Reserve some memory inside the render queue
631     unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
632
633     // Construct message in the render queue memory; note that delete should not be called on the return value
634     new (slot) DerivedType( shader, &Shader::SetProgram, geometryType, subType, resourceId, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
635   }
636 }
637
638 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
639 {
640   if ( !systemLevel )
641   {
642     // copy the list, this is only likely to happen once in application life cycle
643     return &(mImpl->taskList);
644   }
645   else
646   {
647     // copy the list, this is only likely to happen once in application life cycle
648     return &(mImpl->systemLevelTaskList);
649   }
650 }
651
652 void UpdateManager::AddGesture( PanGesture* gesture )
653 {
654   DALI_ASSERT_DEBUG( NULL != gesture );
655
656   mImpl->gestures.PushBack( gesture );
657 }
658
659 void UpdateManager::RemoveGesture( PanGesture* gesture )
660 {
661   DALI_ASSERT_DEBUG( gesture != NULL );
662
663   GestureContainer& gestures = mImpl->gestures;
664
665   // Find the gesture and destroy it
666   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
667   {
668     PanGesture& current = **iter;
669     if ( &current == gesture )
670     {
671       mImpl->gestures.Erase( iter );
672       return;
673     }
674   }
675   // Should not reach here
676   DALI_ASSERT_DEBUG(false);
677 }
678
679 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
680 {
681   return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
682 }
683
684 void UpdateManager::EventProcessingStarted()
685 {
686   mImpl->messageQueue.EventProcessingStarted();
687 }
688
689 bool UpdateManager::FlushQueue()
690 {
691   return mImpl->messageQueue.FlushQueue();
692 }
693
694 void UpdateManager::ResetNodeProperty( Node& node )
695 {
696   node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
697 }
698
699 void UpdateManager::ResetProperties()
700 {
701   PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
702
703   BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
704
705   // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
706   mImpl->animationFinishedDuringUpdate = false;
707
708   // Animated properties have to be reset to their original value each frame
709
710   // Reset node properties
711   if ( mImpl->root )
712   {
713     ResetNodeProperty( *mImpl->root );
714   }
715
716   if ( mImpl->systemLevelRoot )
717   {
718     ResetNodeProperty( *mImpl->systemLevelRoot );
719   }
720
721   // Reset the Connected Nodes
722   const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
723   for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
724   {
725     ResetNodeProperty( **iter );
726   }
727
728   // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
729   for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
730   {
731     Node* node = *iter;
732     node->ResetToBaseValues( bufferIndex );
733     node->SetActive( false );
734
735     // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
736     mImpl->activeDisconnectedNodes.erase( iter );
737     mImpl->disconnectedNodes.insert( node );
738   }
739
740   // Reset system-level render-task list properties to base values
741   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
742
743   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
744   {
745     (*iter)->ResetToBaseValues( bufferIndex );
746   }
747
748   // Reset render-task list properties to base values.
749   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
750
751   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
752   {
753     (*iter)->ResetToBaseValues( bufferIndex );
754   }
755
756   // Reset custom object properties to base values
757   for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
758   {
759     (*iter)->ResetToBaseValues( bufferIndex );
760   }
761
762   mImpl->materials.ResetToBaseValues( bufferIndex );
763   mImpl->geometries.ResetToBaseValues( bufferIndex );
764   mImpl->propertyBuffers.ResetToBaseValues( bufferIndex );
765   mImpl->samplers.ResetToBaseValues( bufferIndex );
766
767
768   // Reset animatable shader properties to base values
769   for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
770   {
771     (*iter)->ResetToBaseValues( bufferIndex );
772   }
773
774   PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
775 }
776
777 bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
778 {
779   bool gestureUpdated( false );
780
781   // constrain gestures... (in construction order)
782   GestureContainer& gestures = mImpl->gestures;
783
784   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
785   {
786     PanGesture& gesture = **iter;
787     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
788     gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
789   }
790
791   return gestureUpdated;
792 }
793
794 void UpdateManager::Animate( float elapsedSeconds )
795 {
796   PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
797
798   AnimationContainer &animations = mImpl->animations;
799   AnimationIter iter = animations.Begin();
800   while ( iter != animations.End() )
801   {
802     Animation* animation = *iter;
803     bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
804
805     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
806
807     // Remove animations that had been destroyed but were still waiting for an update
808     if (animation->GetState() == Animation::Destroyed)
809     {
810       iter = animations.Erase(iter);
811     }
812     else
813     {
814       ++iter;
815     }
816   }
817
818   if ( mImpl->animationFinishedDuringUpdate )
819   {
820     // The application should be notified by NotificationManager, in another thread
821     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
822   }
823
824   PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
825 }
826
827 void UpdateManager::ApplyConstraints()
828 {
829   PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
830
831   BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
832
833   // constrain custom objects... (in construction order)
834   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
835
836   const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
837   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
838   {
839     PropertyOwner& object = **iter;
840     ConstrainPropertyOwner( object, bufferIndex );
841   }
842
843   // constrain nodes... (in Depth First traversal order)
844   if ( mImpl->root )
845   {
846     ConstrainNodes( *(mImpl->root), bufferIndex );
847   }
848
849   if ( mImpl->systemLevelRoot )
850   {
851     ConstrainNodes( *(mImpl->systemLevelRoot), bufferIndex );
852   }
853
854   // constrain other property-owners after nodes as they are more likely to depend on a node's
855   // current frame property than vice versa. They tend to be final constraints (no further
856   // constraints depend on their properties)
857   // e.g. ShaderEffect uniform a function of Actor's position.
858   // Mesh vertex a function of Actor's position or world position.
859
860   // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
861   // they can be all processed in a super-list of property-owners.
862
863   // Constrain system-level render-tasks
864   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
865
866   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
867   {
868     RenderTask& task = **iter;
869     ConstrainPropertyOwner( task, bufferIndex );
870   }
871
872   // Constrain render-tasks
873   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
874
875   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
876   {
877     RenderTask& task = **iter;
878     ConstrainPropertyOwner( task, bufferIndex );
879   }
880
881   // Constrain Materials and geometries
882   mImpl->materials.ConstrainObjects( bufferIndex );
883   mImpl->geometries.ConstrainObjects( bufferIndex );
884   mImpl->samplers.ConstrainObjects( bufferIndex );
885   mImpl->propertyBuffers.ConstrainObjects( bufferIndex );
886
887   // constrain shaders... (in construction order)
888   ShaderContainer& shaders = mImpl->shaders;
889
890   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
891   {
892     Shader& shader = **iter;
893     ConstrainPropertyOwner( shader, bufferIndex );
894   }
895
896   PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
897 }
898
899 void UpdateManager::ProcessPropertyNotifications()
900 {
901   PropertyNotificationContainer &notifications = mImpl->propertyNotifications;
902   PropertyNotificationIter iter = notifications.Begin();
903
904   BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
905
906   while ( iter != notifications.End() )
907   {
908     PropertyNotification* notification = *iter;
909     bool valid = notification->Check( bufferIndex );
910     if(valid)
911     {
912       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
913     }
914     ++iter;
915   }
916 }
917
918 void UpdateManager::UpdateNodes()
919 {
920   mImpl->nodeDirtyFlags = NothingFlag;
921
922   if ( !mImpl->root )
923   {
924     return;
925   }
926
927   PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
928
929   // Prepare resources, update shaders, update attachments, for each node
930   // And add the renderers to the sorted layers. Start from root, which is also a layer
931   mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
932                                                      mSceneGraphBuffers.GetUpdateBufferIndex(),
933                                                      mImpl->resourceManager,
934                                                      mImpl->renderQueue );
935
936   if ( mImpl->systemLevelRoot )
937   {
938     mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
939                                                         mSceneGraphBuffers.GetUpdateBufferIndex(),
940                                                         mImpl->resourceManager,
941                                                         mImpl->renderQueue );
942   }
943
944   PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
945 }
946
947 unsigned int UpdateManager::Update( float elapsedSeconds,
948                                     unsigned int lastVSyncTimeMilliseconds,
949                                     unsigned int nextVSyncTimeMilliseconds )
950 {
951   PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE);   // Mark the End of the last frame
952   PERF_MONITOR_NEXT_FRAME();             // Prints out performance info for the last frame (if enabled)
953   PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
954
955   // Measure the time spent in UpdateManager::Update
956   PERF_MONITOR_START(PerformanceMonitor::UPDATE);
957
958   BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
959
960   // Update the frame time delta on the render thread.
961   mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
962
963   // 1) Clear nodes/resources which were previously discarded
964   mImpl->discardQueue.Clear( bufferIndex );
965
966   // 2) Grab any loaded resources
967   bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
968
969   // 3) Process Touches & Gestures
970   mImpl->touchResampler.Update();
971   const bool gestureUpdated = ProcessGestures( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
972
973   const bool updateScene =                                            // The scene-graph requires an update if..
974       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||              // ..nodes were dirty in previous frame OR
975       IsAnimationRunning() ||                                         // ..at least one animation is running OR
976       mImpl->dynamicsChanged ||                                       // ..there was a change in the dynamics simulation OR
977       mImpl->messageQueue.IsSceneUpdateRequired() ||                  // ..a message that modifies the scene graph node tree is queued OR
978       resourceChanged ||                                              // ..one or more resources were updated/changed OR
979       gestureUpdated;                                                // ..a gesture property was updated
980
981   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
982   // values if the scene was updated in the previous frame.
983   if( updateScene || mImpl->previousUpdateScene )
984   {
985     // 4) Reset properties from the previous update
986     ResetProperties();
987   }
988
989   // 5) Process the queued scene messages
990   mImpl->messageQueue.ProcessMessages();
991
992   // 6) Post Process Ids of resources updated by renderer
993   mImpl->resourceManager.PostProcessResources( bufferIndex );
994
995   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
996   // renderer lists if the scene was updated in the previous frame.
997   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
998   if( updateScene || mImpl->previousUpdateScene )
999   {
1000     // 7) Animate
1001     Animate( elapsedSeconds );
1002
1003     // 8) Apply Constraints
1004     ApplyConstraints();
1005
1006 #ifdef DYNAMICS_SUPPORT
1007     // 9) Update dynamics simulation
1008     mImpl->dynamicsChanged = false;
1009     if( mImpl->dynamicsWorld )
1010     {
1011       mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds );
1012     }
1013 #endif
1014
1015     // 10) Check Property Notifications
1016     ProcessPropertyNotifications();
1017
1018     // 11) Clear the lists of renderable-attachments from the previous update
1019     ClearRenderables( mImpl->sortedLayers );
1020     ClearRenderables( mImpl->systemLevelSortedLayers );
1021
1022     // 12) Update node hierarchy and perform sorting / culling.
1023     //     This will populate each Layer with a list of renderers which are ready.
1024     UpdateNodes();
1025
1026     // 13) Prepare for the next render
1027     PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1028
1029     PrepareRenderables( bufferIndex, mImpl->sortedLayers );
1030     PrepareRenderables( bufferIndex, mImpl->systemLevelSortedLayers );
1031     PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1032
1033     PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1034
1035     // 14) Process the RenderTasks; this creates the instructions for rendering the next frame.
1036     // reset the update buffer index and make sure there is enough room in the instruction container
1037     mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(),
1038                                                mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1039
1040     if ( NULL != mImpl->root )
1041     {
1042       ProcessRenderTasks(  bufferIndex,
1043                            mImpl->completeStatusManager,
1044                            mImpl->taskList,
1045                            *mImpl->root,
1046                            mImpl->sortedLayers,
1047                            mImpl->renderSortingHelper,
1048                            mImpl->renderInstructions );
1049
1050       // Process the system-level RenderTasks last
1051       if ( NULL != mImpl->systemLevelRoot )
1052       {
1053         ProcessRenderTasks(  bufferIndex,
1054                              mImpl->completeStatusManager,
1055                              mImpl->systemLevelTaskList,
1056                              *mImpl->systemLevelRoot,
1057                              mImpl->systemLevelSortedLayers,
1058                              mImpl->renderSortingHelper,
1059                              mImpl->renderInstructions );
1060       }
1061     }
1062   }
1063
1064   // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1065   bool doRenderOnceNotify = false;
1066   mImpl->renderTaskWaiting = false;
1067   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1068   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1069         endIter != iter; ++iter )
1070   {
1071     RenderTask& renderTask(*(*iter));
1072
1073     renderTask.UpdateState();
1074
1075     if( renderTask.IsWaitingToRender() &&
1076         renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1077     {
1078       mImpl->renderTaskWaiting = true; // keep update/render threads alive
1079     }
1080
1081     if( renderTask.HasRendered() )
1082     {
1083       doRenderOnceNotify = true;
1084     }
1085   }
1086
1087   if( doRenderOnceNotify )
1088   {
1089     DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1090     mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1091   }
1092
1093   PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1094
1095   // Macro is undefined in release build.
1096   SNAPSHOT_NODE_LOGGING;
1097
1098   // A ResetProperties() may be required in the next frame
1099   mImpl->previousUpdateScene = updateScene;
1100
1101   // Check whether further updates are required
1102   unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1103
1104 #ifdef PERFORMANCE_MONITOR_ENABLED
1105   // Always keep rendering when measuring FPS
1106   keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1107 #endif
1108
1109   // The update has finished; swap the double-buffering indices
1110   mSceneGraphBuffers.Swap();
1111
1112   // tell the update manager that we're done so the queue can be given to event thread
1113   mImpl->notificationManager.UpdateCompleted();
1114
1115   PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1116
1117   return keepUpdating;
1118 }
1119
1120 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1121 {
1122   // Update the duration set via Stage::KeepRendering()
1123   if ( mImpl->keepRenderingSeconds > 0.0f )
1124   {
1125     mImpl->keepRenderingSeconds -= elapsedSeconds;
1126   }
1127
1128   unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1129
1130   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1131   // Keep updating until no messages are received and no animations are running.
1132   // If an animation has just finished, update at least once more for Discard end-actions.
1133   // No need to check for renderQueue as there is always a render after update and if that
1134   // render needs another update it will tell the adaptor to call update again
1135
1136   if ( mImpl->keepRenderingSeconds > 0.0f )
1137   {
1138     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1139   }
1140
1141   if ( IsAnimationRunning() ||
1142        mImpl->animationFinishedDuringUpdate )
1143   {
1144     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1145   }
1146
1147   if ( mImpl->dynamicsChanged )
1148   {
1149     keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED;
1150   }
1151
1152   if ( mImpl->renderTaskWaiting )
1153   {
1154     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1155   }
1156
1157   return keepUpdatingRequest;
1158 }
1159
1160 void UpdateManager::SetBackgroundColor( const Vector4& color )
1161 {
1162   typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1163
1164   // Reserve some memory inside the render queue
1165   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1166
1167   // Construct message in the render queue memory; note that delete should not be called on the return value
1168   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1169 }
1170
1171 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1172 {
1173   typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1174
1175   // Reserve some memory inside the render queue
1176   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1177
1178   // Construct message in the render queue memory; note that delete should not be called on the return value
1179   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceRect, rect );
1180 }
1181
1182 void UpdateManager::KeepRendering( float durationSeconds )
1183 {
1184   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1185 }
1186
1187 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1188 {
1189   if ( !systemLevel )
1190   {
1191     // just copy the vector of pointers
1192     mImpl->sortedLayers = layers;
1193   }
1194   else
1195   {
1196     mImpl->systemLevelSortedLayers = layers;
1197   }
1198 }
1199
1200 #ifdef DYNAMICS_SUPPORT
1201
1202 void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings )
1203 {
1204   dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers );
1205   mImpl->dynamicsWorld = dynamicsWorld;
1206 }
1207
1208 void UpdateManager::TerminateDynamicsWorld()
1209 {
1210   mImpl->dynamicsWorld.Reset();
1211 }
1212
1213 #endif // DYNAMICS_SUPPORT
1214
1215 } // namespace SceneGraph
1216
1217 } // namespace Internal
1218
1219 } // namespace Dali