Refactored Animator classes to reduce code binary size by 60%
[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   OwnerContainer< Animation* >         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   auto&& iter = mImpl->animations.Begin();
648   bool animationLooped = false;
649
650   while ( iter != mImpl->animations.End() )
651   {
652     Animation* animation = *iter;
653     bool finished = false;
654     bool looped = false;
655     bool progressMarkerReached = false;
656     animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
657
658     if ( progressMarkerReached )
659     {
660       mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
661     }
662
663     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
664     animationLooped = animationLooped || looped;
665
666     // Remove animations that had been destroyed but were still waiting for an update
667     if (animation->GetState() == Animation::Destroyed)
668     {
669       iter = mImpl->animations.Erase(iter);
670     }
671     else
672     {
673       ++iter;
674     }
675   }
676
677   // queue the notification on finished or looped (to update loop count)
678   if ( mImpl->animationFinishedDuringUpdate || animationLooped )
679   {
680     // The application should be notified by NotificationManager, in another thread
681     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
682   }
683 }
684
685 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
686 {
687   //Constrain custom objects (in construction order)
688   for ( auto&& object : mImpl->customObjects )
689   {
690     ConstrainPropertyOwner( *object, bufferIndex );
691   }
692 }
693
694 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
695 {
696   // Constrain render-tasks
697   for( auto taskList : mImpl->taskLists )
698   {
699     RenderTaskList::RenderTaskContainer& tasks = taskList->GetTasks();
700     for ( auto&& task : tasks )
701     {
702       ConstrainPropertyOwner( *task, bufferIndex );
703     }
704   }
705 }
706
707 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
708 {
709   // constrain shaders... (in construction order)
710   for ( auto&& shader : mImpl->shaders )
711   {
712     ConstrainPropertyOwner( *shader, bufferIndex );
713   }
714 }
715
716 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
717 {
718   for( auto&& notification : mImpl->propertyNotifications )
719   {
720     bool valid = notification->Check( bufferIndex );
721     if(valid)
722     {
723       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
724     }
725   }
726 }
727
728 void UpdateManager::ForwardCompiledShadersToEventThread()
729 {
730   DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
731   if( mImpl->shaderSaver )
732   {
733     // lock and swap the queues
734     {
735       // render might be attempting to send us more binaries at the same time
736       Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
737       mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
738     }
739
740     if( mImpl->updateCompiledShaders.size() > 0 )
741     {
742       ShaderSaver& factory = *mImpl->shaderSaver;
743       for( auto&& shader : mImpl->updateCompiledShaders )
744       {
745         mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
746       }
747       // we don't need them in update anymore
748       mImpl->updateCompiledShaders.clear();
749     }
750   }
751 }
752
753 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
754 {
755   for( auto&& renderer : mImpl->renderers )
756   {
757     //Apply constraints
758     ConstrainPropertyOwner( *renderer, bufferIndex );
759
760     renderer->PrepareRender( bufferIndex );
761   }
762 }
763
764 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
765 {
766   mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
767
768   for( auto&& rootLayer : mImpl->roots )
769   {
770     // Prepare resources, update shaders, for each node
771     // And add the renderers to the sorted layers. Start from root, which is also a layer
772     mImpl->nodeDirtyFlags |= UpdateNodeTree( *rootLayer,
773                                             bufferIndex,
774                                             mImpl->renderQueue );
775   }
776 }
777
778 uint32_t UpdateManager::Update( float elapsedSeconds,
779                                 uint32_t lastVSyncTimeMilliseconds,
780                                 uint32_t nextVSyncTimeMilliseconds,
781                                 bool renderToFboEnabled,
782                                 bool isRenderingToFbo )
783 {
784   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
785
786   //Clear nodes/resources which were previously discarded
787   mImpl->discardQueue.Clear( bufferIndex );
788
789   //Process Touches & Gestures
790   const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
791
792   bool updateScene = // The scene-graph requires an update if..
793       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||    // ..nodes were dirty in previous frame OR
794       IsAnimationRunning()                            ||    // ..at least one animation is running OR
795       mImpl->messageQueue.IsSceneUpdateRequired()     ||    // ..a message that modifies the scene graph node tree is queued OR
796       gestureUpdated;                                       // ..a gesture property was updated
797
798
799   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
800   // values if the scene was updated in the previous frame.
801   if( updateScene || mImpl->previousUpdateScene )
802   {
803     //Reset properties from the previous update
804     ResetProperties( bufferIndex );
805     mImpl->transformManager.ResetToBaseValue();
806   }
807
808   // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
809   // between calling IsSceneUpdateRequired() above and here, so updateScene should
810   // be set again
811   updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
812
813   //Forward compiled shader programs to event thread for saving
814   ForwardCompiledShadersToEventThread();
815
816   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
817   // renderer lists if the scene was updated in the previous frame.
818   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
819   if( updateScene || mImpl->previousUpdateScene )
820   {
821     //Animate
822     Animate( bufferIndex, elapsedSeconds );
823
824     //Constraint custom objects
825     ConstrainCustomObjects( bufferIndex );
826
827     //Clear the lists of renderers from the previous update
828     for( auto sortedLayers : mImpl->sortedLayerLists )
829     {
830       for( auto&& layer : sortedLayers )
831       {
832         layer->ClearRenderables();
833       }
834     }
835
836     // Call the frame-callback-processor if set
837     if( mImpl->frameCallbackProcessor )
838     {
839       mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
840     }
841
842     //Update node hierarchy, apply constraints and perform sorting / culling.
843     //This will populate each Layer with a list of renderers which are ready.
844     UpdateNodes( bufferIndex );
845
846     //Apply constraints to RenderTasks, shaders
847     ConstrainRenderTasks( bufferIndex );
848     ConstrainShaders( bufferIndex );
849
850     //Update renderers and apply constraints
851     UpdateRenderers( bufferIndex );
852
853     //Update the transformations of all the nodes
854     mImpl->transformManager.Update();
855
856     //Process Property Notifications
857     ProcessPropertyNotifications( bufferIndex );
858
859     //Update cameras
860     for( auto&& cameraIterator : mImpl->cameras )
861     {
862       cameraIterator->Update( bufferIndex );
863     }
864
865     //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
866     //reset the update buffer index and make sure there is enough room in the instruction container
867     if( mImpl->renderersAdded )
868     {
869       // Calculate how many render tasks we have in total
870       VectorBase::SizeType numberOfRenderTasks = 0;
871
872       const VectorBase::SizeType taskListCount = mImpl->taskLists.Count();
873       for ( VectorBase::SizeType index = 0u; index < taskListCount; index++ )
874       {
875         numberOfRenderTasks += mImpl->taskLists[index]->GetTasks().Count();
876       }
877
878       mImpl->renderInstructions.ResetAndReserve( bufferIndex,
879                                                  static_cast<uint32_t>( numberOfRenderTasks ) );
880
881       for ( VectorBase::SizeType index = 0u; index < taskListCount; index++ )
882       {
883         if ( NULL != mImpl->roots[index] )
884         {
885           mImpl->renderTaskProcessor.Process( bufferIndex,
886                                               *mImpl->taskLists[index],
887                                               *mImpl->roots[index],
888                                               mImpl->sortedLayerLists[index],
889                                               mImpl->renderInstructions,
890                                               renderToFboEnabled,
891                                               isRenderingToFbo );
892         }
893       }
894     }
895   }
896
897   for( auto taskList : mImpl->taskLists )
898   {
899     RenderTaskList::RenderTaskContainer& tasks = taskList->GetTasks();
900
901     // check the countdown and notify
902     bool doRenderOnceNotify = false;
903     mImpl->renderTaskWaiting = false;
904     for ( auto&& renderTask : tasks )
905     {
906       renderTask->UpdateState();
907
908       if( renderTask->IsWaitingToRender() &&
909           renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
910       {
911         mImpl->renderTaskWaiting = true; // keep update/render threads alive
912       }
913
914       if( renderTask->HasRendered() )
915       {
916         doRenderOnceNotify = true;
917       }
918     }
919
920     if( doRenderOnceNotify )
921     {
922       DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
923       mImpl->notificationManager.QueueCompleteNotification( taskList->GetCompleteNotificationInterface() );
924     }
925   }
926
927   // Macro is undefined in release build.
928   SNAPSHOT_NODE_LOGGING;
929
930   // A ResetProperties() may be required in the next frame
931   mImpl->previousUpdateScene = updateScene;
932
933   // Check whether further updates are required
934   uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
935
936   // tell the update manager that we're done so the queue can be given to event thread
937   mImpl->notificationManager.UpdateCompleted();
938
939   // The update has finished; swap the double-buffering indices
940   mSceneGraphBuffers.Swap();
941
942   return keepUpdating;
943 }
944
945 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
946 {
947   // Update the duration set via Stage::KeepRendering()
948   if ( mImpl->keepRenderingSeconds > 0.0f )
949   {
950     mImpl->keepRenderingSeconds -= elapsedSeconds;
951   }
952
953   uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
954
955   // If the rendering behavior is set to continuously render, then continue to render.
956   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
957   // Keep updating until no messages are received and no animations are running.
958   // If an animation has just finished, update at least once more for Discard end-actions.
959   // No need to check for renderQueue as there is always a render after update and if that
960   // render needs another update it will tell the adaptor to call update again
961
962   if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
963        ( mImpl->keepRenderingSeconds > 0.0f ) )
964   {
965     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
966   }
967
968   if ( IsAnimationRunning() ||
969        mImpl->animationFinishedDuringUpdate )
970   {
971     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
972   }
973
974   if ( mImpl->renderTaskWaiting )
975   {
976     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
977   }
978
979   return keepUpdatingRequest;
980 }
981
982 void UpdateManager::SetBackgroundColor( const Vector4& color )
983 {
984   typedef MessageValue1< RenderManager, Vector4 > DerivedType;
985
986   // Reserve some memory inside the render queue
987   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
988
989   // Construct message in the render queue memory; note that delete should not be called on the return value
990   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
991 }
992
993 void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
994 {
995   mImpl->surfaceRectChanged = true;
996
997   typedef MessageValue1< RenderManager, Rect<int32_t> > DerivedType;
998
999   // Reserve some memory inside the render queue
1000   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1001
1002   // Construct message in the render queue memory; note that delete should not be called on the return value
1003   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceRect, rect );
1004 }
1005
1006 void UpdateManager::KeepRendering( float durationSeconds )
1007 {
1008   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1009 }
1010
1011 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1012 {
1013   mImpl->renderingBehavior = renderingBehavior;
1014 }
1015
1016 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1017 {
1018   const VectorBase::SizeType rootCount = mImpl->roots.Count();
1019
1020   // Make sure we reserve the correct size for the container so that
1021   // we can save the sorted layers in the same order as the root layer
1022   mImpl->sortedLayerLists.resize( rootCount );
1023
1024   for ( VectorBase::SizeType rootIndex = 0u; rootIndex < rootCount; rootIndex++ )
1025   {
1026     Layer* root = mImpl->roots[rootIndex];
1027     if ( root == rootLayer )
1028     {
1029       mImpl->sortedLayerLists[rootIndex] = layers;
1030       break;
1031     }
1032   }
1033 }
1034
1035 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1036 {
1037   // note,this vector is already in depth order. It could be used as-is to
1038   // remove sorting in update algorithm. However, it lacks layer boundary markers.
1039   for( auto&& iter : nodeDepths->nodeDepths )
1040   {
1041     iter.node->SetDepthIndex( iter.sortedDepth );
1042   }
1043
1044   for( auto root : mImpl->roots )
1045   {
1046     // Go through node hierarchy and rearrange siblings according to depth-index
1047     SortSiblingNodesRecursively( *root );
1048   }
1049 }
1050
1051 bool UpdateManager::IsDefaultSurfaceRectChanged()
1052 {
1053   bool surfaceRectChanged = mImpl->surfaceRectChanged;
1054
1055   // Reset the flag
1056   mImpl->surfaceRectChanged = false;
1057
1058   return surfaceRectChanged;
1059 }
1060
1061 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1062 {
1063   mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1064 }
1065
1066 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1067 {
1068   mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1069 }
1070
1071 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1072 {
1073   // Message has ownership of Sampler while in transit from update to render
1074   typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
1075
1076   // Reserve some memory inside the render queue
1077   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1078
1079   // Construct message in the render queue memory; note that delete should not be called on the return value
1080   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddSampler, sampler );
1081 }
1082
1083 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1084 {
1085   typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1086
1087   // Reserve some memory inside the render queue
1088   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1089
1090   // Construct message in the render queue memory; note that delete should not be called on the return value
1091   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveSampler, sampler );
1092 }
1093
1094 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1095 {
1096   typedef MessageValue3< RenderManager, Render::Sampler*, uint32_t, uint32_t > DerivedType;
1097
1098   // Reserve some memory inside the render queue
1099   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1100
1101   // Construct message in the render queue memory; note that delete should not be called on the return value
1102   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1103 }
1104
1105 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1106 {
1107   typedef MessageValue4< RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t > DerivedType;
1108
1109   // Reserve some memory inside the render queue
1110   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1111
1112   // Construct message in the render queue memory; note that delete should not be called on the return value
1113   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1114 }
1115
1116 void UpdateManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer )
1117 {
1118   // Message has ownership of format while in transit from update -> render
1119   typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
1120
1121   // Reserve some memory inside the render queue
1122   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1123
1124   // Construct message in the render queue memory; note that delete should not be called on the return value
1125   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddPropertyBuffer, propertyBuffer );
1126 }
1127
1128 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1129 {
1130   typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1131
1132   // Reserve some memory inside the render queue
1133   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1134
1135   // Construct message in the render queue memory; note that delete should not be called on the return value
1136   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemovePropertyBuffer, propertyBuffer );
1137 }
1138
1139 void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format )
1140 {
1141   // Message has ownership of format while in transit from update -> render
1142   typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
1143
1144   // Reserve some memory inside the render queue
1145   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1146
1147   // Construct message in the render queue memory; note that delete should not be called on the return value
1148   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1149 }
1150
1151 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1152 {
1153   // Message has ownership of format while in transit from update -> render
1154   typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<uint8_t> >, uint32_t > DerivedType;
1155
1156   // Reserve some memory inside the render queue
1157   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1158
1159   // Construct message in the render queue memory; note that delete should not be called on the return value
1160   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1161 }
1162
1163 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1164 {
1165   // Message has ownership of format while in transit from update -> render
1166   typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
1167
1168   // Reserve some memory inside the render queue
1169   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1170
1171   // Construct message in the render queue memory; note that delete should not be called on the return value
1172   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddGeometry, geometry );
1173 }
1174
1175 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1176 {
1177   typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1178
1179   // Reserve some memory inside the render queue
1180   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1181
1182   // Construct message in the render queue memory; note that delete should not be called on the return value
1183   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveGeometry, geometry );
1184 }
1185
1186 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1187 {
1188   typedef MessageValue2< RenderManager, Render::Geometry*, uint32_t > DerivedType;
1189
1190   // Reserve some memory inside the render queue
1191   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1192
1193   // Construct message in the render queue memory; note that delete should not be called on the return value
1194   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetGeometryType, geometry, geometryType );
1195 }
1196
1197 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1198 {
1199   typedef IndexBufferMessage< RenderManager > DerivedType;
1200
1201   // Reserve some memory inside the render queue
1202   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1203
1204   // Construct message in the render queue memory; note that delete should not be called on the return value
1205   new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1206 }
1207
1208 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1209 {
1210   typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1211
1212   // Reserve some memory inside the render queue
1213   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1214
1215   // Construct message in the render queue memory; note that delete should not be called on the return value
1216   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1217 }
1218
1219 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1220 {
1221   typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1222
1223   // Reserve some memory inside the render queue
1224   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1225
1226   // Construct message in the render queue memory; note that delete should not be called on the return value
1227   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachVertexBuffer, geometry, propertyBuffer );
1228 }
1229
1230 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1231 {
1232   // Message has ownership of Texture while in transit from update -> render
1233   typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
1234
1235   // Reserve some memory inside the render queue
1236   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1237
1238   // Construct message in the render queue memory; note that delete should not be called on the return value
1239   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1240 }
1241
1242 void UpdateManager::RemoveTexture( Render::Texture* texture)
1243 {
1244   typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1245
1246   // Reserve some memory inside the render queue
1247   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1248
1249   // Construct message in the render queue memory; note that delete should not be called on the return value
1250   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveTexture, texture );
1251 }
1252
1253 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1254 {
1255   typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1256
1257   // Reserve some memory inside the message queue
1258   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1259
1260   // Construct message in the message queue memory; note that delete should not be called on the return value
1261   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1262 }
1263
1264 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1265 {
1266   typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1267
1268   // Reserve some memory inside the render queue
1269   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1270
1271   // Construct message in the render queue memory; note that delete should not be called on the return value
1272   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::GenerateMipmaps, texture );
1273 }
1274
1275 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1276 {
1277   typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1278
1279   // Reserve some memory inside the render queue
1280   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1281
1282   // Construct message in the render queue memory; note that delete should not be called on the return value
1283   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddFrameBuffer, frameBuffer );
1284 }
1285
1286 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1287 {
1288   typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1289
1290   // Reserve some memory inside the render queue
1291   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1292
1293   // Construct message in the render queue memory; note that delete should not be called on the return value
1294   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveFrameBuffer, frameBuffer );
1295 }
1296
1297 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1298 {
1299   typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t > DerivedType;
1300
1301   // Reserve some memory inside the render queue
1302   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1303
1304   // Construct message in the render queue memory; note that delete should not be called on the return value
1305   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1306 }
1307
1308 } // namespace SceneGraph
1309
1310 } // namespace Internal
1311
1312 } // namespace Dali