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