Merge "Allow multiple renderers per Actor and sharing renderers between actors" into...
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-manager.cpp
1 /*
2  * Copyright (c) 2015 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 #include <dali/devel-api/common/mutex.h>
25
26 #include <dali/integration-api/core.h>
27 #include <dali/integration-api/render-controller.h>
28 #include <dali/internal/common/shader-data.h>
29 #include <dali/integration-api/debug.h>
30
31 #include <dali/internal/common/core-impl.h>
32 #include <dali/internal/common/owner-container.h>
33 #include <dali/internal/common/message.h>
34
35 #include <dali/internal/event/common/notification-manager.h>
36 #include <dali/internal/event/common/property-notification-impl.h>
37 #include <dali/internal/event/common/property-notifier.h>
38 #include <dali/internal/event/effects/shader-factory.h>
39
40 #include <dali/internal/update/animation/scene-graph-animator.h>
41 #include <dali/internal/update/animation/scene-graph-animation.h>
42 #include <dali/internal/update/common/discard-queue.h>
43 #include <dali/internal/update/common/scene-graph-buffers.h>
44 #include <dali/internal/update/common/scene-graph-property-buffer.h>
45 #include <dali/internal/update/controllers/render-message-dispatcher.h>
46 #include <dali/internal/update/controllers/scene-controller-impl.h>
47 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
48 #include <dali/internal/update/manager/object-owner-container.h>
49 #include <dali/internal/update/manager/prepare-render-algorithms.h>
50 #include <dali/internal/update/manager/process-render-tasks.h>
51 #include <dali/internal/update/manager/sorted-layers.h>
52 #include <dali/internal/update/manager/update-algorithms.h>
53 #include <dali/internal/update/manager/update-manager-debug.h>
54 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
55 #include <dali/internal/update/node-attachments/scene-graph-image-attachment.h>
56 #include <dali/internal/update/nodes/node.h>
57 #include <dali/internal/update/nodes/scene-graph-layer.h>
58 #include <dali/internal/update/queue/update-message-queue.h>
59 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
60 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
61 #include <dali/internal/update/rendering/scene-graph-material.h>
62 #include <dali/internal/update/rendering/scene-graph-sampler.h>
63 #include <dali/internal/update/rendering/scene-graph-geometry.h>
64 #include <dali/internal/update/resources/resource-manager.h>
65 #include <dali/internal/update/resources/complete-status-manager.h>
66 #include <dali/internal/update/touch/touch-resampler.h>
67
68 #include <dali/internal/render/common/render-instruction-container.h>
69 #include <dali/internal/render/common/render-manager.h>
70 #include <dali/internal/render/queue/render-queue.h>
71 #include <dali/internal/render/common/performance-monitor.h>
72 #include <dali/internal/render/gl-resources/texture-cache.h>
73 #include <dali/internal/render/shaders/scene-graph-shader.h>
74
75 // Un-comment to enable node tree debug logging
76 //#define NODE_TREE_LOGGING 1
77
78 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
79 #define SNAPSHOT_NODE_LOGGING \
80 const int FRAME_COUNT_TRIGGER = 16;\
81 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
82   {\
83     if ( NULL != mImpl->root )\
84     {\
85       mImpl->frameCounter = 0;\
86       PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
87     }\
88   }\
89 mImpl->frameCounter++;
90 #else
91 #define SNAPSHOT_NODE_LOGGING
92 #endif
93
94 #if defined(DEBUG_ENABLED)
95 extern Debug::Filter* gRenderTaskLogFilter;
96 #endif
97
98
99 using namespace Dali::Integration;
100 using Dali::Internal::Update::MessageQueue;
101
102 namespace Dali
103 {
104
105 namespace Internal
106 {
107
108 namespace SceneGraph
109 {
110
111 namespace
112 {
113
114 void DestroyNodeSet( std::set<Node*>& nodeSet )
115 {
116   for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
117   {
118     Node* node( *iter );
119
120     // Call Node::OnDestroy as each node is destroyed
121     node->OnDestroy();
122
123     delete node;
124   }
125   nodeSet.clear();
126 }
127
128 } //namespace
129
130 typedef OwnerContainer< Shader* >              ShaderContainer;
131 typedef ShaderContainer::Iterator              ShaderIter;
132 typedef ShaderContainer::ConstIterator         ShaderConstIter;
133
134 typedef std::vector<Internal::ShaderDataPtr>   ShaderDataBinaryQueue;
135
136 typedef OwnerContainer<PanGesture*>            GestureContainer;
137 typedef GestureContainer::Iterator             GestureIter;
138 typedef GestureContainer::ConstIterator        GestureConstIter;
139
140
141 /**
142  * Structure to contain UpdateManager internal data
143  */
144 struct UpdateManager::Impl
145 {
146   Impl( NotificationManager& notificationManager,
147         GlSyncAbstraction& glSyncAbstraction,
148         CompleteNotificationInterface& animationFinishedNotifier,
149         PropertyNotifier& propertyNotifier,
150         ResourceManager& resourceManager,
151         DiscardQueue& discardQueue,
152         RenderController& renderController,
153         RenderManager& renderManager,
154         RenderQueue& renderQueue,
155         TextureCache& textureCache,
156         TouchResampler& touchResampler,
157         SceneGraphBuffers& sceneGraphBuffers )
158   :
159     renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
160     notificationManager( notificationManager ),
161     animationFinishedNotifier( animationFinishedNotifier ),
162     propertyNotifier( propertyNotifier ),
163     shaderSaver( NULL ),
164     resourceManager( resourceManager ),
165     discardQueue( discardQueue ),
166     renderController( renderController ),
167     sceneController( NULL ),
168     renderManager( renderManager ),
169     renderQueue( renderQueue ),
170     renderInstructions( renderManager.GetRenderInstructionContainer() ),
171     completeStatusManager( glSyncAbstraction, renderMessageDispatcher, resourceManager ),
172     touchResampler( touchResampler ),
173     backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
174     taskList ( completeStatusManager ),
175     systemLevelTaskList ( completeStatusManager ),
176     root( NULL ),
177     systemLevelRoot( NULL ),
178     renderers( sceneGraphBuffers, discardQueue ),
179     geometries( sceneGraphBuffers, discardQueue ),
180     materials( sceneGraphBuffers, discardQueue ),
181     samplers( sceneGraphBuffers, discardQueue ),
182     propertyBuffers( sceneGraphBuffers, discardQueue ),
183     messageQueue( renderController, sceneGraphBuffers ),
184     keepRenderingSeconds( 0.0f ),
185     animationFinishedDuringUpdate( false ),
186     nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
187     previousUpdateScene( false ),
188     frameCounter( 0 ),
189     renderSortingHelper(),
190     renderTaskWaiting( false )
191   {
192     sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
193
194     renderers.SetSceneController( *sceneController );
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   ShaderSaver*                        shaderSaver;                   ///< Saves shader binaries.
248   ResourceManager&                    resourceManager;               ///< resource manager
249   DiscardQueue&                       discardQueue;                  ///< Nodes are added here when disconnected from the scene-graph.
250   RenderController&                   renderController;              ///< render controller
251   SceneControllerImpl*                sceneController;               ///< scene controller
252   RenderManager&                      renderManager;                 ///< This is responsible for rendering the results of each "update"
253   RenderQueue&                        renderQueue;                   ///< Used to queue messages for the next render
254   RenderInstructionContainer&         renderInstructions;            ///< Used to prepare the render instructions
255   CompleteStatusManager               completeStatusManager;         ///< Complete Status Manager
256   TouchResampler&                     touchResampler;                ///< Used to resample touch events on every update.
257
258   Vector4                             backgroundColor;               ///< The glClear color used at the beginning of each frame.
259
260   RenderTaskList                      taskList;                      ///< The list of scene graph render-tasks
261   RenderTaskList                      systemLevelTaskList;           ///< Separate render-tasks for system-level content
262
263   Layer*                              root;                          ///< The root node (root is a layer)
264   Layer*                              systemLevelRoot;               ///< A separate root-node for system-level content
265   std::set< Node* >                   activeDisconnectedNodes;       ///< A container of new or modified nodes (without parent) owned by UpdateManager
266   std::set< Node* >                   connectedNodes;                ///< A container of connected (with parent) nodes owned by UpdateManager
267   std::set< Node* >                   disconnectedNodes;             ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager
268
269   SortedLayerPointers                 sortedLayers;                  ///< A container of Layer pointers sorted by depth
270   SortedLayerPointers                 systemLevelSortedLayers;       ///< A separate container of system-level Layers
271
272   OwnerContainer< PropertyOwner* >    customObjects;                 ///< A container of owned objects (with custom properties)
273
274   AnimationContainer                  animations;                    ///< A container of owned animations
275   PropertyNotificationContainer       propertyNotifications;         ///< A container of owner property notifications.
276
277   ObjectOwnerContainer<Renderer>      renderers;
278   ObjectOwnerContainer<Geometry>      geometries;                    ///< A container of geometries
279   ObjectOwnerContainer<Material>      materials;                     ///< A container of materials
280   ObjectOwnerContainer<Sampler>       samplers;                      ///< A container of samplers
281   ObjectOwnerContainer<PropertyBuffer> propertyBuffers;              ///< A container of property buffers
282
283   ShaderContainer                     shaders;                       ///< A container of owned shaders
284
285   MessageQueue                        messageQueue;                  ///< The messages queued from the event-thread
286   ShaderDataBinaryQueue               renderCompiledShaders;         ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
287   ShaderDataBinaryQueue               updateCompiledShaders;         ///< Shaders to be sent from Update to Event
288   Mutex                               compiledShaderMutex;           ///< lock to ensure no corruption on the renderCompiledShaders
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 )
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 );
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::AddObject( PropertyOwner* object )
443 {
444   DALI_ASSERT_DEBUG( NULL != object );
445
446   mImpl->customObjects.PushBack( object );
447 }
448
449 void UpdateManager::RemoveObject( PropertyOwner* object )
450 {
451   DALI_ASSERT_DEBUG( NULL != object );
452
453   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
454
455   // Find the object and destroy it
456   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
457   {
458     PropertyOwner* current = *iter;
459     if ( current == object )
460     {
461       customObjects.Erase( iter );
462       return;
463     }
464   }
465
466   // Should not reach here
467   DALI_ASSERT_DEBUG(false);
468 }
469
470 void UpdateManager::AddAnimation( Animation* animation )
471 {
472   mImpl->animations.PushBack( animation );
473 }
474
475 void UpdateManager::StopAnimation( Animation* animation )
476 {
477   DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
478
479   bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
480
481   mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
482 }
483
484 void UpdateManager::RemoveAnimation( Animation* animation )
485 {
486   DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
487
488   animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
489
490   DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
491 }
492
493 bool UpdateManager::IsAnimationRunning() const
494 {
495   bool isRunning(false);
496   AnimationContainer& animations = mImpl->animations;
497
498   // Find any animation that isn't stopped or paused
499
500   const AnimationIter endIter = animations.End();
501   for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
502   {
503     const Animation::State state = (*iter)->GetState();
504
505     if (state != Animation::Stopped &&
506         state != Animation::Paused)
507     {
508       isRunning = true;
509     }
510   }
511
512   return isRunning;
513 }
514
515 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
516 {
517   mImpl->propertyNotifications.PushBack( propertyNotification );
518 }
519
520 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
521 {
522   PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
523   PropertyNotificationIter iter = propertyNotifications.Begin();
524
525   while ( iter != propertyNotifications.End() )
526   {
527     if( *iter == propertyNotification )
528     {
529       propertyNotifications.Erase(iter);
530       break;
531     }
532     ++iter;
533   }
534 }
535
536 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
537 {
538   DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
539   propertyNotification->SetNotifyMode( notifyMode );
540 }
541
542 ObjectOwnerContainer<Geometry>& UpdateManager::GetGeometryOwner()
543 {
544   return mImpl->geometries;
545 }
546
547 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
548 {
549   return mImpl->renderers;
550 }
551
552
553 ObjectOwnerContainer<Material>& UpdateManager::GetMaterialOwner()
554 {
555   return mImpl->materials;
556 }
557
558 ObjectOwnerContainer<Sampler>& UpdateManager::GetSamplerOwner()
559 {
560   return mImpl->samplers;
561 }
562
563 ObjectOwnerContainer<PropertyBuffer>& UpdateManager::GetPropertyBufferOwner()
564 {
565   return mImpl->propertyBuffers;
566 }
567
568 void UpdateManager::AddShader( Shader* shader )
569 {
570   DALI_ASSERT_DEBUG( NULL != shader );
571
572   if( mImpl->shaders.Count() == 0 )
573   {
574     // the first added shader becomes our default shader
575     // Construct message in the render queue memory; note that delete should not be called on the return value
576     typedef MessageValue1< RenderManager, Shader* > DerivedType;
577
578     // Reserve some memory inside the render queue
579     unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
580
581     // Construct message in the render queue memory; note that delete should not be called on the return value
582     new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
583   }
584
585   mImpl->shaders.PushBack( shader );
586
587   // Allows the shader to dispatch texture requests to the cache
588   shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
589 }
590
591 void UpdateManager::RemoveShader( Shader* shader )
592 {
593   DALI_ASSERT_DEBUG(shader != NULL);
594
595   ShaderContainer& shaders = mImpl->shaders;
596
597   // Find the shader and destroy it
598   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
599   {
600     Shader& current = **iter;
601     if ( &current == shader )
602     {
603       // Transfer ownership to the discard queue
604       // This keeps the shader alive, until the render-thread has finished with it
605       mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
606
607       return;
608     }
609   }
610   // Should not reach here
611   DALI_ASSERT_DEBUG(false);
612 }
613
614 void UpdateManager::SetShaderProgram( Shader* shader,
615                                       Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
616 {
617   if( shaderData )
618   {
619
620     typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
621
622     // Reserve some memory inside the render queue
623     unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
624
625     // Construct message in the render queue memory; note that delete should not be called on the return value
626     new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
627   }
628 }
629
630 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
631 {
632   DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
633   DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
634   {
635     // lock as update might be sending previously compiled shaders to event thread
636     Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
637     mImpl->renderCompiledShaders.push_back( shaderData );
638   }
639 }
640
641 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
642 {
643   if ( !systemLevel )
644   {
645     // copy the list, this is only likely to happen once in application life cycle
646     return &(mImpl->taskList);
647   }
648   else
649   {
650     // copy the list, this is only likely to happen once in application life cycle
651     return &(mImpl->systemLevelTaskList);
652   }
653 }
654
655 void UpdateManager::AddGesture( PanGesture* gesture )
656 {
657   DALI_ASSERT_DEBUG( NULL != gesture );
658
659   mImpl->gestures.PushBack( gesture );
660 }
661
662 void UpdateManager::RemoveGesture( PanGesture* gesture )
663 {
664   DALI_ASSERT_DEBUG( gesture != NULL );
665
666   GestureContainer& gestures = mImpl->gestures;
667
668   // Find the gesture and destroy it
669   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
670   {
671     PanGesture& current = **iter;
672     if ( &current == gesture )
673     {
674       mImpl->gestures.Erase( iter );
675       return;
676     }
677   }
678   // Should not reach here
679   DALI_ASSERT_DEBUG(false);
680 }
681
682 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
683 {
684   return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
685 }
686
687 void UpdateManager::EventProcessingStarted()
688 {
689   mImpl->messageQueue.EventProcessingStarted();
690 }
691
692 bool UpdateManager::FlushQueue()
693 {
694   return mImpl->messageQueue.FlushQueue();
695 }
696
697 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
698 {
699   PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
700
701   // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
702   mImpl->animationFinishedDuringUpdate = false;
703
704   // Animated properties have to be reset to their original value each frame
705
706   // Reset root properties
707   if ( mImpl->root )
708   {
709     mImpl->root->ResetToBaseValues( bufferIndex );
710   }
711   if ( mImpl->systemLevelRoot )
712   {
713     mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
714   }
715
716   // Reset the Connected Nodes
717   const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
718   for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
719   {
720     (*iter)->ResetToBaseValues( bufferIndex );
721   }
722
723   // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
724   for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
725   {
726     Node* node = *iter;
727     node->ResetToBaseValues( bufferIndex );
728     node->SetActive( false );
729
730     // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
731     mImpl->activeDisconnectedNodes.erase( iter );
732     mImpl->disconnectedNodes.insert( node );
733   }
734
735   // Reset system-level render-task list properties to base values
736   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
737
738   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
739   {
740     (*iter)->ResetToBaseValues( bufferIndex );
741   }
742
743   // Reset render-task list properties to base values.
744   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
745
746   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
747   {
748     (*iter)->ResetToBaseValues( bufferIndex );
749   }
750
751   // Reset custom object properties to base values
752   for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
753   {
754     (*iter)->ResetToBaseValues( bufferIndex );
755   }
756
757   mImpl->materials.ResetToBaseValues( bufferIndex );
758   mImpl->geometries.ResetToBaseValues( bufferIndex );
759   mImpl->propertyBuffers.ResetToBaseValues( bufferIndex );
760   mImpl->samplers.ResetToBaseValues( bufferIndex );
761   mImpl->renderers.ResetToBaseValues( bufferIndex );
762
763
764   // Reset animatable shader properties to base values
765   for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
766   {
767     (*iter)->ResetToBaseValues( bufferIndex );
768   }
769
770   PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
771 }
772
773 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
774 {
775   bool gestureUpdated( false );
776
777   // constrain gestures... (in construction order)
778   GestureContainer& gestures = mImpl->gestures;
779
780   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
781   {
782     PanGesture& gesture = **iter;
783     gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
784     gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
785   }
786
787   return gestureUpdated;
788 }
789
790 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
791 {
792   PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
793
794   AnimationContainer &animations = mImpl->animations;
795   AnimationIter iter = animations.Begin();
796   while ( iter != animations.End() )
797   {
798     Animation* animation = *iter;
799     bool finished = animation->Update( bufferIndex, elapsedSeconds );
800
801     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
802
803     // Remove animations that had been destroyed but were still waiting for an update
804     if (animation->GetState() == Animation::Destroyed)
805     {
806       iter = animations.Erase(iter);
807     }
808     else
809     {
810       ++iter;
811     }
812   }
813
814   if ( mImpl->animationFinishedDuringUpdate )
815   {
816     // The application should be notified by NotificationManager, in another thread
817     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
818   }
819
820   PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
821 }
822
823 void UpdateManager::ApplyConstraints( BufferIndex bufferIndex )
824 {
825   PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
826
827   // constrain custom objects... (in construction order)
828   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
829
830   const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
831   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
832   {
833     PropertyOwner& object = **iter;
834     ConstrainPropertyOwner( object, bufferIndex );
835   }
836
837   // constrain nodes... (in Depth First traversal order)
838   if ( mImpl->root )
839   {
840     ConstrainNodes( *(mImpl->root), bufferIndex );
841   }
842
843   if ( mImpl->systemLevelRoot )
844   {
845     ConstrainNodes( *(mImpl->systemLevelRoot), bufferIndex );
846   }
847
848   // constrain other property-owners after nodes as they are more likely to depend on a node's
849   // current frame property than vice versa. They tend to be final constraints (no further
850   // constraints depend on their properties)
851   // e.g. ShaderEffect uniform a function of Actor's position.
852   // Mesh vertex a function of Actor's position or world position.
853
854   // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
855   // they can be all processed in a super-list of property-owners.
856
857   // Constrain system-level render-tasks
858   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
859
860   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
861   {
862     RenderTask& task = **iter;
863     ConstrainPropertyOwner( task, bufferIndex );
864   }
865
866   // Constrain render-tasks
867   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
868
869   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
870   {
871     RenderTask& task = **iter;
872     ConstrainPropertyOwner( task, bufferIndex );
873   }
874
875   // Constrain Materials and geometries
876   mImpl->materials.ConstrainObjects( bufferIndex );
877   mImpl->geometries.ConstrainObjects( bufferIndex );
878   mImpl->samplers.ConstrainObjects( bufferIndex );
879   mImpl->propertyBuffers.ConstrainObjects( bufferIndex );
880   mImpl->renderers.ConstrainObjects( bufferIndex );
881
882   // constrain shaders... (in construction order)
883   ShaderContainer& shaders = mImpl->shaders;
884
885   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
886   {
887     Shader& shader = **iter;
888     ConstrainPropertyOwner( shader, bufferIndex );
889   }
890
891   PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
892 }
893
894 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
895 {
896   PropertyNotificationContainer &notifications = mImpl->propertyNotifications;
897   PropertyNotificationIter iter = notifications.Begin();
898
899   while ( iter != notifications.End() )
900   {
901     PropertyNotification* notification = *iter;
902     bool valid = notification->Check( bufferIndex );
903     if(valid)
904     {
905       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
906     }
907     ++iter;
908   }
909 }
910
911 void UpdateManager::ForwardCompiledShadersToEventThread()
912 {
913   DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
914   if( mImpl->shaderSaver )
915   {
916     // lock and swap the queues
917     {
918       // render might be attempting to send us more binaries at the same time
919       Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
920       mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
921     }
922
923     if( mImpl->updateCompiledShaders.size() > 0 )
924     {
925       ShaderSaver& factory = *mImpl->shaderSaver;
926       ShaderDataBinaryQueue::iterator i   = mImpl->updateCompiledShaders.begin();
927       ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
928       for( ; i != end; ++i )
929       {
930         mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
931       }
932       // we don't need them in update anymore
933       mImpl->updateCompiledShaders.clear();
934     }
935   }
936 }
937
938 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
939 {
940   const Internal::OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
941   unsigned int rendererCount( rendererContainer.Size() );
942   for( unsigned int i(0); i<rendererCount; ++i )
943   {
944     if( rendererContainer[i]->IsReferenced() )
945     {
946       rendererContainer[i]->PrepareResources(bufferIndex, mImpl->resourceManager);
947       rendererContainer[i]->PrepareRender( bufferIndex );
948     }
949   }
950 }
951
952 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
953 {
954   mImpl->nodeDirtyFlags = NothingFlag;
955
956   if ( !mImpl->root )
957   {
958     return;
959   }
960
961   PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
962
963   // Prepare resources, update shaders, update attachments, for each node
964   // And add the renderers to the sorted layers. Start from root, which is also a layer
965   mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
966                                                      bufferIndex,
967                                                      mImpl->resourceManager,
968                                                      mImpl->renderQueue );
969
970   if ( mImpl->systemLevelRoot )
971   {
972     mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
973                                                         bufferIndex,
974                                                         mImpl->resourceManager,
975                                                         mImpl->renderQueue );
976   }
977
978   PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
979 }
980
981 unsigned int UpdateManager::Update( float elapsedSeconds,
982                                     unsigned int lastVSyncTimeMilliseconds,
983                                     unsigned int nextVSyncTimeMilliseconds )
984 {
985   PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE);   // Mark the End of the last frame
986   PERF_MONITOR_NEXT_FRAME();             // Prints out performance info for the last frame (if enabled)
987   PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
988
989   // Measure the time spent in UpdateManager::Update
990   PERF_MONITOR_START(PerformanceMonitor::UPDATE);
991
992   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
993
994   // Update the frame time delta on the render thread.
995   mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
996
997   // 1) Clear nodes/resources which were previously discarded
998   mImpl->discardQueue.Clear( bufferIndex );
999
1000   // 2) Grab any loaded resources
1001   bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
1002
1003   // 3) Process Touches & Gestures
1004   mImpl->touchResampler.Update();
1005   const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
1006
1007   const bool updateScene =                                  // The scene-graph requires an update if..
1008       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||    // ..nodes were dirty in previous frame OR
1009       IsAnimationRunning()                            ||    // ..at least one animation is running OR
1010       mImpl->messageQueue.IsSceneUpdateRequired()     ||    // ..a message that modifies the scene graph node tree is queued OR
1011       resourceChanged                                 ||    // ..one or more resources were updated/changed OR
1012       gestureUpdated;                                       // ..a gesture property was updated
1013
1014
1015   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1016   // values if the scene was updated in the previous frame.
1017   if( updateScene || mImpl->previousUpdateScene )
1018   {
1019     // 4) Reset properties from the previous update
1020     ResetProperties( bufferIndex );
1021   }
1022
1023   // 5) Process the queued scene messages
1024   mImpl->messageQueue.ProcessMessages( bufferIndex );
1025
1026   // 6) Post Process Ids of resources updated by renderer
1027   mImpl->resourceManager.PostProcessResources( bufferIndex );
1028
1029   // 6.1) Forward compiled shader programs to event thread for saving
1030   ForwardCompiledShadersToEventThread();
1031
1032   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1033   // renderer lists if the scene was updated in the previous frame.
1034   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1035   if( updateScene || mImpl->previousUpdateScene )
1036   {
1037     // 7) Animate
1038     Animate( bufferIndex, elapsedSeconds );
1039
1040     // 8) Apply Constraints
1041     ApplyConstraints( bufferIndex );
1042
1043     // 9) Check Property Notifications
1044     ProcessPropertyNotifications( bufferIndex );
1045
1046     // 10) Clear the lists of renderable-attachments from the previous update
1047     ClearRenderables( mImpl->sortedLayers );
1048     ClearRenderables( mImpl->systemLevelSortedLayers );
1049
1050     // 11) Update node hierarchy and perform sorting / culling.
1051     //     This will populate each Layer with a list of renderers which are ready.
1052     UpdateNodes( bufferIndex );
1053     UpdateRenderers( bufferIndex );
1054
1055
1056     // 12) Prepare for the next render
1057     PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1058
1059     PrepareRenderables( bufferIndex, mImpl->sortedLayers );
1060     PrepareRenderables( bufferIndex, mImpl->systemLevelSortedLayers );
1061     PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1062
1063     PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1064
1065     // 14) Process the RenderTasks; this creates the instructions for rendering the next frame.
1066     // reset the update buffer index and make sure there is enough room in the instruction container
1067     mImpl->renderInstructions.ResetAndReserve( bufferIndex,
1068                                                mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1069
1070     if ( NULL != mImpl->root )
1071     {
1072       ProcessRenderTasks(  bufferIndex,
1073                            mImpl->completeStatusManager,
1074                            mImpl->taskList,
1075                            *mImpl->root,
1076                            mImpl->sortedLayers,
1077                            mImpl->renderSortingHelper,
1078                            mImpl->renderInstructions );
1079
1080       // Process the system-level RenderTasks last
1081       if ( NULL != mImpl->systemLevelRoot )
1082       {
1083         ProcessRenderTasks(  bufferIndex,
1084                              mImpl->completeStatusManager,
1085                              mImpl->systemLevelTaskList,
1086                              *mImpl->systemLevelRoot,
1087                              mImpl->systemLevelSortedLayers,
1088                              mImpl->renderSortingHelper,
1089                              mImpl->renderInstructions );
1090       }
1091     }
1092   }
1093
1094   // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1095   bool doRenderOnceNotify = false;
1096   mImpl->renderTaskWaiting = false;
1097   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1098   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1099         endIter != iter; ++iter )
1100   {
1101     RenderTask& renderTask(*(*iter));
1102
1103     renderTask.UpdateState();
1104
1105     if( renderTask.IsWaitingToRender() &&
1106         renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1107     {
1108       mImpl->renderTaskWaiting = true; // keep update/render threads alive
1109     }
1110
1111     if( renderTask.HasRendered() )
1112     {
1113       doRenderOnceNotify = true;
1114     }
1115   }
1116
1117   if( doRenderOnceNotify )
1118   {
1119     DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1120     mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1121   }
1122
1123   PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1124
1125   // Macro is undefined in release build.
1126   SNAPSHOT_NODE_LOGGING;
1127
1128   // A ResetProperties() may be required in the next frame
1129   mImpl->previousUpdateScene = updateScene;
1130
1131   // Check whether further updates are required
1132   unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1133
1134 #ifdef PERFORMANCE_MONITOR_ENABLED
1135   // Always keep rendering when measuring FPS
1136   keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1137 #endif
1138
1139   // tell the update manager that we're done so the queue can be given to event thread
1140   mImpl->notificationManager.UpdateCompleted();
1141
1142   // The update has finished; swap the double-buffering indices
1143   mSceneGraphBuffers.Swap();
1144
1145   PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1146
1147   return keepUpdating;
1148 }
1149
1150 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1151 {
1152   // Update the duration set via Stage::KeepRendering()
1153   if ( mImpl->keepRenderingSeconds > 0.0f )
1154   {
1155     mImpl->keepRenderingSeconds -= elapsedSeconds;
1156   }
1157
1158   unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1159
1160   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1161   // Keep updating until no messages are received and no animations are running.
1162   // If an animation has just finished, update at least once more for Discard end-actions.
1163   // No need to check for renderQueue as there is always a render after update and if that
1164   // render needs another update it will tell the adaptor to call update again
1165
1166   if ( mImpl->keepRenderingSeconds > 0.0f )
1167   {
1168     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1169   }
1170
1171   if ( IsAnimationRunning() ||
1172        mImpl->animationFinishedDuringUpdate )
1173   {
1174     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1175   }
1176
1177   if ( mImpl->renderTaskWaiting )
1178   {
1179     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1180   }
1181
1182   return keepUpdatingRequest;
1183 }
1184
1185 void UpdateManager::SetBackgroundColor( const Vector4& color )
1186 {
1187   typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1188
1189   // Reserve some memory inside the render queue
1190   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1191
1192   // Construct message in the render queue memory; note that delete should not be called on the return value
1193   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1194 }
1195
1196 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1197 {
1198   typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1199
1200   // Reserve some memory inside the render queue
1201   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1202
1203   // Construct message in the render queue memory; note that delete should not be called on the return value
1204   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceRect, rect );
1205 }
1206
1207 void UpdateManager::KeepRendering( float durationSeconds )
1208 {
1209   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1210 }
1211
1212 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1213 {
1214   if ( !systemLevel )
1215   {
1216     // just copy the vector of pointers
1217     mImpl->sortedLayers = layers;
1218   }
1219   else
1220   {
1221     mImpl->systemLevelSortedLayers = layers;
1222   }
1223 }
1224
1225 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1226 {
1227   mImpl->shaderSaver = &upstream;
1228 }
1229
1230 } // namespace SceneGraph
1231
1232 } // namespace Internal
1233
1234 } // namespace Dali