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