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