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