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