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