[Tizen] Add screen and client rotation itself function
[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           }
1020
1021           numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count( bufferIndex );
1022         }
1023       }
1024
1025       DALI_LOG_INFO( gLogFilter, Debug::General,
1026                      "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n",
1027                      numberOfRenderTasks, numberOfRenderInstructions );
1028     }
1029   }
1030
1031   for ( auto&& scene : mImpl->scenes )
1032   {
1033     if ( scene && scene->root && scene->taskList )
1034     {
1035       RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
1036
1037       // check the countdown and notify
1038       bool doRenderOnceNotify = false;
1039       mImpl->renderTaskWaiting = false;
1040       for ( auto&& renderTask : tasks )
1041       {
1042         renderTask->UpdateState();
1043
1044         if( renderTask->IsWaitingToRender() &&
1045             renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1046         {
1047           mImpl->renderTaskWaiting = true; // keep update/render threads alive
1048         }
1049
1050         if( renderTask->HasRendered() )
1051         {
1052           doRenderOnceNotify = true;
1053         }
1054       }
1055
1056       if( doRenderOnceNotify )
1057       {
1058         DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1059         mImpl->notificationManager.QueueCompleteNotification( scene->taskList->GetCompleteNotificationInterface() );
1060       }
1061     }
1062   }
1063
1064   // Macro is undefined in release build.
1065   SNAPSHOT_NODE_LOGGING;
1066
1067   // A ResetProperties() may be required in the next frame
1068   mImpl->previousUpdateScene = updateScene;
1069
1070   // Check whether further updates are required
1071   uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1072
1073   if( keepRendererRendering )
1074   {
1075     keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
1076
1077     // Set dirty flags for next frame to continue rendering
1078     mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
1079   }
1080
1081   // tell the update manager that we're done so the queue can be given to event thread
1082   mImpl->notificationManager.UpdateCompleted();
1083
1084   // The update has finished; swap the double-buffering indices
1085   mSceneGraphBuffers.Swap();
1086
1087   return keepUpdating;
1088 }
1089
1090 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1091 {
1092   // Update the duration set via Stage::KeepRendering()
1093   if ( mImpl->keepRenderingSeconds > 0.0f )
1094   {
1095     mImpl->keepRenderingSeconds -= elapsedSeconds;
1096   }
1097
1098   uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1099
1100   // If the rendering behavior is set to continuously render, then continue to render.
1101   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1102   // Keep updating until no messages are received and no animations are running.
1103   // If an animation has just finished, update at least once more for Discard end-actions.
1104   // No need to check for renderQueue as there is always a render after update and if that
1105   // render needs another update it will tell the adaptor to call update again
1106
1107   if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
1108        ( mImpl->keepRenderingSeconds > 0.0f ) )
1109   {
1110     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1111   }
1112
1113   if ( IsAnimationRunning() ||
1114        mImpl->animationFinishedDuringUpdate )
1115   {
1116     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1117   }
1118
1119   if ( mImpl->renderTaskWaiting )
1120   {
1121     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1122   }
1123
1124   return keepUpdatingRequest;
1125 }
1126
1127 void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
1128 {
1129   mImpl->surfaceRectChanged = true;
1130
1131   using DerivedType = MessageValue1<RenderManager, Rect<int32_t> >;
1132
1133   // Reserve some memory inside the render queue
1134   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1135
1136   // Construct message in the render queue memory; note that delete should not be called on the return value
1137   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceRect, rect );
1138 }
1139
1140 void UpdateManager::SurfaceReplaced( Scene* scene )
1141 {
1142   using DerivedType = MessageValue1<RenderManager, Scene*>;
1143
1144   // Reserve some memory inside the render queue
1145   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1146
1147   // Construct message in the render queue memory; note that delete should not be called on the return value
1148   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SurfaceReplaced, scene );
1149 }
1150
1151 void UpdateManager::SetDefaultSurfaceOrientation( int orientation )
1152 {
1153   typedef MessageValue1< RenderManager, int > DerivedType;
1154
1155   // Reserve some memory inside the render queue
1156   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1157
1158   // Construct message in the render queue memory; note that delete should not be called on the return value
1159   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceOrientation, orientation );
1160 }
1161
1162 void UpdateManager::KeepRendering( float durationSeconds )
1163 {
1164   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1165 }
1166
1167 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1168 {
1169   mImpl->renderingBehavior = renderingBehavior;
1170 }
1171
1172 void UpdateManager::RequestRendering()
1173 {
1174   mImpl->renderingRequired = true;
1175 }
1176
1177 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1178 {
1179   for ( auto&& scene : mImpl->scenes )
1180   {
1181     if ( scene && scene->root == rootLayer )
1182     {
1183       scene->sortedLayerList = layers;
1184       break;
1185     }
1186   }
1187 }
1188
1189 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1190 {
1191   // note,this vector is already in depth order. It could be used as-is to
1192   // remove sorting in update algorithm. However, it lacks layer boundary markers.
1193   for( auto&& iter : nodeDepths->nodeDepths )
1194   {
1195     iter.node->SetDepthIndex( iter.sortedDepth );
1196   }
1197
1198   for ( auto&& scene : mImpl->scenes )
1199   {
1200     if ( scene )
1201     {
1202       // Go through node hierarchy and rearrange siblings according to depth-index
1203       SortSiblingNodesRecursively( *scene->root );
1204     }
1205   }
1206 }
1207
1208 bool UpdateManager::IsDefaultSurfaceRectChanged()
1209 {
1210   bool surfaceRectChanged = mImpl->surfaceRectChanged;
1211
1212   // Reset the flag
1213   mImpl->surfaceRectChanged = false;
1214
1215   return surfaceRectChanged;
1216 }
1217
1218 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1219 {
1220   mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1221 }
1222
1223 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1224 {
1225   mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1226 }
1227
1228 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1229 {
1230   // Message has ownership of Sampler while in transit from update to render
1231   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Sampler> >;
1232
1233   // Reserve some memory inside the render queue
1234   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1235
1236   // Construct message in the render queue memory; note that delete should not be called on the return value
1237   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddSampler, sampler );
1238 }
1239
1240 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1241 {
1242   using DerivedType = MessageValue1<RenderManager, Render::Sampler*>;
1243
1244   // Reserve some memory inside the render queue
1245   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1246
1247   // Construct message in the render queue memory; note that delete should not be called on the return value
1248   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveSampler, sampler );
1249 }
1250
1251 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1252 {
1253   using DerivedType = MessageValue3<RenderManager, Render::Sampler*, uint32_t, uint32_t>;
1254
1255   // Reserve some memory inside the render queue
1256   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1257
1258   // Construct message in the render queue memory; note that delete should not be called on the return value
1259   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1260 }
1261
1262 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1263 {
1264   using DerivedType = MessageValue4<RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t>;
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::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1271 }
1272
1273 void UpdateManager::AddVertexBuffer( OwnerPointer< Render::VertexBuffer >& vertexBuffer )
1274 {
1275   // Message has ownership of format while in transit from update -> render
1276   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer> >;
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::AddVertexBuffer, vertexBuffer );
1283 }
1284
1285 void UpdateManager::RemoveVertexBuffer( Render::VertexBuffer* vertexBuffer )
1286 {
1287   using DerivedType = MessageValue1<RenderManager, Render::VertexBuffer*>;
1288
1289   // Reserve some memory inside the render queue
1290   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1291
1292   // Construct message in the render queue memory; note that delete should not be called on the return value
1293   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveVertexBuffer, vertexBuffer );
1294 }
1295
1296 void UpdateManager::SetVertexBufferFormat( Render::VertexBuffer* vertexBuffer, OwnerPointer< Render::VertexBuffer::Format>& format )
1297 {
1298   // Message has ownership of format while in transit from update -> render
1299   using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, OwnerPointer<Render::VertexBuffer::Format> >;
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::SetVertexBufferFormat, vertexBuffer, format );
1306 }
1307
1308 void UpdateManager::SetVertexBufferData( Render::VertexBuffer* vertexBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1309 {
1310   // Message has ownership of format while in transit from update -> render
1311   using DerivedType = MessageValue3<RenderManager, Render::VertexBuffer*, OwnerPointer<Dali::Vector<uint8_t> >, uint32_t>;
1312
1313   // Reserve some memory inside the render queue
1314   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1315
1316   // Construct message in the render queue memory; note that delete should not be called on the return value
1317   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetVertexBufferData, vertexBuffer, data, size );
1318 }
1319
1320 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1321 {
1322   // Message has ownership of format while in transit from update -> render
1323   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry> >;
1324
1325   // Reserve some memory inside the render queue
1326   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1327
1328   // Construct message in the render queue memory; note that delete should not be called on the return value
1329   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddGeometry, geometry );
1330 }
1331
1332 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1333 {
1334   using DerivedType = MessageValue1<RenderManager, Render::Geometry*>;
1335
1336   // Reserve some memory inside the render queue
1337   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1338
1339   // Construct message in the render queue memory; note that delete should not be called on the return value
1340   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveGeometry, geometry );
1341 }
1342
1343 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1344 {
1345   using DerivedType = MessageValue2<RenderManager, Render::Geometry*, uint32_t>;
1346
1347   // Reserve some memory inside the render queue
1348   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1349
1350   // Construct message in the render queue memory; note that delete should not be called on the return value
1351   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetGeometryType, geometry, geometryType );
1352 }
1353
1354 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1355 {
1356   using DerivedType = IndexBufferMessage<RenderManager>;
1357
1358   // Reserve some memory inside the render queue
1359   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1360
1361   // Construct message in the render queue memory; note that delete should not be called on the return value
1362   new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1363 }
1364
1365 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1366 {
1367   using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1368
1369   // Reserve some memory inside the render queue
1370   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1371
1372   // Construct message in the render queue memory; note that delete should not be called on the return value
1373   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveVertexBuffer, geometry, vertexBuffer );
1374 }
1375
1376 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1377 {
1378   using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1379
1380   // Reserve some memory inside the render queue
1381   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1382
1383   // Construct message in the render queue memory; note that delete should not be called on the return value
1384   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachVertexBuffer, geometry, vertexBuffer );
1385 }
1386
1387 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1388 {
1389   // Message has ownership of Texture while in transit from update -> render
1390   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Texture> >;
1391
1392   // Reserve some memory inside the render queue
1393   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1394
1395   // Construct message in the render queue memory; note that delete should not be called on the return value
1396   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1397 }
1398
1399 void UpdateManager::RemoveTexture( Render::Texture* texture)
1400 {
1401   using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1402
1403   // Reserve some memory inside the render queue
1404   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1405
1406   // Construct message in the render queue memory; note that delete should not be called on the return value
1407   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveTexture, texture );
1408 }
1409
1410 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1411 {
1412   using DerivedType = MessageValue3<RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams>;
1413
1414   // Reserve some memory inside the message queue
1415   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1416
1417   // Construct message in the message queue memory; note that delete should not be called on the return value
1418   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1419 }
1420
1421 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1422 {
1423   using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1424
1425   // Reserve some memory inside the render queue
1426   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1427
1428   // Construct message in the render queue memory; note that delete should not be called on the return value
1429   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::GenerateMipmaps, texture );
1430 }
1431
1432 void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
1433 {
1434   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer> >;
1435
1436   // Reserve some memory inside the render queue
1437   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1438
1439   // Construct message in the render queue memory; note that delete should not be called on the return value
1440   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddFrameBuffer, frameBuffer );
1441 }
1442
1443 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1444 {
1445   using DerivedType = MessageValue1<RenderManager, Render::FrameBuffer*>;
1446
1447   // Reserve some memory inside the render queue
1448   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1449
1450   // Construct message in the render queue memory; note that delete should not be called on the return value
1451   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveFrameBuffer, frameBuffer );
1452 }
1453
1454 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1455 {
1456   using DerivedType = MessageValue4<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t>;
1457
1458   // Reserve some memory inside the render queue
1459   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1460
1461   // Construct message in the render queue memory; note that delete should not be called on the return value
1462   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1463 }
1464
1465 void UpdateManager::AttachDepthTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1466 {
1467   using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1468
1469   // Reserve some memory inside the render queue
1470   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1471
1472   // Construct message in the render queue memory; note that delete should not be called on the return value
1473   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachDepthTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1474 }
1475
1476 void UpdateManager::AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1477 {
1478   using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1479
1480   // Reserve some memory inside the render queue
1481   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1482
1483   // Construct message in the render queue memory; note that delete should not be called on the return value
1484   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1485 }
1486
1487 } // namespace SceneGraph
1488
1489 } // namespace Internal
1490
1491 } // namespace Dali