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