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