Merge "Stability/Performance for update buffer index" into devel/master
[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::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
762
763   // Reset animatable shader properties to base values
764   for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
765   {
766     (*iter)->ResetToBaseValues( bufferIndex );
767   }
768
769   PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
770 }
771
772 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
773 {
774   bool gestureUpdated( false );
775
776   // constrain gestures... (in construction order)
777   GestureContainer& gestures = mImpl->gestures;
778
779   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
780   {
781     PanGesture& gesture = **iter;
782     gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
783     gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
784   }
785
786   return gestureUpdated;
787 }
788
789 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
790 {
791   PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
792
793   AnimationContainer &animations = mImpl->animations;
794   AnimationIter iter = animations.Begin();
795   while ( iter != animations.End() )
796   {
797     Animation* animation = *iter;
798     bool finished = animation->Update( bufferIndex, elapsedSeconds );
799
800     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
801
802     // Remove animations that had been destroyed but were still waiting for an update
803     if (animation->GetState() == Animation::Destroyed)
804     {
805       iter = animations.Erase(iter);
806     }
807     else
808     {
809       ++iter;
810     }
811   }
812
813   if ( mImpl->animationFinishedDuringUpdate )
814   {
815     // The application should be notified by NotificationManager, in another thread
816     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
817   }
818
819   PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
820 }
821
822 void UpdateManager::ApplyConstraints( BufferIndex bufferIndex )
823 {
824   PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
825
826   // constrain custom objects... (in construction order)
827   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
828
829   const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
830   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
831   {
832     PropertyOwner& object = **iter;
833     ConstrainPropertyOwner( object, bufferIndex );
834   }
835
836   // constrain nodes... (in Depth First traversal order)
837   if ( mImpl->root )
838   {
839     ConstrainNodes( *(mImpl->root), bufferIndex );
840   }
841
842   if ( mImpl->systemLevelRoot )
843   {
844     ConstrainNodes( *(mImpl->systemLevelRoot), bufferIndex );
845   }
846
847   // constrain other property-owners after nodes as they are more likely to depend on a node's
848   // current frame property than vice versa. They tend to be final constraints (no further
849   // constraints depend on their properties)
850   // e.g. ShaderEffect uniform a function of Actor's position.
851   // Mesh vertex a function of Actor's position or world position.
852
853   // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
854   // they can be all processed in a super-list of property-owners.
855
856   // Constrain system-level render-tasks
857   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
858
859   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
860   {
861     RenderTask& task = **iter;
862     ConstrainPropertyOwner( task, bufferIndex );
863   }
864
865   // Constrain render-tasks
866   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
867
868   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
869   {
870     RenderTask& task = **iter;
871     ConstrainPropertyOwner( task, bufferIndex );
872   }
873
874   // Constrain Materials and geometries
875   mImpl->materials.ConstrainObjects( bufferIndex );
876   mImpl->geometries.ConstrainObjects( bufferIndex );
877   mImpl->samplers.ConstrainObjects( bufferIndex );
878   mImpl->propertyBuffers.ConstrainObjects( bufferIndex );
879
880   // constrain shaders... (in construction order)
881   ShaderContainer& shaders = mImpl->shaders;
882
883   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
884   {
885     Shader& shader = **iter;
886     ConstrainPropertyOwner( shader, bufferIndex );
887   }
888
889   PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
890 }
891
892 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
893 {
894   PropertyNotificationContainer &notifications = mImpl->propertyNotifications;
895   PropertyNotificationIter iter = notifications.Begin();
896
897   while ( iter != notifications.End() )
898   {
899     PropertyNotification* notification = *iter;
900     bool valid = notification->Check( bufferIndex );
901     if(valid)
902     {
903       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
904     }
905     ++iter;
906   }
907 }
908
909 void UpdateManager::ForwardCompiledShadersToEventThread()
910 {
911   DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
912   if( mImpl->shaderSaver )
913   {
914     // lock and swap the queues
915     {
916       // render might be attempting to send us more binaries at the same time
917       Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
918       mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
919     }
920
921     if( mImpl->updateCompiledShaders.size() > 0 )
922     {
923       ShaderSaver& factory = *mImpl->shaderSaver;
924       ShaderDataBinaryQueue::iterator i   = mImpl->updateCompiledShaders.begin();
925       ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
926       for( ; i != end; ++i )
927       {
928         mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
929       }
930       // we don't need them in update anymore
931       mImpl->updateCompiledShaders.clear();
932     }
933   }
934 }
935
936 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
937 {
938   mImpl->nodeDirtyFlags = NothingFlag;
939
940   if ( !mImpl->root )
941   {
942     return;
943   }
944
945   PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
946
947   // Prepare resources, update shaders, update attachments, for each node
948   // And add the renderers to the sorted layers. Start from root, which is also a layer
949   mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
950                                                      bufferIndex,
951                                                      mImpl->resourceManager,
952                                                      mImpl->renderQueue );
953
954   if ( mImpl->systemLevelRoot )
955   {
956     mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
957                                                         bufferIndex,
958                                                         mImpl->resourceManager,
959                                                         mImpl->renderQueue );
960   }
961
962   PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
963 }
964
965 unsigned int UpdateManager::Update( float elapsedSeconds,
966                                     unsigned int lastVSyncTimeMilliseconds,
967                                     unsigned int nextVSyncTimeMilliseconds )
968 {
969   PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE);   // Mark the End of the last frame
970   PERF_MONITOR_NEXT_FRAME();             // Prints out performance info for the last frame (if enabled)
971   PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
972
973   // Measure the time spent in UpdateManager::Update
974   PERF_MONITOR_START(PerformanceMonitor::UPDATE);
975
976   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
977
978   // Update the frame time delta on the render thread.
979   mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
980
981   // 1) Clear nodes/resources which were previously discarded
982   mImpl->discardQueue.Clear( bufferIndex );
983
984   // 2) Grab any loaded resources
985   bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
986
987   // 3) Process Touches & Gestures
988   mImpl->touchResampler.Update();
989   const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
990
991   const bool updateScene =                                            // The scene-graph requires an update if..
992       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||              // ..nodes were dirty in previous frame OR
993       IsAnimationRunning() ||                                         // ..at least one animation is running OR
994       mImpl->messageQueue.IsSceneUpdateRequired() ||                  // ..a message that modifies the scene graph node tree is queued OR
995       resourceChanged ||                                              // ..one or more resources were updated/changed OR
996       gestureUpdated;                                                // ..a gesture property was updated
997
998   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
999   // values if the scene was updated in the previous frame.
1000   if( updateScene || mImpl->previousUpdateScene )
1001   {
1002     // 4) Reset properties from the previous update
1003     ResetProperties( bufferIndex );
1004   }
1005
1006   // 5) Process the queued scene messages
1007   mImpl->messageQueue.ProcessMessages( bufferIndex );
1008
1009   // 6) Post Process Ids of resources updated by renderer
1010   mImpl->resourceManager.PostProcessResources( bufferIndex );
1011
1012   // 6.1) Forward compiled shader programs to event thread for saving
1013   ForwardCompiledShadersToEventThread();
1014
1015   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1016   // renderer lists if the scene was updated in the previous frame.
1017   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1018   if( updateScene || mImpl->previousUpdateScene )
1019   {
1020     // 7) Animate
1021     Animate( bufferIndex, elapsedSeconds );
1022
1023     // 8) Apply Constraints
1024     ApplyConstraints( bufferIndex );
1025
1026     // 9) Check Property Notifications
1027     ProcessPropertyNotifications( bufferIndex );
1028
1029     // 10) Clear the lists of renderable-attachments from the previous update
1030     ClearRenderables( mImpl->sortedLayers );
1031     ClearRenderables( mImpl->systemLevelSortedLayers );
1032
1033     // 11) Update node hierarchy and perform sorting / culling.
1034     //     This will populate each Layer with a list of renderers which are ready.
1035     UpdateNodes( bufferIndex );
1036
1037     // 12) Prepare for the next render
1038     PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
1039
1040     PrepareRenderables( bufferIndex, mImpl->sortedLayers );
1041     PrepareRenderables( bufferIndex, mImpl->systemLevelSortedLayers );
1042     PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
1043
1044     PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
1045
1046     // 14) Process the RenderTasks; this creates the instructions for rendering the next frame.
1047     // reset the update buffer index and make sure there is enough room in the instruction container
1048     mImpl->renderInstructions.ResetAndReserve( bufferIndex,
1049                                                mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1050
1051     if ( NULL != mImpl->root )
1052     {
1053       ProcessRenderTasks(  bufferIndex,
1054                            mImpl->completeStatusManager,
1055                            mImpl->taskList,
1056                            *mImpl->root,
1057                            mImpl->sortedLayers,
1058                            mImpl->renderSortingHelper,
1059                            mImpl->renderInstructions );
1060
1061       // Process the system-level RenderTasks last
1062       if ( NULL != mImpl->systemLevelRoot )
1063       {
1064         ProcessRenderTasks(  bufferIndex,
1065                              mImpl->completeStatusManager,
1066                              mImpl->systemLevelTaskList,
1067                              *mImpl->systemLevelRoot,
1068                              mImpl->systemLevelSortedLayers,
1069                              mImpl->renderSortingHelper,
1070                              mImpl->renderInstructions );
1071       }
1072     }
1073   }
1074
1075   // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1076   bool doRenderOnceNotify = false;
1077   mImpl->renderTaskWaiting = false;
1078   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1079   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1080         endIter != iter; ++iter )
1081   {
1082     RenderTask& renderTask(*(*iter));
1083
1084     renderTask.UpdateState();
1085
1086     if( renderTask.IsWaitingToRender() &&
1087         renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1088     {
1089       mImpl->renderTaskWaiting = true; // keep update/render threads alive
1090     }
1091
1092     if( renderTask.HasRendered() )
1093     {
1094       doRenderOnceNotify = true;
1095     }
1096   }
1097
1098   if( doRenderOnceNotify )
1099   {
1100     DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1101     mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1102   }
1103
1104   PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
1105
1106   // Macro is undefined in release build.
1107   SNAPSHOT_NODE_LOGGING;
1108
1109   // A ResetProperties() may be required in the next frame
1110   mImpl->previousUpdateScene = updateScene;
1111
1112   // Check whether further updates are required
1113   unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1114
1115 #ifdef PERFORMANCE_MONITOR_ENABLED
1116   // Always keep rendering when measuring FPS
1117   keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
1118 #endif
1119
1120   // tell the update manager that we're done so the queue can be given to event thread
1121   mImpl->notificationManager.UpdateCompleted();
1122
1123   // The update has finished; swap the double-buffering indices
1124   mSceneGraphBuffers.Swap();
1125
1126   PERF_MONITOR_END(PerformanceMonitor::UPDATE);
1127
1128   return keepUpdating;
1129 }
1130
1131 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1132 {
1133   // Update the duration set via Stage::KeepRendering()
1134   if ( mImpl->keepRenderingSeconds > 0.0f )
1135   {
1136     mImpl->keepRenderingSeconds -= elapsedSeconds;
1137   }
1138
1139   unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1140
1141   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1142   // Keep updating until no messages are received and no animations are running.
1143   // If an animation has just finished, update at least once more for Discard end-actions.
1144   // No need to check for renderQueue as there is always a render after update and if that
1145   // render needs another update it will tell the adaptor to call update again
1146
1147   if ( mImpl->keepRenderingSeconds > 0.0f )
1148   {
1149     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1150   }
1151
1152   if ( IsAnimationRunning() ||
1153        mImpl->animationFinishedDuringUpdate )
1154   {
1155     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1156   }
1157
1158   if ( mImpl->renderTaskWaiting )
1159   {
1160     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1161   }
1162
1163   return keepUpdatingRequest;
1164 }
1165
1166 void UpdateManager::SetBackgroundColor( const Vector4& color )
1167 {
1168   typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1169
1170   // Reserve some memory inside the render queue
1171   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1172
1173   // Construct message in the render queue memory; note that delete should not be called on the return value
1174   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1175 }
1176
1177 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1178 {
1179   typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1180
1181   // Reserve some memory inside the render queue
1182   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1183
1184   // Construct message in the render queue memory; note that delete should not be called on the return value
1185   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceRect, rect );
1186 }
1187
1188 void UpdateManager::KeepRendering( float durationSeconds )
1189 {
1190   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1191 }
1192
1193 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1194 {
1195   if ( !systemLevel )
1196   {
1197     // just copy the vector of pointers
1198     mImpl->sortedLayers = layers;
1199   }
1200   else
1201   {
1202     mImpl->systemLevelSortedLayers = layers;
1203   }
1204 }
1205
1206 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1207 {
1208   mImpl->shaderSaver = &upstream;
1209 }
1210
1211 } // namespace SceneGraph
1212
1213 } // namespace Internal
1214
1215 } // namespace Dali