Clean up the code to build successfully on macOS
[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     surfaceRectChanged( 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                                 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(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   // 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( nullptr != parent );
398   DALI_ASSERT_ALWAYS( nullptr != node );
399   DALI_ASSERT_ALWAYS( nullptr == 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( nullptr != 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( nullptr != node );
432   DALI_ASSERT_ALWAYS( nullptr == 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       mImpl->frameCallbackProcessor                   ||    // ..a frame callback processor is existed OR
895       gestureUpdated;                                       // ..a gesture property was updated
896
897   bool keepRendererRendering = 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     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     mImpl->transformManager.Update();
961
962     //Process Property Notifications
963     ProcessPropertyNotifications( bufferIndex );
964
965     //Update cameras
966     for( auto&& cameraIterator : mImpl->cameras )
967     {
968       cameraIterator->Update( bufferIndex );
969     }
970
971     //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
972     //reset the update buffer index and make sure there is enough room in the instruction container
973     if( mImpl->renderersAdded )
974     {
975       // Calculate how many render tasks we have in total
976       std::size_t numberOfRenderTasks = 0;
977       for (auto&& scene : mImpl->scenes )
978       {
979         if ( scene && scene->taskList )
980         {
981           numberOfRenderTasks += scene->taskList->GetTasks().Count();
982         }
983       }
984
985
986       std::size_t numberOfRenderInstructions = 0;
987       for ( auto&& scene : mImpl->scenes )
988       {
989         if ( scene && scene->root && scene->taskList && scene->scene )
990         {
991           scene->scene->GetRenderInstructions().ResetAndReserve( bufferIndex,
992                                                      static_cast<uint32_t>( scene->taskList->GetTasks().Count() ) );
993
994           keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
995                                               *scene->taskList,
996                                               *scene->root,
997                                               scene->sortedLayerList,
998                                               scene->scene->GetRenderInstructions(),
999                                               renderToFboEnabled,
1000                                               isRenderingToFbo );
1001
1002           numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count( bufferIndex );
1003         }
1004       }
1005
1006       DALI_LOG_INFO( gLogFilter, Debug::General,
1007                      "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n",
1008                      numberOfRenderTasks, numberOfRenderInstructions );
1009     }
1010   }
1011
1012   for ( auto&& scene : mImpl->scenes )
1013   {
1014     if ( scene && scene->root && scene->taskList )
1015     {
1016       RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
1017
1018       // check the countdown and notify
1019       bool doRenderOnceNotify = false;
1020       mImpl->renderTaskWaiting = false;
1021       for ( auto&& renderTask : tasks )
1022       {
1023         renderTask->UpdateState();
1024
1025         if( renderTask->IsWaitingToRender() &&
1026             renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1027         {
1028           mImpl->renderTaskWaiting = true; // keep update/render threads alive
1029         }
1030
1031         if( renderTask->HasRendered() )
1032         {
1033           doRenderOnceNotify = true;
1034         }
1035       }
1036
1037       if( doRenderOnceNotify )
1038       {
1039         DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1040         mImpl->notificationManager.QueueCompleteNotification( scene->taskList->GetCompleteNotificationInterface() );
1041       }
1042     }
1043   }
1044
1045   // Macro is undefined in release build.
1046   SNAPSHOT_NODE_LOGGING;
1047
1048   // A ResetProperties() may be required in the next frame
1049   mImpl->previousUpdateScene = updateScene;
1050
1051   // Check whether further updates are required
1052   uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1053
1054   if( keepRendererRendering )
1055   {
1056     keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
1057
1058     // Set dirty flags for next frame to continue rendering
1059     mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
1060   }
1061
1062   // tell the update manager that we're done so the queue can be given to event thread
1063   mImpl->notificationManager.UpdateCompleted();
1064
1065   // The update has finished; swap the double-buffering indices
1066   mSceneGraphBuffers.Swap();
1067
1068   return keepUpdating;
1069 }
1070
1071 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1072 {
1073   // Update the duration set via Stage::KeepRendering()
1074   if ( mImpl->keepRenderingSeconds > 0.0f )
1075   {
1076     mImpl->keepRenderingSeconds -= elapsedSeconds;
1077   }
1078
1079   uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1080
1081   // If the rendering behavior is set to continuously render, then continue to render.
1082   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1083   // Keep updating until no messages are received and no animations are running.
1084   // If an animation has just finished, update at least once more for Discard end-actions.
1085   // No need to check for renderQueue as there is always a render after update and if that
1086   // render needs another update it will tell the adaptor to call update again
1087
1088   if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
1089        ( mImpl->keepRenderingSeconds > 0.0f ) )
1090   {
1091     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1092   }
1093
1094   if ( IsAnimationRunning() ||
1095        mImpl->animationFinishedDuringUpdate )
1096   {
1097     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1098   }
1099
1100   if ( mImpl->renderTaskWaiting )
1101   {
1102     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1103   }
1104
1105   return keepUpdatingRequest;
1106 }
1107
1108 void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
1109 {
1110   mImpl->surfaceRectChanged = true;
1111
1112   using DerivedType = MessageValue1<RenderManager, Rect<int32_t> >;
1113
1114   // Reserve some memory inside the render queue
1115   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1116
1117   // Construct message in the render queue memory; note that delete should not be called on the return value
1118   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceRect, rect );
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::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1143 {
1144   for ( auto&& scene : mImpl->scenes )
1145   {
1146     if ( scene && scene->root == rootLayer )
1147     {
1148       scene->sortedLayerList = layers;
1149       break;
1150     }
1151   }
1152 }
1153
1154 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1155 {
1156   // note,this vector is already in depth order. It could be used as-is to
1157   // remove sorting in update algorithm. However, it lacks layer boundary markers.
1158   for( auto&& iter : nodeDepths->nodeDepths )
1159   {
1160     iter.node->SetDepthIndex( iter.sortedDepth );
1161   }
1162
1163   for ( auto&& scene : mImpl->scenes )
1164   {
1165     if ( scene )
1166     {
1167       // Go through node hierarchy and rearrange siblings according to depth-index
1168       SortSiblingNodesRecursively( *scene->root );
1169     }
1170   }
1171 }
1172
1173 bool UpdateManager::IsDefaultSurfaceRectChanged()
1174 {
1175   bool surfaceRectChanged = mImpl->surfaceRectChanged;
1176
1177   // Reset the flag
1178   mImpl->surfaceRectChanged = false;
1179
1180   return surfaceRectChanged;
1181 }
1182
1183 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1184 {
1185   mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1186 }
1187
1188 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1189 {
1190   mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1191 }
1192
1193 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1194 {
1195   // Message has ownership of Sampler while in transit from update to render
1196   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Sampler> >;
1197
1198   // Reserve some memory inside the render queue
1199   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1200
1201   // Construct message in the render queue memory; note that delete should not be called on the return value
1202   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddSampler, sampler );
1203 }
1204
1205 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1206 {
1207   using DerivedType = MessageValue1<RenderManager, Render::Sampler*>;
1208
1209   // Reserve some memory inside the render queue
1210   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1211
1212   // Construct message in the render queue memory; note that delete should not be called on the return value
1213   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveSampler, sampler );
1214 }
1215
1216 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1217 {
1218   using DerivedType = MessageValue3<RenderManager, Render::Sampler*, uint32_t, uint32_t>;
1219
1220   // Reserve some memory inside the render queue
1221   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1222
1223   // Construct message in the render queue memory; note that delete should not be called on the return value
1224   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1225 }
1226
1227 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1228 {
1229   using DerivedType = MessageValue4<RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t>;
1230
1231   // Reserve some memory inside the render queue
1232   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1233
1234   // Construct message in the render queue memory; note that delete should not be called on the return value
1235   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1236 }
1237
1238 void UpdateManager::AddVertexBuffer( OwnerPointer< Render::VertexBuffer >& vertexBuffer )
1239 {
1240   // Message has ownership of format while in transit from update -> render
1241   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer> >;
1242
1243   // Reserve some memory inside the render queue
1244   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1245
1246   // Construct message in the render queue memory; note that delete should not be called on the return value
1247   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddVertexBuffer, vertexBuffer );
1248 }
1249
1250 void UpdateManager::RemoveVertexBuffer( Render::VertexBuffer* vertexBuffer )
1251 {
1252   using DerivedType = MessageValue1<RenderManager, Render::VertexBuffer*>;
1253
1254   // Reserve some memory inside the render queue
1255   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1256
1257   // Construct message in the render queue memory; note that delete should not be called on the return value
1258   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveVertexBuffer, vertexBuffer );
1259 }
1260
1261 void UpdateManager::SetVertexBufferFormat( Render::VertexBuffer* vertexBuffer, OwnerPointer< Render::VertexBuffer::Format>& format )
1262 {
1263   // Message has ownership of format while in transit from update -> render
1264   using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, OwnerPointer<Render::VertexBuffer::Format> >;
1265
1266   // Reserve some memory inside the render queue
1267   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1268
1269   // Construct message in the render queue memory; note that delete should not be called on the return value
1270   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetVertexBufferFormat, vertexBuffer, format );
1271 }
1272
1273 void UpdateManager::SetVertexBufferData( Render::VertexBuffer* vertexBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1274 {
1275   // Message has ownership of format while in transit from update -> render
1276   using DerivedType = MessageValue3<RenderManager, Render::VertexBuffer*, OwnerPointer<Dali::Vector<uint8_t> >, uint32_t>;
1277
1278   // Reserve some memory inside the render queue
1279   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1280
1281   // Construct message in the render queue memory; note that delete should not be called on the return value
1282   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetVertexBufferData, vertexBuffer, data, size );
1283 }
1284
1285 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1286 {
1287   // Message has ownership of format while in transit from update -> render
1288   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry> >;
1289
1290   // Reserve some memory inside the render queue
1291   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1292
1293   // Construct message in the render queue memory; note that delete should not be called on the return value
1294   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddGeometry, geometry );
1295 }
1296
1297 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1298 {
1299   using DerivedType = MessageValue1<RenderManager, Render::Geometry*>;
1300
1301   // Reserve some memory inside the render queue
1302   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1303
1304   // Construct message in the render queue memory; note that delete should not be called on the return value
1305   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveGeometry, geometry );
1306 }
1307
1308 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1309 {
1310   using DerivedType = MessageValue2<RenderManager, Render::Geometry*, uint32_t>;
1311
1312   // Reserve some memory inside the render queue
1313   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1314
1315   // Construct message in the render queue memory; note that delete should not be called on the return value
1316   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetGeometryType, geometry, geometryType );
1317 }
1318
1319 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1320 {
1321   using DerivedType = IndexBufferMessage<RenderManager>;
1322
1323   // Reserve some memory inside the render queue
1324   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1325
1326   // Construct message in the render queue memory; note that delete should not be called on the return value
1327   new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1328 }
1329
1330 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1331 {
1332   using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1333
1334   // Reserve some memory inside the render queue
1335   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1336
1337   // Construct message in the render queue memory; note that delete should not be called on the return value
1338   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveVertexBuffer, geometry, vertexBuffer );
1339 }
1340
1341 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1342 {
1343   using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1344
1345   // Reserve some memory inside the render queue
1346   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1347
1348   // Construct message in the render queue memory; note that delete should not be called on the return value
1349   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachVertexBuffer, geometry, vertexBuffer );
1350 }
1351
1352 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1353 {
1354   // Message has ownership of Texture while in transit from update -> render
1355   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Texture> >;
1356
1357   // Reserve some memory inside the render queue
1358   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1359
1360   // Construct message in the render queue memory; note that delete should not be called on the return value
1361   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1362 }
1363
1364 void UpdateManager::RemoveTexture( Render::Texture* texture)
1365 {
1366   using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1367
1368   // Reserve some memory inside the render queue
1369   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1370
1371   // Construct message in the render queue memory; note that delete should not be called on the return value
1372   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveTexture, texture );
1373 }
1374
1375 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1376 {
1377   using DerivedType = MessageValue3<RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams>;
1378
1379   // Reserve some memory inside the message queue
1380   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1381
1382   // Construct message in the message queue memory; note that delete should not be called on the return value
1383   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1384 }
1385
1386 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1387 {
1388   using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1389
1390   // Reserve some memory inside the render queue
1391   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1392
1393   // Construct message in the render queue memory; note that delete should not be called on the return value
1394   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::GenerateMipmaps, texture );
1395 }
1396
1397 void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
1398 {
1399   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer> >;
1400
1401   // Reserve some memory inside the render queue
1402   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1403
1404   // Construct message in the render queue memory; note that delete should not be called on the return value
1405   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddFrameBuffer, frameBuffer );
1406 }
1407
1408 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1409 {
1410   using DerivedType = MessageValue1<RenderManager, Render::FrameBuffer*>;
1411
1412   // Reserve some memory inside the render queue
1413   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1414
1415   // Construct message in the render queue memory; note that delete should not be called on the return value
1416   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveFrameBuffer, frameBuffer );
1417 }
1418
1419 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1420 {
1421   using DerivedType = MessageValue4<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t>;
1422
1423   // Reserve some memory inside the render queue
1424   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1425
1426   // Construct message in the render queue memory; note that delete should not be called on the return value
1427   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1428 }
1429
1430 void UpdateManager::AttachDepthTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1431 {
1432   using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1433
1434   // Reserve some memory inside the render queue
1435   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1436
1437   // Construct message in the render queue memory; note that delete should not be called on the return value
1438   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachDepthTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1439 }
1440
1441 void UpdateManager::AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1442 {
1443   using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1444
1445   // Reserve some memory inside the render queue
1446   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1447
1448   // Construct message in the render queue memory; note that delete should not be called on the return value
1449   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1450 }
1451
1452 } // namespace SceneGraph
1453
1454 } // namespace Internal
1455
1456 } // namespace Dali