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