Merge branch 'devel/master' into tizen
[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( nullptr ),
171     discardQueue( discardQueue ),
172     renderController( renderController ),
173     sceneController( nullptr ),
174     renderManager( renderManager ),
175     renderQueue( renderQueue ),
176     renderTaskProcessor( renderTaskProcessor ),
177     backgroundColor( Dali::DEFAULT_BACKGROUND_COLOR ),
178     renderers(),
179     textureSets(),
180     shaders(),
181     panGestureProcessor( nullptr ),
182     messageQueue( renderController, sceneGraphBuffers ),
183     frameCallbackProcessor( nullptr ),
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     renderingRequired( false )
193   {
194     sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
195
196     // create first 'dummy' node
197     nodes.PushBack(nullptr);
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( nullptr );
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                                 renderingRequired;             ///< True if required to render the current frame
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(nullptr)
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( nullptr == node->GetParent() ); // Should not have a parent yet
378
379   Node* rawNode = node.Release();
380   DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddNode\n", rawNode );
381
382   mImpl->nodes.PushBack(rawNode);
383   rawNode->CreateTransform(&mImpl->transformManager);
384 }
385
386 void UpdateManager::ConnectNode( Node* parent, Node* node )
387 {
388   DALI_ASSERT_ALWAYS( nullptr != parent );
389   DALI_ASSERT_ALWAYS( nullptr != node );
390   DALI_ASSERT_ALWAYS( nullptr == node->GetParent() ); // Should not have a parent yet
391
392   DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] ConnectNode\n", node );
393
394   parent->ConnectChild( node );
395
396   // Inform the frame-callback-processor, if set, about the node-hierarchy changing
397   if( mImpl->frameCallbackProcessor )
398   {
399     mImpl->frameCallbackProcessor->NodeHierarchyChanged();
400   }
401 }
402
403 void UpdateManager::DisconnectNode( Node* node )
404 {
405   DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DisconnectNode\n", node );
406
407   Node* parent = node->GetParent();
408   DALI_ASSERT_ALWAYS( nullptr != parent );
409   parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
410
411   parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
412
413   // Inform the frame-callback-processor, if set, about the node-hierarchy changing
414   if( mImpl->frameCallbackProcessor )
415   {
416     mImpl->frameCallbackProcessor->NodeHierarchyChanged();
417   }
418 }
419
420 void UpdateManager::DestroyNode( Node* node )
421 {
422   DALI_ASSERT_ALWAYS( nullptr != node );
423   DALI_ASSERT_ALWAYS( nullptr == node->GetParent() ); // Should have been disconnected
424
425   DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DestroyNode\n", node );
426
427   Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
428   Vector<Node*>::Iterator endIter = mImpl->nodes.End();
429   for(;iter!=endIter;++iter)
430   {
431     if((*iter) == node)
432     {
433       mImpl->nodes.Erase(iter);
434       break;
435     }
436   }
437
438   mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
439
440   // Notify the Node about impending destruction
441   node->OnDestroy();
442 }
443
444 void UpdateManager::AddCamera( OwnerPointer< Camera >& camera )
445 {
446   mImpl->cameras.PushBack( camera.Release() ); // takes ownership
447 }
448
449 void UpdateManager::RemoveCamera( Camera* camera )
450 {
451   // Find the camera and destroy it
452   EraseUsingDiscardQueue( mImpl->cameras, camera, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
453 }
454
455 void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
456 {
457   mImpl->customObjects.PushBack( object.Release() );
458 }
459
460 void UpdateManager::RemoveObject( PropertyOwner* object )
461 {
462   mImpl->customObjects.EraseObject( object );
463 }
464
465 void UpdateManager::AddRenderTaskList( OwnerPointer<RenderTaskList>& taskList )
466 {
467   RenderTaskList* taskListPointer = taskList.Release();
468   taskListPointer->SetRenderMessageDispatcher( &mImpl->renderMessageDispatcher );
469
470   mImpl->scenes.back()->taskList = taskListPointer;
471 }
472
473 void UpdateManager::RemoveRenderTaskList( RenderTaskList* taskList )
474 {
475   for ( auto&& scene : mImpl->scenes )
476   {
477     if ( scene && scene->taskList == taskList )
478     {
479       scene->taskList.Reset();
480       break;
481     }
482   }
483 }
484
485 void UpdateManager::AddScene( OwnerPointer< Scene >& scene )
486 {
487   mImpl->scenes.back()->scene = scene.Release();
488
489   // Initialize the context from render manager
490   typedef MessageValue1< RenderManager, SceneGraph::Scene* > DerivedType;
491
492   // Reserve some memory inside the render queue
493   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
494
495   // Construct message in the render queue memory; note that delete should not be called on the return value
496   SceneGraph::Scene& sceneObject = *mImpl->scenes.back()->scene;
497   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::InitializeScene, &sceneObject );
498 }
499
500 void UpdateManager::RemoveScene( Scene* scene )
501 {
502   // Initialize the context from render manager
503   using DerivedType = MessageValue1<RenderManager, SceneGraph::Scene*>;
504
505   // Reserve some memory inside the render queue
506   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
507
508   // Construct message in the render queue memory; note that delete should not be called on the return value
509   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::UninitializeScene, scene );
510
511   for ( auto&& sceneInfo : mImpl->scenes )
512   {
513     if ( sceneInfo && sceneInfo->scene && sceneInfo->scene.Get() == scene )
514     {
515       mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), sceneInfo->scene.Release() ); // take the address of the reference to a pointer
516       break;
517     }
518   }
519 }
520
521 void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
522 {
523   mImpl->animations.PushBack( animation.Release() );
524 }
525
526 void UpdateManager::StopAnimation( Animation* animation )
527 {
528   DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
529
530   bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
531
532   mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
533 }
534
535 void UpdateManager::RemoveAnimation( Animation* animation )
536 {
537   DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
538
539   animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
540
541   DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
542 }
543
544 bool UpdateManager::IsAnimationRunning() const
545 {
546   // Find any animation that isn't stopped or paused
547   for ( auto&& iter : mImpl->animations )
548   {
549     const Animation::State state = iter->GetState();
550
551     if (state != Animation::Stopped &&
552         state != Animation::Paused)
553     {
554       return true; // stop iteration as soon as first one is found
555     }
556   }
557
558   return false;
559 }
560
561 void UpdateManager::AddPropertyResetter( OwnerPointer<PropertyResetterBase>& propertyResetter )
562 {
563   propertyResetter->Initialize();
564   mImpl->propertyResetters.PushBack( propertyResetter.Release() );
565 }
566
567 void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification )
568 {
569   mImpl->propertyNotifications.PushBack( propertyNotification.Release() );
570 }
571
572 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
573 {
574   mImpl->propertyNotifications.EraseObject( propertyNotification );
575 }
576
577 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
578 {
579   DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
580   propertyNotification->SetNotifyMode( notifyMode );
581 }
582
583 void UpdateManager::AddShader( OwnerPointer< Shader >& shader )
584 {
585   mImpl->shaders.PushBack( shader.Release() );
586 }
587
588 void UpdateManager::RemoveShader( Shader* shader )
589 {
590   // Find the shader and destroy it
591   EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
592 }
593
594 void UpdateManager::SetShaderProgram( Shader* shader,
595                                       Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
596 {
597   if( shaderData )
598   {
599     using DerivedType = MessageValue3<Shader, Internal::ShaderDataPtr, ProgramCache*, bool>;
600
601     // Reserve some memory inside the render queue
602     uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
603
604     // Construct message in the render queue memory; note that delete should not be called on the return value
605     new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
606   }
607 }
608
609 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
610 {
611   DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
612   DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
613   {
614     // lock as update might be sending previously compiled shaders to event thread
615     Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
616     mImpl->renderCompiledShaders.push_back( shaderData );
617   }
618 }
619
620 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
621 {
622   mImpl->shaderSaver = &upstream;
623 }
624
625 void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer )
626 {
627   DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer.Get() );
628
629   renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
630   mImpl->renderers.PushBack( renderer.Release() );
631   mImpl->renderersAdded = true;
632 }
633
634 void UpdateManager::RemoveRenderer( Renderer* renderer )
635 {
636   DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] RemoveRenderer\n", renderer );
637
638   // Find the renderer and destroy it
639   EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
640   // Need to remove the render object as well
641   renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
642 }
643
644 void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor )
645 {
646   DALI_ASSERT_DEBUG( NULL != panGestureProcessor );
647
648   mImpl->panGestureProcessor = panGestureProcessor;
649 }
650
651 void UpdateManager::AddTextureSet( OwnerPointer< TextureSet >& textureSet )
652 {
653   mImpl->textureSets.PushBack( textureSet.Release() );
654 }
655
656 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
657 {
658   mImpl->textureSets.EraseObject( textureSet );
659 }
660
661 uint32_t* UpdateManager::ReserveMessageSlot( uint32_t size, bool updateScene )
662 {
663   return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
664 }
665
666 void UpdateManager::EventProcessingStarted()
667 {
668   mImpl->messageQueue.EventProcessingStarted();
669 }
670
671 bool UpdateManager::FlushQueue()
672 {
673   return mImpl->messageQueue.FlushQueue();
674 }
675
676 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
677 {
678   // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
679   mImpl->animationFinishedDuringUpdate = false;
680
681   // Reset all animating / constrained properties
682   std::vector<PropertyResetterBase*>toDelete;
683   for( auto&& element : mImpl->propertyResetters )
684   {
685     element->ResetToBaseValue( bufferIndex );
686     if( element->IsFinished() )
687     {
688       toDelete.push_back( element );
689     }
690   }
691
692   // If a resetter is no longer required (the animator or constraint has been removed), delete it.
693   for( auto&& elementPtr : toDelete )
694   {
695     mImpl->propertyResetters.EraseObject( elementPtr );
696   }
697
698   // Clear all root nodes dirty flags
699   for( auto& scene : mImpl->scenes )
700   {
701     auto root = scene->root;
702     root->ResetDirtyFlags( bufferIndex );
703   }
704
705   // Clear node dirty flags
706   Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
707   Vector<Node*>::Iterator endIter = mImpl->nodes.End();
708   for( ;iter != endIter; ++iter )
709   {
710     (*iter)->ResetDirtyFlags( bufferIndex );
711   }
712 }
713
714 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds )
715 {
716   bool gestureUpdated( false );
717
718   if( mImpl->panGestureProcessor )
719   {
720     // gesture processor only supports default properties
721     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
722     gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
723   }
724
725   return gestureUpdated;
726 }
727
728 bool UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
729 {
730   bool animationActive = false;
731
732   auto&& iter = mImpl->animations.Begin();
733   bool animationLooped = false;
734
735   while ( iter != mImpl->animations.End() )
736   {
737     Animation* animation = *iter;
738     bool finished = false;
739     bool looped = false;
740     bool progressMarkerReached = false;
741     animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
742
743     animationActive = animationActive || animation->IsActive();
744
745     if ( progressMarkerReached )
746     {
747       mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
748     }
749
750     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
751     animationLooped = animationLooped || looped;
752
753     // Remove animations that had been destroyed but were still waiting for an update
754     if (animation->GetState() == Animation::Destroyed)
755     {
756       iter = mImpl->animations.Erase(iter);
757     }
758     else
759     {
760       ++iter;
761     }
762   }
763
764   // queue the notification on finished or looped (to update loop count)
765   if ( mImpl->animationFinishedDuringUpdate || animationLooped )
766   {
767     // The application should be notified by NotificationManager, in another thread
768     mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
769   }
770
771   return animationActive;
772 }
773
774 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
775 {
776   //Constrain custom objects (in construction order)
777   for ( auto&& object : mImpl->customObjects )
778   {
779     ConstrainPropertyOwner( *object, bufferIndex );
780   }
781 }
782
783 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
784 {
785   // Constrain render-tasks
786   for ( auto&& scene : mImpl->scenes )
787   {
788     if ( scene && scene->taskList )
789     {
790       RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
791       for ( auto&& task : tasks )
792       {
793         ConstrainPropertyOwner( *task, bufferIndex );
794       }
795     }
796   }
797 }
798
799 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
800 {
801   // constrain shaders... (in construction order)
802   for ( auto&& shader : mImpl->shaders )
803   {
804     ConstrainPropertyOwner( *shader, bufferIndex );
805   }
806 }
807
808 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
809 {
810   for( auto&& notification : mImpl->propertyNotifications )
811   {
812     bool valid = notification->Check( bufferIndex );
813     if(valid)
814     {
815       mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
816     }
817   }
818 }
819
820 void UpdateManager::ForwardCompiledShadersToEventThread()
821 {
822   DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
823   if( mImpl->shaderSaver )
824   {
825     // lock and swap the queues
826     {
827       // render might be attempting to send us more binaries at the same time
828       Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
829       mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
830     }
831
832     if( mImpl->updateCompiledShaders.size() > 0 )
833     {
834       ShaderSaver& factory = *mImpl->shaderSaver;
835       for( auto&& shader : mImpl->updateCompiledShaders )
836       {
837         mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
838       }
839       // we don't need them in update anymore
840       mImpl->updateCompiledShaders.clear();
841     }
842   }
843 }
844
845 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
846 {
847   for( auto&& renderer : mImpl->renderers )
848   {
849     //Apply constraints
850     ConstrainPropertyOwner( *renderer, bufferIndex );
851
852     mImpl->renderingRequired = renderer->PrepareRender( bufferIndex ) || mImpl->renderingRequired;
853   }
854 }
855
856 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
857 {
858   mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
859
860   for ( auto&& scene : mImpl->scenes )
861   {
862     if ( scene && scene->root )
863     {
864       // Prepare resources, update shaders, for each node
865       // And add the renderers to the sorted layers. Start from root, which is also a layer
866       mImpl->nodeDirtyFlags |= UpdateNodeTree( *scene->root,
867                                               bufferIndex,
868                                               mImpl->renderQueue );
869     }
870   }
871 }
872
873 uint32_t UpdateManager::Update( float elapsedSeconds,
874                                 uint32_t lastVSyncTimeMilliseconds,
875                                 uint32_t nextVSyncTimeMilliseconds,
876                                 bool renderToFboEnabled,
877                                 bool isRenderingToFbo )
878 {
879   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
880
881   //Clear nodes/resources which were previously discarded
882   mImpl->discardQueue.Clear( bufferIndex );
883
884   bool isAnimationRunning = IsAnimationRunning();
885
886   //Process Touches & Gestures
887   const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
888
889   bool updateScene = // The scene-graph requires an update if..
890       (mImpl->nodeDirtyFlags & RenderableUpdateFlags) ||    // ..nodes were dirty in previous frame OR
891       isAnimationRunning                              ||    // ..at least one animation is running OR
892       mImpl->messageQueue.IsSceneUpdateRequired()     ||    // ..a message that modifies the scene graph node tree is queued OR
893       mImpl->frameCallbackProcessor                   ||    // ..a frame callback processor is existed OR
894       gestureUpdated;                                       // ..a gesture property was updated
895
896   bool keepRendererRendering = false;
897   mImpl->renderingRequired = false;
898
899   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
900   // values if the scene was updated in the previous frame.
901   if( updateScene || mImpl->previousUpdateScene )
902   {
903     //Reset properties from the previous update
904     ResetProperties( bufferIndex );
905     mImpl->transformManager.ResetToBaseValue();
906   }
907
908   // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
909   // between calling IsSceneUpdateRequired() above and here, so updateScene should
910   // be set again
911   updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
912
913   //Forward compiled shader programs to event thread for saving
914   ForwardCompiledShadersToEventThread();
915
916   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
917   // renderer lists if the scene was updated in the previous frame.
918   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
919   if( updateScene || mImpl->previousUpdateScene )
920   {
921     //Animate
922     bool animationActive = Animate( bufferIndex, elapsedSeconds );
923
924     //Constraint custom objects
925     ConstrainCustomObjects( bufferIndex );
926
927     //Clear the lists of renderers from the previous update
928     for( auto&& scene : mImpl->scenes )
929     {
930       if ( scene )
931       {
932         for( auto&& layer : scene->sortedLayerList )
933         {
934           if ( layer )
935           {
936             layer->ClearRenderables();
937           }
938         }
939       }
940     }
941
942     // Call the frame-callback-processor if set
943     if( mImpl->frameCallbackProcessor )
944     {
945       mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
946     }
947
948     //Update node hierarchy, apply constraints and perform sorting / culling.
949     //This will populate each Layer with a list of renderers which are ready.
950     UpdateNodes( bufferIndex );
951
952     //Apply constraints to RenderTasks, shaders
953     ConstrainRenderTasks( bufferIndex );
954     ConstrainShaders( bufferIndex );
955
956     //Update renderers and apply constraints
957     UpdateRenderers( bufferIndex );
958
959     //Update the transformations of all the nodes
960     if ( mImpl->transformManager.Update() )
961     {
962       mImpl->nodeDirtyFlags |= NodePropertyFlags::TRANSFORM;
963     }
964
965     //Process Property Notifications
966     ProcessPropertyNotifications( bufferIndex );
967
968     //Update cameras
969     for( auto&& cameraIterator : mImpl->cameras )
970     {
971       cameraIterator->Update( bufferIndex );
972     }
973
974     //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
975     //reset the update buffer index and make sure there is enough room in the instruction container
976     if( mImpl->renderersAdded )
977     {
978       // Calculate how many render tasks we have in total
979       std::size_t numberOfRenderTasks = 0;
980       for (auto&& scene : mImpl->scenes )
981       {
982         if ( scene && scene->taskList )
983         {
984           numberOfRenderTasks += scene->taskList->GetTasks().Count();
985         }
986       }
987
988       std::size_t numberOfRenderInstructions = 0;
989       for ( auto&& scene : mImpl->scenes )
990       {
991         if ( scene && scene->root && scene->taskList && scene->scene )
992         {
993           scene->scene->GetRenderInstructions().ResetAndReserve( bufferIndex,
994                                                      static_cast<uint32_t>( scene->taskList->GetTasks().Count() ) );
995
996           // If there are animations running, only add render instruction if at least one animation is currently active (i.e. not delayed)
997           // or the nodes are dirty
998           if ( !isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags) )
999           {
1000             keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
1001                                                 *scene->taskList,
1002                                                 *scene->root,
1003                                                 scene->sortedLayerList,
1004                                                 scene->scene->GetRenderInstructions(),
1005                                                 renderToFboEnabled,
1006                                                 isRenderingToFbo );
1007
1008             scene->scene->SetSkipRendering( false );
1009           }
1010           else
1011           {
1012             scene->scene->SetSkipRendering( true );
1013           }
1014
1015           numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count( bufferIndex );
1016         }
1017       }
1018
1019       DALI_LOG_INFO( gLogFilter, Debug::General,
1020                      "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n",
1021                      numberOfRenderTasks, numberOfRenderInstructions );
1022     }
1023   }
1024
1025   for ( auto&& scene : mImpl->scenes )
1026   {
1027     if ( scene && scene->root && scene->taskList )
1028     {
1029       RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
1030
1031       // check the countdown and notify
1032       bool doRenderOnceNotify = false;
1033       mImpl->renderTaskWaiting = false;
1034       for ( auto&& renderTask : tasks )
1035       {
1036         renderTask->UpdateState();
1037
1038         if( renderTask->IsWaitingToRender() &&
1039             renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1040         {
1041           mImpl->renderTaskWaiting = true; // keep update/render threads alive
1042         }
1043
1044         if( renderTask->HasRendered() )
1045         {
1046           doRenderOnceNotify = true;
1047         }
1048       }
1049
1050       if( doRenderOnceNotify )
1051       {
1052         DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1053         mImpl->notificationManager.QueueCompleteNotification( scene->taskList->GetCompleteNotificationInterface() );
1054       }
1055     }
1056   }
1057
1058   // Macro is undefined in release build.
1059   SNAPSHOT_NODE_LOGGING;
1060
1061   // A ResetProperties() may be required in the next frame
1062   mImpl->previousUpdateScene = updateScene;
1063
1064   // Check whether further updates are required
1065   uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1066
1067   if( keepRendererRendering )
1068   {
1069     keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
1070
1071     // Set dirty flags for next frame to continue rendering
1072     mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
1073   }
1074
1075   // tell the update manager that we're done so the queue can be given to event thread
1076   mImpl->notificationManager.UpdateCompleted();
1077
1078   // The update has finished; swap the double-buffering indices
1079   mSceneGraphBuffers.Swap();
1080
1081   return keepUpdating;
1082 }
1083
1084 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1085 {
1086   // Update the duration set via Stage::KeepRendering()
1087   if ( mImpl->keepRenderingSeconds > 0.0f )
1088   {
1089     mImpl->keepRenderingSeconds -= elapsedSeconds;
1090   }
1091
1092   uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1093
1094   // If the rendering behavior is set to continuously render, then continue to render.
1095   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1096   // Keep updating until no messages are received and no animations are running.
1097   // If an animation has just finished, update at least once more for Discard end-actions.
1098   // No need to check for renderQueue as there is always a render after update and if that
1099   // render needs another update it will tell the adaptor to call update again
1100
1101   if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
1102        ( mImpl->keepRenderingSeconds > 0.0f ) )
1103   {
1104     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1105   }
1106
1107   if ( IsAnimationRunning() ||
1108        mImpl->animationFinishedDuringUpdate )
1109   {
1110     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1111   }
1112
1113   if ( mImpl->renderTaskWaiting )
1114   {
1115     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1116   }
1117
1118   return keepUpdatingRequest;
1119 }
1120
1121 void UpdateManager::SurfaceReplaced( Scene* scene )
1122 {
1123   using DerivedType = MessageValue1<RenderManager, Scene*>;
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::SurfaceReplaced, scene );
1130 }
1131
1132 void UpdateManager::KeepRendering( float durationSeconds )
1133 {
1134   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1135 }
1136
1137 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1138 {
1139   mImpl->renderingBehavior = renderingBehavior;
1140 }
1141
1142 void UpdateManager::RequestRendering()
1143 {
1144   mImpl->renderingRequired = true;
1145 }
1146
1147 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1148 {
1149   for ( auto&& scene : mImpl->scenes )
1150   {
1151     if ( scene && scene->root == rootLayer )
1152     {
1153       scene->sortedLayerList = layers;
1154       break;
1155     }
1156   }
1157 }
1158
1159 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1160 {
1161   // note,this vector is already in depth order. It could be used as-is to
1162   // remove sorting in update algorithm. However, it lacks layer boundary markers.
1163   for( auto&& iter : nodeDepths->nodeDepths )
1164   {
1165     iter.node->SetDepthIndex( iter.sortedDepth );
1166   }
1167
1168   for ( auto&& scene : mImpl->scenes )
1169   {
1170     if ( scene )
1171     {
1172       // Go through node hierarchy and rearrange siblings according to depth-index
1173       SortSiblingNodesRecursively( *scene->root );
1174     }
1175   }
1176 }
1177
1178 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1179 {
1180   mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1181 }
1182
1183 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1184 {
1185   mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1186 }
1187
1188 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1189 {
1190   // Message has ownership of Sampler while in transit from update to render
1191   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Sampler> >;
1192
1193   // Reserve some memory inside the render queue
1194   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1195
1196   // Construct message in the render queue memory; note that delete should not be called on the return value
1197   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddSampler, sampler );
1198 }
1199
1200 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1201 {
1202   using DerivedType = MessageValue1<RenderManager, Render::Sampler*>;
1203
1204   // Reserve some memory inside the render queue
1205   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1206
1207   // Construct message in the render queue memory; note that delete should not be called on the return value
1208   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveSampler, sampler );
1209 }
1210
1211 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1212 {
1213   using DerivedType = MessageValue3<RenderManager, Render::Sampler*, uint32_t, uint32_t>;
1214
1215   // Reserve some memory inside the render queue
1216   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1217
1218   // Construct message in the render queue memory; note that delete should not be called on the return value
1219   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1220 }
1221
1222 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1223 {
1224   using DerivedType = MessageValue4<RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t>;
1225
1226   // Reserve some memory inside the render queue
1227   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1228
1229   // Construct message in the render queue memory; note that delete should not be called on the return value
1230   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1231 }
1232
1233 void UpdateManager::AddVertexBuffer( OwnerPointer< Render::VertexBuffer >& vertexBuffer )
1234 {
1235   // Message has ownership of format while in transit from update -> render
1236   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer> >;
1237
1238   // Reserve some memory inside the render queue
1239   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1240
1241   // Construct message in the render queue memory; note that delete should not be called on the return value
1242   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddVertexBuffer, vertexBuffer );
1243 }
1244
1245 void UpdateManager::RemoveVertexBuffer( Render::VertexBuffer* vertexBuffer )
1246 {
1247   using DerivedType = MessageValue1<RenderManager, Render::VertexBuffer*>;
1248
1249   // Reserve some memory inside the render queue
1250   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1251
1252   // Construct message in the render queue memory; note that delete should not be called on the return value
1253   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveVertexBuffer, vertexBuffer );
1254 }
1255
1256 void UpdateManager::SetVertexBufferFormat( Render::VertexBuffer* vertexBuffer, OwnerPointer< Render::VertexBuffer::Format>& format )
1257 {
1258   // Message has ownership of format while in transit from update -> render
1259   using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, OwnerPointer<Render::VertexBuffer::Format> >;
1260
1261   // Reserve some memory inside the render queue
1262   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1263
1264   // Construct message in the render queue memory; note that delete should not be called on the return value
1265   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetVertexBufferFormat, vertexBuffer, format );
1266 }
1267
1268 void UpdateManager::SetVertexBufferData( Render::VertexBuffer* vertexBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1269 {
1270   // Message has ownership of format while in transit from update -> render
1271   using DerivedType = MessageValue3<RenderManager, Render::VertexBuffer*, OwnerPointer<Dali::Vector<uint8_t> >, uint32_t>;
1272
1273   // Reserve some memory inside the render queue
1274   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1275
1276   // Construct message in the render queue memory; note that delete should not be called on the return value
1277   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetVertexBufferData, vertexBuffer, data, size );
1278 }
1279
1280 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1281 {
1282   // Message has ownership of format while in transit from update -> render
1283   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry> >;
1284
1285   // Reserve some memory inside the render queue
1286   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1287
1288   // Construct message in the render queue memory; note that delete should not be called on the return value
1289   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddGeometry, geometry );
1290 }
1291
1292 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1293 {
1294   using DerivedType = MessageValue1<RenderManager, Render::Geometry*>;
1295
1296   // Reserve some memory inside the render queue
1297   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1298
1299   // Construct message in the render queue memory; note that delete should not be called on the return value
1300   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveGeometry, geometry );
1301 }
1302
1303 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1304 {
1305   using DerivedType = MessageValue2<RenderManager, Render::Geometry*, uint32_t>;
1306
1307   // Reserve some memory inside the render queue
1308   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1309
1310   // Construct message in the render queue memory; note that delete should not be called on the return value
1311   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetGeometryType, geometry, geometryType );
1312 }
1313
1314 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1315 {
1316   using DerivedType = IndexBufferMessage<RenderManager>;
1317
1318   // Reserve some memory inside the render queue
1319   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1320
1321   // Construct message in the render queue memory; note that delete should not be called on the return value
1322   new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1323 }
1324
1325 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1326 {
1327   using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1328
1329   // Reserve some memory inside the render queue
1330   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1331
1332   // Construct message in the render queue memory; note that delete should not be called on the return value
1333   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveVertexBuffer, geometry, vertexBuffer );
1334 }
1335
1336 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1337 {
1338   using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1339
1340   // Reserve some memory inside the render queue
1341   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1342
1343   // Construct message in the render queue memory; note that delete should not be called on the return value
1344   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachVertexBuffer, geometry, vertexBuffer );
1345 }
1346
1347 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1348 {
1349   // Message has ownership of Texture while in transit from update -> render
1350   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Texture> >;
1351
1352   // Reserve some memory inside the render queue
1353   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1354
1355   // Construct message in the render queue memory; note that delete should not be called on the return value
1356   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1357 }
1358
1359 void UpdateManager::RemoveTexture( Render::Texture* texture)
1360 {
1361   using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1362
1363   // Reserve some memory inside the render queue
1364   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1365
1366   // Construct message in the render queue memory; note that delete should not be called on the return value
1367   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveTexture, texture );
1368 }
1369
1370 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1371 {
1372   using DerivedType = MessageValue3<RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams>;
1373
1374   // Reserve some memory inside the message queue
1375   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1376
1377   // Construct message in the message queue memory; note that delete should not be called on the return value
1378   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1379 }
1380
1381 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1382 {
1383   using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1384
1385   // Reserve some memory inside the render queue
1386   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1387
1388   // Construct message in the render queue memory; note that delete should not be called on the return value
1389   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::GenerateMipmaps, texture );
1390 }
1391
1392 void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
1393 {
1394   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer> >;
1395
1396   // Reserve some memory inside the render queue
1397   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1398
1399   // Construct message in the render queue memory; note that delete should not be called on the return value
1400   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddFrameBuffer, frameBuffer );
1401 }
1402
1403 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1404 {
1405   using DerivedType = MessageValue1<RenderManager, Render::FrameBuffer*>;
1406
1407   // Reserve some memory inside the render queue
1408   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1409
1410   // Construct message in the render queue memory; note that delete should not be called on the return value
1411   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveFrameBuffer, frameBuffer );
1412 }
1413
1414 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1415 {
1416   using DerivedType = MessageValue4<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t>;
1417
1418   // Reserve some memory inside the render queue
1419   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1420
1421   // Construct message in the render queue memory; note that delete should not be called on the return value
1422   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1423 }
1424
1425 void UpdateManager::AttachDepthTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1426 {
1427   using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1428
1429   // Reserve some memory inside the render queue
1430   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1431
1432   // Construct message in the render queue memory; note that delete should not be called on the return value
1433   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachDepthTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1434 }
1435
1436 void UpdateManager::AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1437 {
1438   using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1439
1440   // Reserve some memory inside the render queue
1441   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1442
1443   // Construct message in the render queue memory; note that delete should not be called on the return value
1444   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1445 }
1446
1447 } // namespace SceneGraph
1448
1449 } // namespace Internal
1450
1451 } // namespace Dali