Removed unneeded index param and code from ConnectNode / Child
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-manager.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/update/manager/update-manager.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/common/stage.h>
23 #include <dali/devel-api/common/set-wrapper.h>
24
25 #include <dali/integration-api/core.h>
26 #include <dali/integration-api/render-controller.h>
27 #include <dali/internal/common/shader-data.h>
28 #include <dali/integration-api/debug.h>
29
30 #include <dali/internal/common/core-impl.h>
31 #include <dali/internal/common/owner-container.h>
32 #include <dali/internal/common/message.h>
33
34 #include <dali/internal/event/common/notification-manager.h>
35 #include <dali/internal/event/common/property-notification-impl.h>
36 #include <dali/internal/event/common/property-notifier.h>
37 #include <dali/internal/event/effects/shader-factory.h>
38
39 #include <dali/internal/update/animation/scene-graph-animator.h>
40 #include <dali/internal/update/animation/scene-graph-animation.h>
41 #include <dali/internal/update/common/discard-queue.h>
42 #include <dali/internal/update/common/scene-graph-buffers.h>
43 #include <dali/internal/update/common/scene-graph-property-buffer.h>
44 #include <dali/internal/update/controllers/render-message-dispatcher.h>
45 #include <dali/internal/update/controllers/scene-controller-impl.h>
46 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
47 #include <dali/internal/update/manager/object-owner-container.h>
48 #include <dali/internal/update/manager/prepare-render-algorithms.h>
49 #include <dali/internal/update/manager/process-render-tasks.h>
50 #include <dali/internal/update/manager/sorted-layers.h>
51 #include <dali/internal/update/manager/update-algorithms.h>
52 #include <dali/internal/update/manager/update-manager-debug.h>
53 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
54 #include <dali/internal/update/node-attachments/scene-graph-renderer-attachment.h>
55 #include <dali/internal/update/node-attachments/scene-graph-image-attachment.h>
56 #include <dali/internal/update/nodes/node.h>
57 #include <dali/internal/update/nodes/scene-graph-layer.h>
58 #include <dali/internal/update/queue/update-message-queue.h>
59 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
60 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
61 #include <dali/internal/update/rendering/scene-graph-material.h>
62 #include <dali/internal/update/rendering/scene-graph-sampler.h>
63 #include <dali/internal/update/rendering/scene-graph-geometry.h>
64 #include <dali/internal/update/resources/resource-manager.h>
65 #include <dali/internal/update/resources/complete-status-manager.h>
66 #include <dali/internal/update/touch/touch-resampler.h>
67
68 #include <dali/internal/render/common/render-instruction-container.h>
69 #include <dali/internal/render/common/render-manager.h>
70 #include <dali/internal/render/queue/render-queue.h>
71 #include <dali/internal/render/common/performance-monitor.h>
72 #include <dali/internal/render/gl-resources/texture-cache.h>
73 #include <dali/internal/render/shaders/scene-graph-shader.h>
74
75 // Un-comment to enable node tree debug logging
76 //#define NODE_TREE_LOGGING 1
77
78 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
79 #define SNAPSHOT_NODE_LOGGING \
80 const int FRAME_COUNT_TRIGGER = 16;\
81 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
82   {\
83     if ( NULL != mImpl->root )\
84     {\
85       mImpl->frameCounter = 0;\
86       PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
87     }\
88   }\
89 mImpl->frameCounter++;
90 #else
91 #define SNAPSHOT_NODE_LOGGING
92 #endif
93
94 #if defined(DEBUG_ENABLED)
95 extern Debug::Filter* gRenderTaskLogFilter;
96 #endif
97
98
99 using namespace Dali::Integration;
100 using Dali::Internal::Update::MessageQueue;
101
102 namespace Dali
103 {
104
105 namespace Internal
106 {
107
108 namespace SceneGraph
109 {
110
111 namespace
112 {
113
114 void DestroyNodeSet( std::set<Node*>& nodeSet )
115 {
116   for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
117   {
118     Node* node( *iter );
119
120     // Call Node::OnDestroy as each node is destroyed
121     node->OnDestroy();
122
123     delete node;
124   }
125   nodeSet.clear();
126 }
127
128 } //namespace
129
130 typedef OwnerContainer< Shader* >              ShaderContainer;
131 typedef ShaderContainer::Iterator              ShaderIter;
132 typedef ShaderContainer::ConstIterator         ShaderConstIter;
133
134 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBatchedQueue;
135 typedef ShaderDataBatchedQueue::iterator        ShaderDataBatchedQueueIterator;
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   ShaderDataBatchedQueue              compiledShaders[2];            ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
285
286   float                               keepRenderingSeconds;          ///< Set via Dali::Stage::KeepRendering
287   bool                                animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
288
289   int                                 nodeDirtyFlags;                ///< cumulative node dirty flags from previous frame
290   bool                                previousUpdateScene;           ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
291
292   int                                 frameCounter;                  ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
293   RendererSortingHelper               renderSortingHelper;           ///< helper used to sort transparent renderers
294
295   GestureContainer                    gestures;                      ///< A container of owned gesture detectors
296   bool                                renderTaskWaiting;             ///< A REFRESH_ONCE render task is waiting to be rendered
297 };
298
299 UpdateManager::UpdateManager( NotificationManager& notificationManager,
300                               GlSyncAbstraction& glSyncAbstraction,
301                               CompleteNotificationInterface& animationFinishedNotifier,
302                               PropertyNotifier& propertyNotifier,
303                               ResourceManager& resourceManager,
304                               DiscardQueue& discardQueue,
305                               RenderController& controller,
306                               RenderManager& renderManager,
307                               RenderQueue& renderQueue,
308                               TextureCache& textureCache,
309                               TouchResampler& touchResampler )
310   : mImpl(NULL)
311 {
312   mImpl = new Impl( notificationManager,
313                     glSyncAbstraction,
314                     animationFinishedNotifier,
315                     propertyNotifier,
316                     resourceManager,
317                     discardQueue,
318                     controller,
319                     renderManager,
320                     renderQueue,
321                     textureCache,
322                     touchResampler,
323                     mSceneGraphBuffers );
324
325   textureCache.SetBufferIndices( &mSceneGraphBuffers );
326 }
327
328 UpdateManager::~UpdateManager()
329 {
330   delete mImpl;
331 }
332
333 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
334 {
335   DALI_ASSERT_DEBUG( layer->IsLayer() );
336   DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
337
338   if ( !systemLevel )
339   {
340     DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
341     mImpl->root = layer;
342   }
343   else
344   {
345     DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
346     mImpl->systemLevelRoot = layer;
347   }
348
349   layer->SetRoot(true);
350 }
351
352 void UpdateManager::AddNode( Node* node )
353 {
354   DALI_ASSERT_ALWAYS( NULL != node );
355   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
356
357   mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
358 }
359
360 void UpdateManager::ConnectNode( Node* parent, Node* node )
361 {
362   DALI_ASSERT_ALWAYS( NULL != parent );
363   DALI_ASSERT_ALWAYS( NULL != node );
364   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
365
366   // Move from active/disconnectedNodes to connectedNodes
367   std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
368   if( !removed )
369   {
370     removed = mImpl->disconnectedNodes.erase( node );
371     DALI_ASSERT_ALWAYS( removed );
372   }
373   mImpl->connectedNodes.insert( node );
374
375   node->SetActive( true );
376
377   parent->ConnectChild( node );
378 }
379
380 void UpdateManager::DisconnectNode( Node* node )
381 {
382   Node* parent = node->GetParent();
383   DALI_ASSERT_ALWAYS( NULL != parent );
384   parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
385
386   // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
387   parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
388 }
389
390 void UpdateManager::SetNodeActive( Node* node )
391 {
392   DALI_ASSERT_ALWAYS( NULL != node );
393   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
394
395   // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
396   std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
397   DALI_ASSERT_ALWAYS( removed );
398   mImpl->activeDisconnectedNodes.insert( node );
399
400   node->SetActive( true );
401 }
402
403 void UpdateManager::DestroyNode( Node* node )
404 {
405   DALI_ASSERT_ALWAYS( NULL != node );
406   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
407
408   // Transfer ownership from new/disconnectedNodes to the discard queue
409   // This keeps the nodes alive, until the render-thread has finished with them
410   std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
411   if( !removed )
412   {
413     removed = mImpl->disconnectedNodes.erase( node );
414     DALI_ASSERT_ALWAYS( removed );
415   }
416   mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
417
418   // Notify the Node about impending destruction
419   node->OnDestroy();
420 }
421
422 //@todo MESH_REWORK Extend to allow arbitrary scene objects to connect to each other
423 void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
424 {
425   DALI_ASSERT_DEBUG( node != NULL );
426   DALI_ASSERT_DEBUG( attachment != NULL );
427
428   // attach node to attachment first so that parent is known by the time attachment is connected
429   node->Attach( *attachment ); // node takes ownership
430
431   // @todo MESH_REWORK Remove after merge of SceneGraph::RenderableAttachment and SceneGraph::RendererAttachment
432   if( dynamic_cast<SceneGraph::ImageAttachment*>( attachment ) != NULL )
433   {
434     attachment->Initialize( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
435   }
436 }
437
438 void UpdateManager::AttachToSceneGraph( RendererAttachment* renderer )
439 {
440   // @todo MESH_REWORK Take ownership of this object after merge with SceneGraph::RenderableAttachment
441
442   SceneGraph::NodeAttachment* attachment = static_cast<SceneGraph::NodeAttachment*>(renderer);
443   attachment->Initialize( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
444 }
445
446 void UpdateManager::AddObject( PropertyOwner* object )
447 {
448   DALI_ASSERT_DEBUG( NULL != object );
449
450   mImpl->customObjects.PushBack( object );
451 }
452
453 void UpdateManager::RemoveObject( PropertyOwner* object )
454 {
455   DALI_ASSERT_DEBUG( NULL != object );
456
457   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
458
459   // Find the object and destroy it
460   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
461   {
462     PropertyOwner* current = *iter;
463     if ( current == object )
464     {
465       customObjects.Erase( iter );
466       return;
467     }
468   }
469
470   // Should not reach here
471   DALI_ASSERT_DEBUG(false);
472 }
473
474 void UpdateManager::AddAnimation( Animation* animation )
475 {
476   mImpl->animations.PushBack( animation );
477 }
478
479 void UpdateManager::StopAnimation( Animation* animation )
480 {
481   DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
482
483   bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
484
485   mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
486 }
487
488 void UpdateManager::RemoveAnimation( Animation* animation )
489 {
490   DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
491
492   animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
493
494   DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
495 }
496
497 bool UpdateManager::IsAnimationRunning() const
498 {
499   bool isRunning(false);
500   AnimationContainer& animations = mImpl->animations;
501
502   // Find any animation that isn't stopped or paused
503
504   const AnimationIter endIter = animations.End();
505   for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
506   {
507     const Animation::State state = (*iter)->GetState();
508
509     if (state != Animation::Stopped &&
510         state != Animation::Paused)
511     {
512       isRunning = true;
513     }
514   }
515
516   return isRunning;
517 }
518
519 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
520 {
521   mImpl->propertyNotifications.PushBack( propertyNotification );
522 }
523
524 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
525 {
526   PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
527   PropertyNotificationIter iter = propertyNotifications.Begin();
528
529   while ( iter != propertyNotifications.End() )
530   {
531     if( *iter == propertyNotification )
532     {
533       propertyNotifications.Erase(iter);
534       break;
535     }
536     ++iter;
537   }
538 }
539
540 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
541 {
542   DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
543   propertyNotification->SetNotifyMode( notifyMode );
544 }
545
546 ObjectOwnerContainer<Geometry>& UpdateManager::GetGeometryOwner()
547 {
548   return mImpl->geometries;
549 }
550
551 ObjectOwnerContainer<Material>& UpdateManager::GetMaterialOwner()
552 {
553   return mImpl->materials;
554 }
555
556 ObjectOwnerContainer<Sampler>& UpdateManager::GetSamplerOwner()
557 {
558   return mImpl->samplers;
559 }
560
561 ObjectOwnerContainer<PropertyBuffer>& UpdateManager::GetPropertyBufferOwner()
562 {
563   return mImpl->propertyBuffers;
564 }
565
566 void UpdateManager::AddShader( Shader* shader )
567 {
568   DALI_ASSERT_DEBUG( NULL != shader );
569
570   if( mImpl->shaders.Count() == 0 )
571   {
572     // the first added shader becomes our default shader
573     // Construct message in the render queue memory; note that delete should not be called on the return value
574     typedef MessageValue1< RenderManager, Shader* > DerivedType;
575
576     // Reserve some memory inside the render queue
577     unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
578
579     // Construct message in the render queue memory; note that delete should not be called on the return value
580     new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
581   }
582
583   mImpl->shaders.PushBack( shader );
584
585   // Allows the shader to dispatch texture requests to the cache
586   shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
587 }
588
589 void UpdateManager::RemoveShader( Shader* shader )
590 {
591   DALI_ASSERT_DEBUG(shader != NULL);
592
593   ShaderContainer& shaders = mImpl->shaders;
594
595   // Find the shader and destroy it
596   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
597   {
598     Shader& current = **iter;
599     if ( &current == shader )
600     {
601       // Transfer ownership to the discard queue
602       // This keeps the shader alive, until the render-thread has finished with it
603       mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
604
605       return;
606     }
607   }
608   // Should not reach here
609   DALI_ASSERT_DEBUG(false);
610 }
611
612 void UpdateManager::SetShaderProgram( Shader* shader,
613                                       Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
614 {
615   if( shaderData )
616   {
617
618     typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
619
620     // Reserve some memory inside the render queue
621     unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
622
623     // Construct message in the render queue memory; note that delete should not be called on the return value
624     new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
625   }
626 }
627
628 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
629 {
630   DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
631   DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
632   mImpl->compiledShaders[mSceneGraphBuffers.GetUpdateBufferIndex() > 0 ? 0 : 1].push_back( shaderData );
633 }
634
635 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
636 {
637   if ( !systemLevel )
638   {
639     // copy the list, this is only likely to happen once in application life cycle
640     return &(mImpl->taskList);
641   }
642   else
643   {
644     // copy the list, this is only likely to happen once in application life cycle
645     return &(mImpl->systemLevelTaskList);
646   }
647 }
648
649 void UpdateManager::AddGesture( PanGesture* gesture )
650 {
651   DALI_ASSERT_DEBUG( NULL != gesture );
652
653   mImpl->gestures.PushBack( gesture );
654 }
655
656 void UpdateManager::RemoveGesture( PanGesture* gesture )
657 {
658   DALI_ASSERT_DEBUG( gesture != NULL );
659
660   GestureContainer& gestures = mImpl->gestures;
661
662   // Find the gesture and destroy it
663   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
664   {
665     PanGesture& current = **iter;
666     if ( &current == gesture )
667     {
668       mImpl->gestures.Erase( iter );
669       return;
670     }
671   }
672   // Should not reach here
673   DALI_ASSERT_DEBUG(false);
674 }
675
676 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
677 {
678   return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
679 }
680
681 void UpdateManager::EventProcessingStarted()
682 {
683   mImpl->messageQueue.EventProcessingStarted();
684 }
685
686 bool UpdateManager::FlushQueue()
687 {
688   return mImpl->messageQueue.FlushQueue();
689 }
690
691 void UpdateManager::ResetNodeProperty( Node& node )
692 {
693   BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
694
695   node.ResetToBaseValues( bufferIndex );
696 }
697
698 void UpdateManager::ResetProperties()
699 {
700   PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
701
702   BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
703
704   // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
705   mImpl->animationFinishedDuringUpdate = false;
706
707   // Animated properties have to be reset to their original value each frame
708
709   // Reset node properties
710   if ( mImpl->root )
711   {
712     ResetNodeProperty( *mImpl->root );
713   }
714
715   if ( mImpl->systemLevelRoot )
716   {
717     ResetNodeProperty( *mImpl->systemLevelRoot );
718   }
719
720   // Reset the Connected Nodes
721   const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
722   for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
723   {
724     ResetNodeProperty( **iter );
725   }
726
727   // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
728   for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
729   {
730     Node* node = *iter;
731     node->ResetToBaseValues( bufferIndex );
732     node->SetActive( false );
733
734     // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
735     mImpl->activeDisconnectedNodes.erase( iter );
736     mImpl->disconnectedNodes.insert( node );
737   }
738
739   // Reset system-level render-task list properties to base values
740   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
741
742   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
743   {
744     (*iter)->ResetToBaseValues( bufferIndex );
745   }
746
747   // Reset render-task list properties to base values.
748   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
749
750   for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
751   {
752     (*iter)->ResetToBaseValues( bufferIndex );
753   }
754
755   // Reset custom object properties to base values
756   for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
757   {
758     (*iter)->ResetToBaseValues( bufferIndex );
759   }
760
761   mImpl->materials.ResetToBaseValues( bufferIndex );
762   mImpl->geometries.ResetToBaseValues( bufferIndex );
763   mImpl->propertyBuffers.ResetToBaseValues( bufferIndex );
764   mImpl->samplers.ResetToBaseValues( bufferIndex );
765
766
767   // Reset animatable shader properties to base values
768   for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
769   {
770     (*iter)->ResetToBaseValues( bufferIndex );
771   }
772
773   PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
774 }
775
776 bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
777 {
778   bool gestureUpdated( false );
779
780   // constrain gestures... (in construction order)
781   GestureContainer& gestures = mImpl->gestures;
782
783   for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
784   {
785     PanGesture& gesture = **iter;
786     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
787     gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
788   }
789
790   return gestureUpdated;
791 }
792
793 void UpdateManager::Animate( float elapsedSeconds )
794 {
795   PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
796
797   AnimationContainer &animations = mImpl->animations;
798   AnimationIter iter = animations.Begin();
799   while ( iter != animations.End() )
800   {
801     Animation* animation = *iter;
802     bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds);
803
804     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
805
806     // Remove animations that had been destroyed but were still waiting for an update
807     if (animation->GetState() == Animation::Destroyed)
808     {
809       iter = animations.Erase(iter);
810     }
811     else
812     {
813       ++iter;
814     }
815   }
816
817   if ( mImpl->animationFinishedDuringUpdate )
818   {
819     // The application should be notified by NotificationManager, in another thread
820     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
821   }
822
823   PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
824 }
825
826 void UpdateManager::ApplyConstraints()
827 {
828   PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
829
830   BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
831
832   // constrain custom objects... (in construction order)
833   OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
834
835   const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
836   for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
837   {
838     PropertyOwner& object = **iter;
839     ConstrainPropertyOwner( object, bufferIndex );
840   }
841
842   // constrain nodes... (in Depth First traversal order)
843   if ( mImpl->root )
844   {
845     ConstrainNodes( *(mImpl->root), bufferIndex );
846   }
847
848   if ( mImpl->systemLevelRoot )
849   {
850     ConstrainNodes( *(mImpl->systemLevelRoot), bufferIndex );
851   }
852
853   // constrain other property-owners after nodes as they are more likely to depend on a node's
854   // current frame property than vice versa. They tend to be final constraints (no further
855   // constraints depend on their properties)
856   // e.g. ShaderEffect uniform a function of Actor's position.
857   // Mesh vertex a function of Actor's position or world position.
858
859   // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
860   // they can be all processed in a super-list of property-owners.
861
862   // Constrain system-level render-tasks
863   const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
864
865   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
866   {
867     RenderTask& task = **iter;
868     ConstrainPropertyOwner( task, bufferIndex );
869   }
870
871   // Constrain render-tasks
872   const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
873
874   for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
875   {
876     RenderTask& task = **iter;
877     ConstrainPropertyOwner( task, bufferIndex );
878   }
879
880   // Constrain Materials and geometries
881   mImpl->materials.ConstrainObjects( bufferIndex );
882   mImpl->geometries.ConstrainObjects( bufferIndex );
883   mImpl->samplers.ConstrainObjects( bufferIndex );
884   mImpl->propertyBuffers.ConstrainObjects( bufferIndex );
885
886   // constrain shaders... (in construction order)
887   ShaderContainer& shaders = mImpl->shaders;
888
889   for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
890   {
891     Shader& shader = **iter;
892     ConstrainPropertyOwner( shader, bufferIndex );
893   }
894
895   PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
896 }
897
898 void UpdateManager::ProcessPropertyNotifications()
899 {
900   PropertyNotificationContainer &notifications = mImpl->propertyNotifications;
901   PropertyNotificationIter iter = notifications.Begin();
902
903   BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
904
905   while ( iter != notifications.End() )
906   {
907     PropertyNotification* notification = *iter;
908     bool valid = notification->Check( bufferIndex );
909     if(valid)
910     {
911       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
912     }
913     ++iter;
914   }
915 }
916
917 void UpdateManager::ForwardCompiledShadersToEventThread()
918 {
919   DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
920   if( mImpl->shaderSaver )
921   {
922     ShaderDataBatchedQueue& compiledShaders = mImpl->compiledShaders[mSceneGraphBuffers.GetUpdateBufferIndex()];
923     if( compiledShaders.size() > 0 )
924     {
925       ShaderSaver& factory = *mImpl->shaderSaver;
926       ShaderDataBatchedQueueIterator i   = compiledShaders.begin();
927       ShaderDataBatchedQueueIterator end = compiledShaders.end();
928       for( ; i != end; ++i )
929       {
930         mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
931       }
932     }
933   }
934 }
935
936 void UpdateManager::UpdateNodes()
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                                                      mSceneGraphBuffers.GetUpdateBufferIndex(),
951                                                      mImpl->resourceManager,
952                                                      mImpl->renderQueue );
953
954   if ( mImpl->systemLevelRoot )
955   {
956     mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
957                                                         mSceneGraphBuffers.GetUpdateBufferIndex(),
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   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( 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();
1004   }
1005
1006   // 5) Process the queued scene messages
1007   mImpl->messageQueue.ProcessMessages();
1008
1009   // 6) Post Process Ids of resources updated by renderer
1010   mImpl->resourceManager.PostProcessResources( bufferIndex );
1011
1012   // 6.1) Forward a batch of 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( elapsedSeconds );
1022
1023     // 8) Apply Constraints
1024     ApplyConstraints();
1025
1026     // 9) Check Property Notifications
1027     ProcessPropertyNotifications();
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();
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( mSceneGraphBuffers.GetUpdateBufferIndex(),
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   // The update has finished; swap the double-buffering indices
1121   mSceneGraphBuffers.Swap();
1122
1123   // tell the update manager that we're done so the queue can be given to event thread
1124   mImpl->notificationManager.UpdateCompleted();
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