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