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