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