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