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