[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( 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       gestureUpdated;                                       // ..a gesture property was updated
896
897   bool keepRendererRendering = false;
898
899   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
900   // values if the scene was updated in the previous frame.
901   if( updateScene || mImpl->previousUpdateScene )
902   {
903     //Reset properties from the previous update
904     ResetProperties( bufferIndex );
905     mImpl->transformManager.ResetToBaseValue();
906   }
907
908   // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
909   // between calling IsSceneUpdateRequired() above and here, so updateScene should
910   // be set again
911   updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
912
913   //Forward compiled shader programs to event thread for saving
914   ForwardCompiledShadersToEventThread();
915
916   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
917   // renderer lists if the scene was updated in the previous frame.
918   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
919   if( updateScene || mImpl->previousUpdateScene )
920   {
921     //Animate
922     Animate( bufferIndex, elapsedSeconds );
923
924     //Constraint custom objects
925     ConstrainCustomObjects( bufferIndex );
926
927     //Clear the lists of renderers from the previous update
928     for( auto&& scene : mImpl->scenes )
929     {
930       if ( scene )
931       {
932         for( auto&& layer : scene->sortedLayerList )
933         {
934           if ( layer )
935           {
936             layer->ClearRenderables();
937           }
938         }
939       }
940     }
941
942     // Call the frame-callback-processor if set
943     if( mImpl->frameCallbackProcessor )
944     {
945       mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
946     }
947
948     //Update node hierarchy, apply constraints and perform sorting / culling.
949     //This will populate each Layer with a list of renderers which are ready.
950     UpdateNodes( bufferIndex );
951
952     //Apply constraints to RenderTasks, shaders
953     ConstrainRenderTasks( bufferIndex );
954     ConstrainShaders( bufferIndex );
955
956     //Update renderers and apply constraints
957     UpdateRenderers( bufferIndex );
958
959     //Update the transformations of all the nodes
960     mImpl->transformManager.Update();
961
962     //Process Property Notifications
963     ProcessPropertyNotifications( bufferIndex );
964
965     //Update cameras
966     for( auto&& cameraIterator : mImpl->cameras )
967     {
968       cameraIterator->Update( bufferIndex );
969     }
970
971     //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
972     //reset the update buffer index and make sure there is enough room in the instruction container
973     if( mImpl->renderersAdded )
974     {
975       // Calculate how many render tasks we have in total
976       std::size_t numberOfRenderTasks = 0;
977       for (auto&& scene : mImpl->scenes )
978       {
979         if ( scene && scene->taskList )
980         {
981           numberOfRenderTasks += scene->taskList->GetTasks().Count();
982         }
983       }
984
985
986       std::size_t numberOfRenderInstructions = 0;
987       for ( auto&& scene : mImpl->scenes )
988       {
989         if ( scene && scene->root && scene->taskList && scene->scene )
990         {
991           scene->scene->GetRenderInstructions().ResetAndReserve( bufferIndex,
992                                                      static_cast<uint32_t>( scene->taskList->GetTasks().Count() ) );
993
994           keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
995                                               *scene->taskList,
996                                               *scene->root,
997                                               scene->sortedLayerList,
998                                               *scene->scene->GetContext(),
999                                               scene->scene->GetRenderInstructions(),
1000                                               renderToFboEnabled,
1001                                               isRenderingToFbo );
1002
1003           numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count( bufferIndex );
1004         }
1005       }
1006
1007       DALI_LOG_INFO( gLogFilter, Debug::General,
1008                      "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n",
1009                      numberOfRenderTasks, numberOfRenderInstructions );
1010     }
1011   }
1012
1013   for ( auto&& scene : mImpl->scenes )
1014   {
1015     if ( scene && scene->root && scene->taskList )
1016     {
1017       RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
1018
1019       // check the countdown and notify
1020       bool doRenderOnceNotify = false;
1021       mImpl->renderTaskWaiting = false;
1022       for ( auto&& renderTask : tasks )
1023       {
1024         renderTask->UpdateState();
1025
1026         if( renderTask->IsWaitingToRender() &&
1027             renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1028         {
1029           mImpl->renderTaskWaiting = true; // keep update/render threads alive
1030         }
1031
1032         if( renderTask->HasRendered() )
1033         {
1034           doRenderOnceNotify = true;
1035         }
1036       }
1037
1038       if( doRenderOnceNotify )
1039       {
1040         DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1041         mImpl->notificationManager.QueueCompleteNotification( scene->taskList->GetCompleteNotificationInterface() );
1042       }
1043     }
1044   }
1045
1046   // Macro is undefined in release build.
1047   SNAPSHOT_NODE_LOGGING;
1048
1049   // A ResetProperties() may be required in the next frame
1050   mImpl->previousUpdateScene = updateScene;
1051
1052   // Check whether further updates are required
1053   uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1054
1055   if( keepRendererRendering )
1056   {
1057     keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
1058
1059     // Set dirty flags for next frame to continue rendering
1060     mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
1061   }
1062
1063   // tell the update manager that we're done so the queue can be given to event thread
1064   mImpl->notificationManager.UpdateCompleted();
1065
1066   // The update has finished; swap the double-buffering indices
1067   mSceneGraphBuffers.Swap();
1068
1069   return keepUpdating;
1070 }
1071
1072 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1073 {
1074   // Update the duration set via Stage::KeepRendering()
1075   if ( mImpl->keepRenderingSeconds > 0.0f )
1076   {
1077     mImpl->keepRenderingSeconds -= elapsedSeconds;
1078   }
1079
1080   uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1081
1082   // If the rendering behavior is set to continuously render, then continue to render.
1083   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1084   // Keep updating until no messages are received and no animations are running.
1085   // If an animation has just finished, update at least once more for Discard end-actions.
1086   // No need to check for renderQueue as there is always a render after update and if that
1087   // render needs another update it will tell the adaptor to call update again
1088
1089   if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
1090        ( mImpl->keepRenderingSeconds > 0.0f ) )
1091   {
1092     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1093   }
1094
1095   if ( IsAnimationRunning() ||
1096        mImpl->animationFinishedDuringUpdate )
1097   {
1098     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1099   }
1100
1101   if ( mImpl->renderTaskWaiting )
1102   {
1103     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1104   }
1105
1106   return keepUpdatingRequest;
1107 }
1108
1109 void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
1110 {
1111   mImpl->surfaceRectChanged = true;
1112
1113   typedef MessageValue1< RenderManager, Rect<int32_t> > DerivedType;
1114
1115   // Reserve some memory inside the render queue
1116   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1117
1118   // Construct message in the render queue memory; note that delete should not be called on the return value
1119   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceRect, rect );
1120 }
1121
1122 void UpdateManager::SurfaceReplaced( Scene* scene )
1123 {
1124   typedef MessageValue1< RenderManager, Scene* > DerivedType;
1125
1126   // Reserve some memory inside the render queue
1127   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1128
1129   // Construct message in the render queue memory; note that delete should not be called on the return value
1130   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SurfaceReplaced, scene );
1131 }
1132
1133 void UpdateManager::SetDefaultSurfaceOrientation( int orientation )
1134 {
1135   typedef MessageValue1< RenderManager, int > DerivedType;
1136
1137   // Reserve some memory inside the render queue
1138   unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1139
1140   // Construct message in the render queue memory; note that delete should not be called on the return value
1141   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetDefaultSurfaceOrientation, orientation );
1142 }
1143
1144 void UpdateManager::KeepRendering( float durationSeconds )
1145 {
1146   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1147 }
1148
1149 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1150 {
1151   mImpl->renderingBehavior = renderingBehavior;
1152 }
1153
1154 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1155 {
1156   for ( auto&& scene : mImpl->scenes )
1157   {
1158     if ( scene && scene->root == rootLayer )
1159     {
1160       scene->sortedLayerList = layers;
1161       break;
1162     }
1163   }
1164 }
1165
1166 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1167 {
1168   // note,this vector is already in depth order. It could be used as-is to
1169   // remove sorting in update algorithm. However, it lacks layer boundary markers.
1170   for( auto&& iter : nodeDepths->nodeDepths )
1171   {
1172     iter.node->SetDepthIndex( iter.sortedDepth );
1173   }
1174
1175   for ( auto&& scene : mImpl->scenes )
1176   {
1177     if ( scene )
1178     {
1179       // Go through node hierarchy and rearrange siblings according to depth-index
1180       SortSiblingNodesRecursively( *scene->root );
1181     }
1182   }
1183 }
1184
1185 bool UpdateManager::IsDefaultSurfaceRectChanged()
1186 {
1187   bool surfaceRectChanged = mImpl->surfaceRectChanged;
1188
1189   // Reset the flag
1190   mImpl->surfaceRectChanged = false;
1191
1192   return surfaceRectChanged;
1193 }
1194
1195 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1196 {
1197   mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1198 }
1199
1200 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1201 {
1202   mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1203 }
1204
1205 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1206 {
1207   // Message has ownership of Sampler while in transit from update to render
1208   typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
1209
1210   // Reserve some memory inside the render queue
1211   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1212
1213   // Construct message in the render queue memory; note that delete should not be called on the return value
1214   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddSampler, sampler );
1215 }
1216
1217 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1218 {
1219   typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1220
1221   // Reserve some memory inside the render queue
1222   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1223
1224   // Construct message in the render queue memory; note that delete should not be called on the return value
1225   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveSampler, sampler );
1226 }
1227
1228 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1229 {
1230   typedef MessageValue3< RenderManager, Render::Sampler*, uint32_t, uint32_t > DerivedType;
1231
1232   // Reserve some memory inside the render queue
1233   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1234
1235   // Construct message in the render queue memory; note that delete should not be called on the return value
1236   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1237 }
1238
1239 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1240 {
1241   typedef MessageValue4< RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t > DerivedType;
1242
1243   // Reserve some memory inside the render queue
1244   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1245
1246   // Construct message in the render queue memory; note that delete should not be called on the return value
1247   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1248 }
1249
1250 void UpdateManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer )
1251 {
1252   // Message has ownership of format while in transit from update -> render
1253   typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
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::AddPropertyBuffer, propertyBuffer );
1260 }
1261
1262 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1263 {
1264   typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
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::RemovePropertyBuffer, propertyBuffer );
1271 }
1272
1273 void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format )
1274 {
1275   // Message has ownership of format while in transit from update -> render
1276   typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
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::SetPropertyBufferFormat, propertyBuffer, format );
1283 }
1284
1285 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1286 {
1287   // Message has ownership of format while in transit from update -> render
1288   typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<uint8_t> >, uint32_t > DerivedType;
1289
1290   // Reserve some memory inside the render queue
1291   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1292
1293   // Construct message in the render queue memory; note that delete should not be called on the return value
1294   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1295 }
1296
1297 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1298 {
1299   // Message has ownership of format while in transit from update -> render
1300   typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
1301
1302   // Reserve some memory inside the render queue
1303   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1304
1305   // Construct message in the render queue memory; note that delete should not be called on the return value
1306   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddGeometry, geometry );
1307 }
1308
1309 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1310 {
1311   typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
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::RemoveGeometry, geometry );
1318 }
1319
1320 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1321 {
1322   typedef MessageValue2< RenderManager, Render::Geometry*, uint32_t > DerivedType;
1323
1324   // Reserve some memory inside the render queue
1325   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1326
1327   // Construct message in the render queue memory; note that delete should not be called on the return value
1328   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::SetGeometryType, geometry, geometryType );
1329 }
1330
1331 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1332 {
1333   typedef IndexBufferMessage< RenderManager > DerivedType;
1334
1335   // Reserve some memory inside the render queue
1336   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1337
1338   // Construct message in the render queue memory; note that delete should not be called on the return value
1339   new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1340 }
1341
1342 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1343 {
1344   typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1345
1346   // Reserve some memory inside the render queue
1347   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1348
1349   // Construct message in the render queue memory; note that delete should not be called on the return value
1350   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1351 }
1352
1353 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1354 {
1355   typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1356
1357   // Reserve some memory inside the render queue
1358   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1359
1360   // Construct message in the render queue memory; note that delete should not be called on the return value
1361   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachVertexBuffer, geometry, propertyBuffer );
1362 }
1363
1364 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1365 {
1366   // Message has ownership of Texture while in transit from update -> render
1367   typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
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::AddTexture, texture );
1374 }
1375
1376 void UpdateManager::RemoveTexture( Render::Texture* texture)
1377 {
1378   typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
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::RemoveTexture, texture );
1385 }
1386
1387 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1388 {
1389   typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1390
1391   // Reserve some memory inside the message queue
1392   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1393
1394   // Construct message in the message queue memory; note that delete should not be called on the return value
1395   new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1396 }
1397
1398 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1399 {
1400   typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1401
1402   // Reserve some memory inside the render queue
1403   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1404
1405   // Construct message in the render queue memory; note that delete should not be called on the return value
1406   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::GenerateMipmaps, texture );
1407 }
1408
1409 void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
1410 {
1411   typedef MessageValue1< RenderManager, OwnerPointer< Render::FrameBuffer > > DerivedType;
1412
1413   // Reserve some memory inside the render queue
1414   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1415
1416   // Construct message in the render queue memory; note that delete should not be called on the return value
1417   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AddFrameBuffer, frameBuffer );
1418 }
1419
1420 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1421 {
1422   typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1423
1424   // Reserve some memory inside the render queue
1425   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1426
1427   // Construct message in the render queue memory; note that delete should not be called on the return value
1428   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::RemoveFrameBuffer, frameBuffer );
1429 }
1430
1431 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1432 {
1433   typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t > DerivedType;
1434
1435   // Reserve some memory inside the render queue
1436   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1437
1438   // Construct message in the render queue memory; note that delete should not be called on the return value
1439   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1440 }
1441
1442 void UpdateManager::AttachDepthTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1443 {
1444   typedef MessageValue3< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t > DerivedType;
1445
1446   // Reserve some memory inside the render queue
1447   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1448
1449   // Construct message in the render queue memory; note that delete should not be called on the return value
1450   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachDepthTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1451 }
1452
1453 void UpdateManager::AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1454 {
1455   typedef MessageValue3< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t > DerivedType;
1456
1457   // Reserve some memory inside the render queue
1458   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1459
1460   // Construct message in the render queue memory; note that delete should not be called on the return value
1461   new (slot) DerivedType( &mImpl->renderManager,  &RenderManager::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1462 }
1463
1464 } // namespace SceneGraph
1465
1466 } // namespace Internal
1467
1468 } // namespace Dali