[dali_2.3.24] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-manager.cpp
1 /*
2  * Copyright (c) 2024 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 // EXTERNAL INCLUDES
22 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
23 #include <dali/devel-api/common/map-wrapper.h>
24 #else
25 #include <unordered_map>
26 #endif
27
28 // INTERNAL INCLUDES
29 #include <dali/integration-api/core.h>
30
31 #include <dali/internal/common/owner-key-container.h>
32
33 #include <dali/internal/event/animation/animation-playlist.h>
34 #include <dali/internal/event/common/notification-manager.h>
35 #include <dali/internal/event/common/property-notifier.h>
36 #include <dali/internal/event/effects/shader-factory.h>
37
38 #include <dali/internal/update/common/discard-queue.h>
39 #include <dali/internal/update/controllers/render-message-dispatcher.h>
40 #include <dali/internal/update/controllers/scene-controller-impl.h>
41 #include <dali/internal/update/manager/frame-callback-processor.h>
42 #include <dali/internal/update/manager/render-task-processor.h>
43 #include <dali/internal/update/manager/resetter-container.h>
44 #include <dali/internal/update/manager/transform-manager.h>
45 #include <dali/internal/update/manager/update-algorithms.h>
46 #include <dali/internal/update/manager/update-manager-debug.h>
47 #include <dali/internal/update/nodes/node.h>
48 #include <dali/internal/update/queue/update-message-queue.h>
49
50 #include <dali/internal/render/common/render-manager.h>
51 #include <dali/internal/render/queue/render-queue.h>
52 #include <dali/internal/render/renderers/render-vertex-buffer.h>
53
54 // Un-comment to enable node tree debug logging
55 //#define NODE_TREE_LOGGING 1
56
57 #if(defined(DEBUG_ENABLED) && defined(NODE_TREE_LOGGING))
58 #define SNAPSHOT_NODE_LOGGING                                                   \
59   const uint32_t FRAME_COUNT_TRIGGER = 16;                                      \
60   if(mImpl->frameCounter >= FRAME_COUNT_TRIGGER)                                \
61   {                                                                             \
62     for(auto&& scene : mImpl->scenes)                                           \
63     {                                                                           \
64       if(scene && scene->root)                                                  \
65       {                                                                         \
66         mImpl->frameCounter = 0;                                                \
67         PrintNodes(*scene->root, mSceneGraphBuffers.GetUpdateBufferIndex(), 0); \
68       }                                                                         \
69     }                                                                           \
70   }                                                                             \
71   mImpl->frameCounter++;
72 #else
73 #define SNAPSHOT_NODE_LOGGING
74 #endif
75
76 #if defined(DEBUG_ENABLED)
77 extern Debug::Filter* gRenderTaskLogFilter;
78 namespace
79 {
80 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_UPDATE_MANAGER");
81 } // unnamed namespace
82 #endif
83
84 using namespace Dali::Integration;
85 using Dali::Internal::Update::MessageQueue;
86
87 namespace Dali
88 {
89 namespace Internal
90 {
91 namespace SceneGraph
92 {
93 namespace
94 {
95 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
96 /**
97  * Flag whether property has changed, during the Update phase.
98  */
99 enum ContainerRemovedFlagBits
100 {
101   NOTHING               = 0x00,
102   NODE                  = 0x01,
103   RENDERER              = 0x02,
104   SHADER                = 0x04,
105   TEXTURE_SET           = 0x08,
106   ANIMATION             = 0x10,
107   PROPERTY_NOTIFICATION = 0x20,
108   CUSTOM_OBJECT         = 0x40,
109 };
110
111 /**
112  * @brief ContainerRemovedFlags alters behaviour of implementation
113  */
114 using ContainerRemovedFlags = uint8_t;
115 #endif
116 /**
117  * Helper to Erase an object from OwnerContainer using discard queue
118  * @param container to remove from
119  * @param object to remove
120  * @param discardQueue to put the object to
121  * @param updateBufferIndex to use
122  */
123 template<class Type>
124 inline void EraseUsingDiscardQueue(OwnerContainer<Type*>& container, Type* object, DiscardQueue<Type*, OwnerContainer<Type*>>& discardQueue, BufferIndex updateBufferIndex)
125 {
126   DALI_ASSERT_DEBUG(object && "NULL object not allowed");
127
128   // need to use the reference version of auto as we need the pointer to the pointer for the Release call below
129   for(auto&& iter : container)
130   {
131     if(iter == object)
132     {
133       // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it
134       discardQueue.Add(updateBufferIndex, container.Release(&iter)); // take the address of the reference to a pointer (iter)
135       return;                                                        // return as we only ever remove one object. Iterators to container are now invalidated as well so cannot continue
136     }
137   }
138 }
139
140 /**
141  * Helper to Erase an object from std::vector using discard queue
142  * @param container to remove from
143  * @param object to remove
144  * @param discardQueue to put the object to
145  * @param updateBufferIndex to use
146  */
147 template<class Type>
148 inline void EraseUsingDiscardQueue(OwnerKeyContainer<Type>& container, const MemoryPoolKey<Type>& key, DiscardQueue<MemoryPoolKey<Type>, OwnerKeyContainer<Type>>& discardQueue, BufferIndex updateBufferIndex)
149 {
150   DALI_ASSERT_DEBUG(key && "INVALID Key not allowed");
151
152   for(auto iter = container.begin(), end = container.end(); iter != end; ++iter)
153   {
154     if(*iter == key)
155     {
156       // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it
157       discardQueue.Add(updateBufferIndex, container.Release(iter));
158       return; // return as we only ever remove one object. Iterators to container are now invalidated as well so cannot continue
159     }
160   }
161 }
162
163 } // unnamed namespace
164
165 /**
166  * Structure to contain UpdateManager internal data
167  */
168 struct UpdateManager::Impl
169 {
170   // SceneInfo keeps the root node of the Scene, its scene graph render task list, and the list of Layer pointers sorted by depth
171   struct SceneInfo
172   {
173     SceneInfo(Layer* root) ///< Constructor
174     : root(root)
175     {
176     }
177
178     ~SceneInfo()               = default;                ///< Default non-virtual destructor
179     SceneInfo(SceneInfo&& rhs) = default;                ///< Move constructor
180     SceneInfo& operator=(SceneInfo&& rhs) = default;     ///< Move assignment operator
181     SceneInfo& operator=(const SceneInfo& rhs) = delete; ///< Assignment operator
182     SceneInfo(const SceneInfo& rhs)            = delete; ///< Copy constructor
183
184     Layer*                       root{nullptr};   ///< Root node (root is a layer). The layer is not stored in the node memory pool.
185     OwnerPointer<RenderTaskList> taskList;        ///< Scene graph render task list
186     SortedLayerPointers          sortedLayerList; ///< List of Layer pointers sorted by depth (one list of sorted layers per root)
187     OwnerPointer<Scene>          scene;           ///< Scene graph object of the scene
188   };
189
190   Impl(NotificationManager&           notificationManager,
191        CompleteNotificationInterface& animationPlaylist,
192        PropertyNotifier&              propertyNotifier,
193        RenderController&              renderController,
194        RenderManager&                 renderManager,
195        RenderQueue&                   renderQueue,
196        SceneGraphBuffers&             sceneGraphBuffers,
197        RenderTaskProcessor&           renderTaskProcessor)
198   : renderMessageDispatcher(renderManager, renderQueue, sceneGraphBuffers),
199     notificationManager(notificationManager),
200     transformManager(),
201     animationPlaylist(animationPlaylist),
202     propertyNotifier(propertyNotifier),
203     shaderSaver(nullptr),
204     renderController(renderController),
205     sceneController(nullptr),
206     renderManager(renderManager),
207     renderQueue(renderQueue),
208     renderTaskProcessor(renderTaskProcessor),
209     backgroundColor(Dali::DEFAULT_BACKGROUND_COLOR),
210     renderers(),
211     textureSets(),
212     shaders(),
213     panGestureProcessor(nullptr),
214     messageQueue(renderController, sceneGraphBuffers),
215     frameCallbackProcessor(nullptr),
216     nodeDirtyFlags(NodePropertyFlags::TRANSFORM), // set to TransformFlag to ensure full update the first time through Update()
217     frameCounter(0),
218     renderingBehavior(DevelStage::Rendering::IF_REQUIRED),
219 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
220     containerRemovedFlags(ContainerRemovedFlagBits::NOTHING),
221 #endif
222     animationFinishedDuringUpdate(false),
223     previousUpdateScene(false),
224     renderTaskWaiting(false),
225     renderersAdded(false),
226     renderingRequired(false)
227   {
228     sceneController = new SceneControllerImpl(renderMessageDispatcher, renderQueue);
229
230     // create first 'dummy' node
231     nodes.PushBack(nullptr);
232   }
233
234   ~Impl()
235   {
236     // Disconnect render tasks from nodes, before destroying the nodes
237     for(auto&& scene : scenes)
238     {
239       if(scene && scene->taskList)
240       {
241         RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
242         for(auto&& task : tasks)
243         {
244           task->SetSourceNode(nullptr);
245         }
246       }
247     }
248
249     // UpdateManager owns the Nodes. Although Nodes are pool allocated they contain heap allocated parts
250     // like custom properties, which get released here
251     Vector<Node*>::Iterator iter    = nodes.Begin() + 1;
252     Vector<Node*>::Iterator endIter = nodes.End();
253     for(; iter != endIter; ++iter)
254     {
255       (*iter)->OnDestroy();
256       Node::Delete(*iter);
257     }
258     nodeIdMap.clear();
259
260     for(auto&& scene : scenes)
261     {
262       if(scene && scene->root)
263       {
264         scene->root->OnDestroy();
265         Node::Delete(scene->root);
266       }
267     }
268     scenes.clear();
269
270     delete sceneController;
271
272     // Ensure to clear renderers
273     renderers.Clear();
274     shaders.Clear();
275   }
276
277   /**
278    * Lazy init for FrameCallbackProcessor.
279    * @param[in]  updateManager  A reference to the update-manager
280    */
281   FrameCallbackProcessor& GetFrameCallbackProcessor(UpdateManager& updateManager)
282   {
283     if(!frameCallbackProcessor)
284     {
285       frameCallbackProcessor = new FrameCallbackProcessor(updateManager, transformManager);
286     }
287     return *frameCallbackProcessor;
288   }
289
290   SceneGraphBuffers              sceneGraphBuffers;       ///< Used to keep track of which buffers are being written or read
291   RenderMessageDispatcher        renderMessageDispatcher; ///< Used for passing messages to the render-thread
292   NotificationManager&           notificationManager;     ///< Queues notification messages for the event-thread.
293   TransformManager               transformManager;        ///< Used to update the transformation matrices of the nodes
294   CompleteNotificationInterface& animationPlaylist;       ///< Holds handles to all the animations
295   PropertyNotifier&              propertyNotifier;        ///< Provides notification to applications when properties are modified.
296   ShaderSaver*                   shaderSaver;             ///< Saves shader binaries.
297   RenderController&              renderController;        ///< render controller
298   SceneControllerImpl*           sceneController;         ///< scene controller
299   RenderManager&                 renderManager;           ///< This is responsible for rendering the results of each "update"
300   RenderQueue&                   renderQueue;             ///< Used to queue messages for the next render
301   RenderTaskProcessor&           renderTaskProcessor;     ///< Handles RenderTasks and RenderInstrucitons
302
303   Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
304
305   using SceneInfoPtr = std::unique_ptr<SceneInfo>;
306   std::vector<SceneInfoPtr> scenes; ///< A container of SceneInfo.
307
308   Vector<Node*> nodes; ///< A container of all instantiated nodes
309
310 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
311   using NodeIdMap = std::map<uint32_t, Node*>;
312 #else
313   using NodeIdMap = std::unordered_map<uint32_t, Node*>;
314 #endif
315   NodeIdMap nodeIdMap; ///< A container of nodes map by id.
316
317   Vector<Camera*> cameras; ///< A container of cameras. Note : these cameras are owned by Impl::nodes.
318
319   OwnerContainer<PropertyOwner*> customObjects; ///< A container of owned objects (with custom properties)
320
321   ResetterContainer<PropertyResetterBase> propertyResetters; ///< A container of property resetters
322   ResetterContainer<NodeResetter>         nodeResetters;     ///< A container of node resetters
323   ResetterContainer<RendererResetter>     rendererResetters; ///< A container of renderer resetters
324
325   OwnerContainer<Animation*>            animations;            ///< A container of owned animations
326   OwnerContainer<PropertyNotification*> propertyNotifications; ///< A container of owner property notifications.
327   OwnerKeyContainer<Renderer>           renderers;             ///< A container of owned renderers
328   OwnerContainer<TextureSet*>           textureSets;           ///< A container of owned texture sets
329   OwnerContainer<Shader*>               shaders;               ///< A container of owned shaders
330
331   DiscardQueue<Node*, OwnerContainer<Node*>>                         nodeDiscardQueue; ///< Nodes are added here when disconnected from the scene-graph.
332   DiscardQueue<Shader*, OwnerContainer<Shader*>>                     shaderDiscardQueue;
333   DiscardQueue<MemoryPoolKey<Renderer>, OwnerKeyContainer<Renderer>> rendererDiscardQueue;
334   DiscardQueue<Scene*, OwnerContainer<Scene*>>                       sceneDiscardQueue;
335
336   CompleteNotificationInterface::ParameterList notifyRequiredAnimations; ///< A temperal container of complete notify required animations, like animation finished, stopped, or loop completed.
337
338   OwnerPointer<PanGesture> panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
339
340   MessageQueue                         messageQueue;          ///< The messages queued from the event-thread
341   std::vector<Internal::ShaderDataPtr> renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
342   std::vector<Internal::ShaderDataPtr> updateCompiledShaders; ///< Shaders to be sent from Update to Event
343   Mutex                                compiledShaderMutex;   ///< lock to ensure no corruption on the renderCompiledShaders
344
345   OwnerPointer<FrameCallbackProcessor> frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required.
346
347   std::atomic<std::size_t> renderInstructionCapacity{0u};
348   NodePropertyFlags        nodeDirtyFlags;    ///< cumulative node dirty flags from previous frame
349   uint32_t                 frameCounter;      ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
350   DevelStage::Rendering    renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior
351
352 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
353   ContainerRemovedFlags containerRemovedFlags; ///< cumulative container removed flags during current frame
354 #endif
355
356   bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
357   bool previousUpdateScene;           ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
358   bool renderTaskWaiting;             ///< A REFRESH_ONCE render task is waiting to be rendered
359   bool renderersAdded;                ///< Flag to keep track when renderers have been added to avoid unnecessary processing
360   bool renderingRequired;             ///< True if required to render the current frame
361
362 private:
363   Impl(const Impl&);            ///< Undefined
364   Impl& operator=(const Impl&); ///< Undefined
365 };
366
367 UpdateManager::UpdateManager(NotificationManager&           notificationManager,
368                              CompleteNotificationInterface& animationFinishedNotifier,
369                              PropertyNotifier&              propertyNotifier,
370                              RenderController&              controller,
371                              RenderManager&                 renderManager,
372                              RenderQueue&                   renderQueue,
373                              RenderTaskProcessor&           renderTaskProcessor)
374 : mImpl(nullptr)
375 {
376   mImpl = new Impl(notificationManager,
377                    animationFinishedNotifier,
378                    propertyNotifier,
379                    controller,
380                    renderManager,
381                    renderQueue,
382                    mSceneGraphBuffers,
383                    renderTaskProcessor);
384 }
385
386 UpdateManager::~UpdateManager()
387 {
388   delete mImpl;
389 }
390
391 void UpdateManager::InstallRoot(OwnerPointer<Layer>& layer)
392 {
393   DALI_ASSERT_DEBUG(layer->IsLayer());
394   DALI_ASSERT_DEBUG(layer->GetParent() == NULL);
395
396   Layer* rootLayer = layer.Release();
397
398   DALI_ASSERT_DEBUG(std::find_if(mImpl->scenes.begin(), mImpl->scenes.end(), [rootLayer](Impl::SceneInfoPtr& scene) { return scene && scene->root == rootLayer; }) == mImpl->scenes.end() &&
399                     "Root Node already installed");
400
401   rootLayer->CreateTransform(&mImpl->transformManager);
402   rootLayer->SetRoot(true);
403
404   rootLayer->AddInitializeResetter(*this);
405
406   // Do not allow to insert duplicated nodes.
407   // It could be happened if node id is overflowed.
408   DALI_ASSERT_ALWAYS(mImpl->nodeIdMap.insert({rootLayer->GetId(), rootLayer}).second);
409
410   mImpl->scenes.emplace_back(new Impl::SceneInfo(rootLayer));
411 }
412
413 void UpdateManager::UninstallRoot(Layer* layer)
414 {
415   DALI_ASSERT_DEBUG(layer->IsLayer());
416   DALI_ASSERT_DEBUG(layer->GetParent() == NULL);
417
418   for(auto iter = mImpl->scenes.begin(); iter != mImpl->scenes.end(); ++iter)
419   {
420     if((*iter) && (*iter)->root == layer)
421     {
422       mImpl->scenes.erase(iter);
423       break;
424     }
425   }
426
427   mImpl->nodeIdMap.erase(layer->GetId());
428
429   mImpl->nodeDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), layer);
430
431   // Notify the layer about impending destruction
432   layer->OnDestroy();
433 }
434
435 void UpdateManager::AddNode(OwnerPointer<Node>& node)
436 {
437   DALI_ASSERT_ALWAYS(nullptr == node->GetParent()); // Should not have a parent yet
438
439   Node* rawNode = node.Release();
440   DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] AddNode\n", rawNode);
441
442   // Add camera nodes occured rarely.
443   if(DALI_UNLIKELY(rawNode->IsCamera()))
444   {
445     AddCamera(static_cast<Camera*>(rawNode));
446   }
447
448   // Do not allow to insert duplicated nodes.
449   // It could be happened if node id is overflowed.
450   DALI_ASSERT_ALWAYS(mImpl->nodeIdMap.insert({rawNode->GetId(), rawNode}).second);
451
452   mImpl->nodes.PushBack(rawNode);
453
454   rawNode->CreateTransform(&mImpl->transformManager);
455 }
456
457 void UpdateManager::ConnectNode(Node* parent, Node* node)
458 {
459   DALI_ASSERT_ALWAYS(nullptr != parent);
460   DALI_ASSERT_ALWAYS(nullptr != node);
461   DALI_ASSERT_ALWAYS(nullptr == node->GetParent()); // Should not have a parent yet
462
463   DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] ConnectNode\n", node);
464
465   parent->SetDirtyFlag(NodePropertyFlags::DESCENDENT_HIERARCHY_CHANGED); // make parent dirty so that render items dont get reused
466   parent->ConnectChild(node);
467
468   node->AddInitializeResetter(*this);
469
470   // Inform the frame-callback-processor, if set, about the node-hierarchy changing
471   if(mImpl->frameCallbackProcessor)
472   {
473     mImpl->frameCallbackProcessor->NodeHierarchyChanged();
474   }
475 }
476
477 void UpdateManager::DisconnectNode(Node* node)
478 {
479   DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] DisconnectNode\n", node);
480
481   Node* parent = node->GetParent();
482   DALI_ASSERT_ALWAYS(nullptr != parent);
483   parent->SetDirtyFlag(NodePropertyFlags::CHILD_DELETED | NodePropertyFlags::DESCENDENT_HIERARCHY_CHANGED); // make parent dirty so that render items dont get reused
484
485   parent->DisconnectChild(mSceneGraphBuffers.GetUpdateBufferIndex(), *node);
486
487   // Inform the frame-callback-processor, if set, about the node-hierarchy changing
488   if(mImpl->frameCallbackProcessor)
489   {
490     mImpl->frameCallbackProcessor->NodeHierarchyChanged();
491   }
492 }
493
494 void UpdateManager::DestroyNode(Node* node)
495 {
496   DALI_ASSERT_ALWAYS(nullptr != node);
497   DALI_ASSERT_ALWAYS(nullptr == node->GetParent()); // Should have been disconnected
498
499   DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] DestroyNode\n", node);
500
501   Vector<Node*>::Iterator iter    = mImpl->nodes.Begin() + 1;
502   Vector<Node*>::Iterator endIter = mImpl->nodes.End();
503   for(; iter != endIter; ++iter)
504   {
505     if((*iter) == node)
506     {
507       mImpl->nodes.Erase(iter);
508 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
509       mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::NODE;
510 #endif
511       break;
512     }
513   }
514
515   // Remove camera nodes occured rarely.
516   if(DALI_UNLIKELY(node->IsCamera()))
517   {
518     RemoveCamera(static_cast<Camera*>(node));
519   }
520
521   mImpl->nodeIdMap.erase(node->GetId());
522
523   mImpl->nodeDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), node);
524
525   // Notify the Node about impending destruction
526   node->OnDestroy();
527 }
528
529 void UpdateManager::AddCamera(Camera* camera)
530 {
531   DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] AddCamera\n", camera);
532
533   mImpl->cameras.PushBack(camera);
534 }
535
536 void UpdateManager::RemoveCamera(Camera* camera)
537 {
538   DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] RemoveCamera\n", camera);
539
540   // Find the camera and remove it from list of cameras
541   Vector<Camera*>::Iterator iter    = mImpl->cameras.Begin();
542   Vector<Camera*>::Iterator endIter = mImpl->cameras.End();
543   for(; iter != endIter; ++iter)
544   {
545     if((*iter) == camera)
546     {
547       mImpl->cameras.Erase(iter);
548       break;
549     }
550   }
551 }
552
553 void UpdateManager::AddObject(OwnerPointer<PropertyOwner>& object)
554 {
555   mImpl->customObjects.PushBack(object.Release());
556 }
557
558 void UpdateManager::RemoveObject(PropertyOwner* object)
559 {
560   mImpl->customObjects.EraseObject(object);
561 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
562   mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::CUSTOM_OBJECT;
563 #endif
564 }
565
566 void UpdateManager::AddRenderTaskList(OwnerPointer<RenderTaskList>& taskList)
567 {
568   RenderTaskList* taskListPointer = taskList.Release();
569   taskListPointer->Initialize(*this, mImpl->renderMessageDispatcher);
570
571   mImpl->scenes.back()->taskList = taskListPointer;
572 }
573
574 void UpdateManager::RemoveRenderTaskList(RenderTaskList* taskList)
575 {
576   for(auto&& scene : mImpl->scenes)
577   {
578     if(scene && scene->taskList == taskList)
579     {
580       scene->taskList.Reset();
581       break;
582     }
583   }
584 }
585
586 void UpdateManager::AddScene(OwnerPointer<Scene>& scene)
587 {
588   auto& sceneInfo  = mImpl->scenes.back();
589   sceneInfo->scene = scene.Release();
590
591   // Set root to the Scene
592   sceneInfo->scene->SetRoot(sceneInfo->root);
593
594   // Initialize the context from render manager
595   typedef MessageValue1<RenderManager, SceneGraph::Scene*> DerivedType;
596
597   // Reserve some memory inside the render queue
598   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
599
600   // Construct message in the render queue memory; note that delete should not be called on the return value
601   SceneGraph::Scene& sceneObject = *sceneInfo->scene;
602   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::InitializeScene, &sceneObject);
603 }
604
605 void UpdateManager::RemoveScene(Scene* scene)
606 {
607   // Initialize the context from render manager
608   using DerivedType = MessageValue1<RenderManager, SceneGraph::Scene*>;
609
610   // Reserve some memory inside the render queue
611   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
612
613   // Construct message in the render queue memory; note that delete should not be called on the return value
614   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::UninitializeScene, scene);
615
616   scene->RemoveSurfaceRenderTarget();
617
618   for(auto&& sceneInfo : mImpl->scenes)
619   {
620     if(sceneInfo && sceneInfo->scene && sceneInfo->scene.Get() == scene)
621     {
622       mImpl->sceneDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), sceneInfo->scene.Release()); // take the address of the reference to a pointer
623       break;
624     }
625   }
626 }
627
628 void UpdateManager::AddAnimation(OwnerPointer<SceneGraph::Animation>& animation)
629 {
630   mImpl->animations.PushBack(animation.Release());
631 }
632
633 void UpdateManager::StopAnimation(Animation* animation)
634 {
635   DALI_ASSERT_DEBUG(animation && "NULL animation called to stop");
636
637   bool animationFinished = animation->Stop(mSceneGraphBuffers.GetUpdateBufferIndex());
638
639   mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
640 }
641
642 void UpdateManager::ClearAnimation(Animation* animation)
643 {
644   DALI_ASSERT_DEBUG(animation && "NULL animation called to clear");
645
646   animation->ClearAnimator(mSceneGraphBuffers.GetUpdateBufferIndex());
647 }
648
649 void UpdateManager::RemoveAnimation(Animation* animation)
650 {
651   DALI_ASSERT_DEBUG(animation && "NULL animation called to remove");
652
653   animation->OnDestroy(mSceneGraphBuffers.GetUpdateBufferIndex());
654
655   DALI_ASSERT_DEBUG(animation->GetState() == Animation::Destroyed);
656
657   // Do not remove from container now. Destroyed animation will be removed at Animate.
658 }
659
660 bool UpdateManager::IsAnimationRunning() const
661 {
662   // Find any animation that isn't stopped or paused
663   for(auto&& iter : mImpl->animations)
664   {
665     const Animation::State state = iter->GetState();
666
667     if(state != Animation::Stopped &&
668        state != Animation::Paused)
669     {
670       return true; // stop iteration as soon as first one is found
671     }
672   }
673
674   return false;
675 }
676
677 void UpdateManager::AddPropertyResetter(OwnerPointer<PropertyResetterBase>& propertyResetter)
678 {
679   propertyResetter->Initialize();
680   mImpl->propertyResetters.PushBack(propertyResetter.Release());
681 }
682
683 void UpdateManager::AddNodeResetter(const Node& node)
684 {
685   OwnerPointer<SceneGraph::NodeResetter> nodeResetter = SceneGraph::NodeResetter::New(node);
686   nodeResetter->Initialize();
687   mImpl->nodeResetters.PushBack(nodeResetter.Release());
688 }
689
690 void UpdateManager::AddRendererResetter(const Renderer& renderer)
691 {
692   OwnerPointer<SceneGraph::RendererResetter> rendererResetter = SceneGraph::RendererResetter::New(renderer);
693   rendererResetter->Initialize();
694   mImpl->rendererResetters.PushBack(rendererResetter.Release());
695 }
696
697 void UpdateManager::AddPropertyNotification(OwnerPointer<PropertyNotification>& propertyNotification)
698 {
699   mImpl->propertyNotifications.PushBack(propertyNotification.Release());
700 }
701
702 void UpdateManager::RemovePropertyNotification(PropertyNotification* propertyNotification)
703 {
704   auto iter = std::find(mImpl->propertyNotifications.Begin(), mImpl->propertyNotifications.End(), propertyNotification);
705   if(iter != mImpl->propertyNotifications.End())
706   {
707     mImpl->propertyNotifications.Erase(iter);
708 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
709     mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::PROPERTY_NOTIFICATION;
710 #endif
711   }
712 }
713
714 void UpdateManager::PropertyNotificationSetNotify(PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode)
715 {
716   DALI_ASSERT_DEBUG(propertyNotification && "propertyNotification scene graph object missing");
717   propertyNotification->SetNotifyMode(notifyMode);
718 }
719
720 void UpdateManager::AddShader(OwnerPointer<Shader>& shader)
721 {
722   mImpl->shaders.PushBack(shader.Release());
723 }
724
725 void UpdateManager::RemoveShader(Shader* shader)
726 {
727   // Find the shader and destroy it
728   EraseUsingDiscardQueue(mImpl->shaders, shader, mImpl->shaderDiscardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
729 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
730   mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::SHADER;
731 #endif
732 }
733
734 void UpdateManager::SaveBinary(Internal::ShaderDataPtr shaderData)
735 {
736   DALI_ASSERT_DEBUG(shaderData && "No NULL shader data pointers please.");
737   DALI_ASSERT_DEBUG(shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save.");
738   {
739     // lock as update might be sending previously compiled shaders to event thread
740     Mutex::ScopedLock lock(mImpl->compiledShaderMutex);
741     mImpl->renderCompiledShaders.push_back(shaderData);
742   }
743 }
744
745 void UpdateManager::SetShaderSaver(ShaderSaver& upstream)
746 {
747   mImpl->shaderSaver = &upstream;
748 }
749
750 void UpdateManager::AddRenderer(const RendererKey& rendererKey)
751 {
752   SceneGraph::Renderer* renderer = rendererKey.Get();
753
754   DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer);
755
756   renderer->ConnectToSceneGraph(*mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex());
757   renderer->AddInitializeResetter(*this);
758
759   mImpl->renderers.PushBack(rendererKey);
760 }
761
762 void UpdateManager::RemoveRenderer(const RendererKey& rendererKey)
763 {
764   DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] RemoveRenderer\n", rendererKey.Get());
765
766   // Find the renderer and destroy it
767   EraseUsingDiscardQueue(mImpl->renderers, rendererKey, mImpl->rendererDiscardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
768   // Need to remove the render object as well
769   rendererKey->DisconnectFromSceneGraph(*mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex());
770
771 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
772   mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::RENDERER;
773 #endif
774 }
775
776 void UpdateManager::AttachRenderer(Node* node, Renderer* renderer)
777 {
778   node->AddRenderer(Renderer::GetKey(renderer));
779   mImpl->renderersAdded = true;
780 }
781
782 void UpdateManager::SetPanGestureProcessor(PanGesture* panGestureProcessor)
783 {
784   DALI_ASSERT_DEBUG(NULL != panGestureProcessor);
785
786   mImpl->panGestureProcessor = panGestureProcessor;
787 }
788
789 void UpdateManager::AddTextureSet(OwnerPointer<TextureSet>& textureSet)
790 {
791   textureSet->SetRenderMessageDispatcher(&mImpl->renderMessageDispatcher);
792   mImpl->textureSets.PushBack(textureSet.Release());
793 }
794
795 void UpdateManager::RemoveTextureSet(TextureSet* textureSet)
796 {
797   mImpl->textureSets.EraseObject(textureSet);
798 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
799   mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::TEXTURE_SET;
800 #endif
801 }
802
803 uint32_t* UpdateManager::ReserveMessageSlot(uint32_t size, bool updateScene)
804 {
805   return mImpl->messageQueue.ReserveMessageSlot(size, updateScene);
806 }
807
808 std::size_t UpdateManager::GetUpdateMessageQueueCapacity() const
809 {
810   return mImpl->messageQueue.GetCapacity();
811 }
812
813 std::size_t UpdateManager::GetRenderMessageQueueCapacity() const
814 {
815   return mImpl->renderQueue.GetCapacity();
816 }
817
818 std::size_t UpdateManager::GetRenderInstructionCapacity() const
819 {
820   return mImpl->renderInstructionCapacity;
821 }
822
823 void UpdateManager::EventProcessingStarted()
824 {
825   mImpl->messageQueue.EventProcessingStarted();
826 }
827
828 void UpdateManager::EventProcessingFinished()
829 {
830   mImpl->messageQueue.EventProcessingFinished();
831 }
832
833 bool UpdateManager::FlushQueue()
834 {
835   return mImpl->messageQueue.FlushQueue();
836 }
837
838 void UpdateManager::ResetProperties(BufferIndex bufferIndex)
839 {
840   // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
841   mImpl->animationFinishedDuringUpdate = false;
842
843   // Reset node properties
844   mImpl->nodeResetters.ResetToBaseValues(bufferIndex);
845
846   // Reset renderer properties
847   mImpl->rendererResetters.ResetToBaseValues(bufferIndex);
848
849   // Reset all animating / constrained properties
850   mImpl->propertyResetters.ResetToBaseValues(bufferIndex);
851
852   // Clear all root nodes dirty flags
853   for(auto& scene : mImpl->scenes)
854   {
855     auto root = scene->root;
856     root->ResetDirtyFlags(bufferIndex);
857   }
858
859   // Clear node dirty flags
860   Vector<Node*>::Iterator iter    = mImpl->nodes.Begin() + 1;
861   Vector<Node*>::Iterator endIter = mImpl->nodes.End();
862   for(; iter != endIter; ++iter)
863   {
864     (*iter)->ResetDirtyFlags(bufferIndex);
865   }
866 }
867
868 bool UpdateManager::ProcessGestures(BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds)
869 {
870   bool gestureUpdated(false);
871
872   if(mImpl->panGestureProcessor)
873   {
874     // gesture processor only supports default properties
875     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
876     gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties(lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds);
877   }
878
879   return gestureUpdated;
880 }
881
882 bool UpdateManager::Animate(BufferIndex bufferIndex, float elapsedSeconds)
883 {
884   bool animationActive = false;
885
886   auto&& iter = mImpl->animations.Begin();
887
888   while(iter != mImpl->animations.End())
889   {
890     Animation* animation             = *iter;
891     bool       finished              = false;
892     bool       stopped               = false;
893     bool       progressMarkerReached = false;
894     animation->Update(bufferIndex, elapsedSeconds, stopped, finished, progressMarkerReached);
895
896     animationActive = animationActive || animation->IsActive();
897
898     if(progressMarkerReached)
899     {
900       mImpl->notificationManager.QueueMessage(Internal::NotifyProgressReachedMessage(mImpl->animationPlaylist, animation->GetNotifyId()));
901     }
902
903     mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
904
905     // queue the notification on finished or stopped
906     if(finished || stopped)
907     {
908       mImpl->notifyRequiredAnimations.PushBack(animation->GetNotifyId());
909     }
910
911     // Remove animations that had been destroyed but were still waiting for an update
912     if(animation->GetState() == Animation::Destroyed)
913     {
914       iter = mImpl->animations.Erase(iter);
915 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
916       mImpl->containerRemovedFlags |= ContainerRemovedFlagBits::ANIMATION;
917 #endif
918     }
919     else
920     {
921       ++iter;
922     }
923   }
924
925   // The application should be notified by NotificationManager, in another thread
926   if(!mImpl->notifyRequiredAnimations.Empty())
927   {
928     mImpl->notificationManager.QueueNotification(&mImpl->animationPlaylist, std::move(mImpl->notifyRequiredAnimations));
929   }
930
931   return animationActive;
932 }
933
934 void UpdateManager::ConstrainCustomObjects(PropertyOwnerContainer& postPropertyOwners, BufferIndex bufferIndex)
935 {
936   // Constrain custom objects (in construction order)
937   for(auto&& object : mImpl->customObjects)
938   {
939     ConstrainPropertyOwner(*object, bufferIndex);
940     if(!object->GetPostConstraints().Empty())
941     {
942       postPropertyOwners.PushBack(object);
943     }
944   }
945 }
946
947 void UpdateManager::ConstrainRenderTasks(PropertyOwnerContainer& postPropertyOwners, BufferIndex bufferIndex)
948 {
949   // Constrain render-tasks
950   for(auto&& scene : mImpl->scenes)
951   {
952     if(scene && scene->taskList)
953     {
954       RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
955       for(auto&& task : tasks)
956       {
957         ConstrainPropertyOwner(*task, bufferIndex);
958         if(!task->GetPostConstraints().Empty())
959         {
960           postPropertyOwners.PushBack(task);
961         }
962       }
963     }
964   }
965 }
966
967 void UpdateManager::ConstrainShaders(PropertyOwnerContainer& postPropertyOwners, BufferIndex bufferIndex)
968 {
969   // constrain shaders... (in construction order)
970   for(auto&& shader : mImpl->shaders)
971   {
972     ConstrainPropertyOwner(*shader, bufferIndex);
973     if(!shader->GetPostConstraints().Empty())
974     {
975       postPropertyOwners.PushBack(shader);
976     }
977   }
978 }
979
980 void UpdateManager::ProcessPropertyNotifications(BufferIndex bufferIndex)
981 {
982   for(auto&& notification : mImpl->propertyNotifications)
983   {
984     bool valid = notification->Check(bufferIndex);
985     if(valid)
986     {
987       mImpl->notificationManager.QueueMessage(PropertyChangedMessage(mImpl->propertyNotifier, notification->GetNotifyId(), notification->GetValidity()));
988     }
989   }
990 }
991
992 void UpdateManager::ForwardCompiledShadersToEventThread()
993 {
994   DALI_ASSERT_DEBUG((mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup.");
995   if(mImpl->shaderSaver)
996   {
997     // lock and swap the queues
998     {
999       // render might be attempting to send us more binaries at the same time
1000       Mutex::ScopedLock lock(mImpl->compiledShaderMutex);
1001       mImpl->renderCompiledShaders.swap(mImpl->updateCompiledShaders);
1002     }
1003
1004     if(mImpl->updateCompiledShaders.size() > 0)
1005     {
1006       ShaderSaver& factory = *mImpl->shaderSaver;
1007       for(auto&& shader : mImpl->updateCompiledShaders)
1008       {
1009         mImpl->notificationManager.QueueMessage(ShaderCompiledMessage(factory, shader));
1010       }
1011       // we don't need them in update anymore
1012       mImpl->updateCompiledShaders.clear();
1013     }
1014   }
1015 }
1016
1017 void UpdateManager::UpdateRenderers(PropertyOwnerContainer& postPropertyOwners, BufferIndex bufferIndex)
1018 {
1019   for(const auto& rendererKey : mImpl->renderers)
1020   {
1021     // Apply constraints
1022     auto renderer = rendererKey.Get();
1023     ConstrainPropertyOwner(*renderer, bufferIndex);
1024     if(!renderer->GetPostConstraints().Empty())
1025     {
1026       postPropertyOwners.PushBack(renderer);
1027     }
1028
1029     mImpl->renderingRequired = renderer->PrepareRender(bufferIndex) || mImpl->renderingRequired;
1030   }
1031 }
1032
1033 void UpdateManager::UpdateNodes(PropertyOwnerContainer& postPropertyOwners, BufferIndex bufferIndex)
1034 {
1035   mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
1036
1037   for(auto&& scene : mImpl->scenes)
1038   {
1039     if(scene && scene->root)
1040     {
1041       // Prepare resources, update shaders, for each node
1042       // And add the renderers to the sorted layers. Start from root, which is also a layer
1043       mImpl->nodeDirtyFlags |= UpdateNodeTree(*scene->root,
1044                                               bufferIndex,
1045                                               mImpl->renderQueue,
1046                                               postPropertyOwners);
1047     }
1048   }
1049 }
1050
1051 void UpdateManager::UpdateLayers(BufferIndex bufferIndex)
1052 {
1053   for(auto&& scene : mImpl->scenes)
1054   {
1055     if(scene && scene->root)
1056     {
1057       SceneGraph::UpdateLayerTree(*scene->root, bufferIndex);
1058     }
1059   }
1060 }
1061
1062 uint32_t UpdateManager::Update(float    elapsedSeconds,
1063                                uint32_t lastVSyncTimeMilliseconds,
1064                                uint32_t nextVSyncTimeMilliseconds,
1065                                bool     renderToFboEnabled,
1066                                bool     isRenderingToFbo,
1067                                bool     uploadOnly)
1068 {
1069   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
1070
1071   // Clear nodes/resources which were previously discarded
1072   mImpl->nodeDiscardQueue.Clear(bufferIndex);
1073   mImpl->shaderDiscardQueue.Clear(bufferIndex);
1074   mImpl->rendererDiscardQueue.Clear(bufferIndex);
1075   mImpl->sceneDiscardQueue.Clear(bufferIndex);
1076
1077   bool isAnimationRunning = IsAnimationRunning();
1078
1079   // Process Touches & Gestures
1080   const bool gestureUpdated = ProcessGestures(bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds);
1081
1082   bool updateScene =                                   // The scene-graph requires an update if..
1083     (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
1084     isAnimationRunning ||                              // ..at least one animation is running OR
1085     mImpl->messageQueue.IsSceneUpdateRequired() ||     // ..a message that modifies the scene graph node tree is queued OR
1086     mImpl->frameCallbackProcessor ||                   // ..a frame callback processor is existed OR
1087     gestureUpdated;                                    // ..a gesture property was updated
1088
1089   uint32_t keepUpdating    = 0;
1090   mImpl->renderingRequired = false;
1091
1092   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1093   // values if the scene was updated in the previous frame.
1094   if(updateScene || mImpl->previousUpdateScene)
1095   {
1096     // Reset properties from the previous update
1097     ResetProperties(bufferIndex);
1098     mImpl->transformManager.ResetToBaseValue();
1099   }
1100
1101   // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
1102   // between calling IsSceneUpdateRequired() above and here, so updateScene should
1103   // be set again
1104   updateScene |= mImpl->messageQueue.ProcessMessages(bufferIndex);
1105
1106   // Forward compiled shader programs to event thread for saving
1107   ForwardCompiledShadersToEventThread();
1108
1109   // Although the scene-graph may not require an update, we still need to synchronize double-buffered
1110   // renderer lists if the scene was updated in the previous frame.
1111   // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
1112   if(updateScene || mImpl->previousUpdateScene)
1113   {
1114     // Animate
1115     bool animationActive = Animate(bufferIndex, elapsedSeconds);
1116
1117     PropertyOwnerContainer postPropertyOwners;
1118     // Constraint custom objects
1119     ConstrainCustomObjects(postPropertyOwners, bufferIndex);
1120
1121     // Clear the lists of renderers from the previous update
1122     for(auto&& scene : mImpl->scenes)
1123     {
1124       if(scene)
1125       {
1126         for(auto&& layer : scene->sortedLayerList)
1127         {
1128           if(layer)
1129           {
1130             layer->ClearRenderables();
1131           }
1132         }
1133       }
1134     }
1135
1136     // Call the frame-callback-processor if set
1137     if(mImpl->frameCallbackProcessor)
1138     {
1139       if(mImpl->frameCallbackProcessor->Update(bufferIndex, elapsedSeconds))
1140       {
1141         keepUpdating |= KeepUpdating::FRAME_UPDATE_CALLBACK;
1142       }
1143     }
1144
1145     // Update node hierarchy, apply constraints,
1146     UpdateNodes(postPropertyOwners, bufferIndex);
1147
1148     // Apply constraints to RenderTasks, shaders
1149     ConstrainRenderTasks(postPropertyOwners, bufferIndex);
1150     ConstrainShaders(postPropertyOwners, bufferIndex);
1151
1152     // Update renderers and apply constraints
1153     UpdateRenderers(postPropertyOwners, bufferIndex);
1154
1155     // Update the transformations of all the nodes
1156     if(mImpl->transformManager.Update())
1157     {
1158       mImpl->nodeDirtyFlags |= NodePropertyFlags::TRANSFORM;
1159     }
1160
1161     // Constraint applied after transform manager updated. Only required property owner processed.
1162     for(auto&& propertyOwner : postPropertyOwners)
1163     {
1164       ConstrainPropertyOwner(*propertyOwner, bufferIndex, false);
1165     }
1166
1167     // Initialise layer renderable reuse
1168     UpdateLayers(bufferIndex);
1169
1170     // Process Property Notifications
1171     ProcessPropertyNotifications(bufferIndex);
1172
1173     // Update cameras
1174     for(auto&& cameraIterator : mImpl->cameras)
1175     {
1176       cameraIterator->Update(bufferIndex);
1177     }
1178
1179     // Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
1180     // reset the update buffer index and make sure there is enough room in the instruction container
1181     if(mImpl->renderersAdded)
1182     {
1183       // Calculate how many render tasks we have in total
1184       std::size_t numberOfRenderTasks        = 0;
1185       std::size_t numberOfRenderInstructions = 0;
1186       bool        renderContinuously         = false;
1187       for(auto&& scene : mImpl->scenes)
1188       {
1189         if(scene && scene->taskList)
1190         {
1191           numberOfRenderTasks += scene->taskList->GetTasks().Count();
1192         }
1193       }
1194
1195       mImpl->renderInstructionCapacity = 0u;
1196       for(auto&& scene : mImpl->scenes)
1197       {
1198         if(scene && scene->root && scene->taskList && scene->scene)
1199         {
1200           scene->scene->GetRenderInstructions().ResetAndReserve(bufferIndex,
1201                                                                 static_cast<uint32_t>(scene->taskList->GetTasks().Count()));
1202
1203           bool sceneKeepUpdating = scene->scene->KeepRenderingCheck(elapsedSeconds);
1204           if(sceneKeepUpdating)
1205           {
1206             keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
1207           }
1208
1209           // If there are animations running, only add render instruction if at least one animation is currently active (i.e. not delayed)
1210           // or the nodes are dirty
1211           // or keep rendering is requested
1212           if(!isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || sceneKeepUpdating)
1213           {
1214             renderContinuously |= mImpl->renderTaskProcessor.Process(bufferIndex,
1215                                                                      *scene->taskList,
1216                                                                      *scene->root,
1217                                                                      scene->sortedLayerList,
1218                                                                      scene->scene->GetRenderInstructions(),
1219                                                                      renderToFboEnabled,
1220                                                                      isRenderingToFbo);
1221
1222             mImpl->renderInstructionCapacity += scene->scene->GetRenderInstructions().GetCapacity();
1223             scene->scene->SetSkipRendering(false);
1224           }
1225           else
1226           {
1227             scene->scene->SetSkipRendering(true);
1228           }
1229
1230           numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count(bufferIndex);
1231         }
1232       }
1233
1234       if(renderContinuously)
1235       {
1236         keepUpdating |= KeepUpdating::RENDERER_CONTINUOUSLY;
1237       }
1238
1239       DALI_LOG_INFO(gLogFilter, Debug::General, "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n", numberOfRenderTasks, numberOfRenderInstructions);
1240     }
1241   }
1242
1243   if(!uploadOnly)
1244   {
1245     // check the countdown and notify
1246     mImpl->renderTaskWaiting = false;
1247
1248     for(auto&& scene : mImpl->scenes)
1249     {
1250       if(scene && scene->root && scene->taskList)
1251       {
1252         RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
1253
1254         CompleteNotificationInterface::ParameterList notifyRequiredRenderTasks;
1255
1256         for(auto&& renderTask : tasks)
1257         {
1258           renderTask->UpdateState();
1259
1260           if(renderTask->IsWaitingToRender() &&
1261              renderTask->ReadyToRender(bufferIndex) /*avoid updating forever when source actor is off-stage*/)
1262           {
1263             mImpl->renderTaskWaiting = true; // keep update/render threads alive
1264           }
1265
1266           if(renderTask->HasRendered())
1267           {
1268             notifyRequiredRenderTasks.PushBack(renderTask->GetNotifyId());
1269           }
1270         }
1271
1272         if(!notifyRequiredRenderTasks.Empty())
1273         {
1274           DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1275           mImpl->notificationManager.QueueNotification(scene->taskList->GetCompleteNotificationInterface(), std::move(notifyRequiredRenderTasks));
1276         }
1277       }
1278     }
1279   }
1280
1281   // Macro is undefined in release build.
1282   SNAPSHOT_NODE_LOGGING;
1283
1284 #if defined(LOW_SPEC_MEMORY_MANAGEMENT_ENABLED)
1285   // Shrink relevant containers if required.
1286   if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::NODE)
1287   {
1288     mImpl->nodes.ShrinkToFitIfNeeded();
1289   }
1290   if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::RENDERER)
1291   {
1292     mImpl->renderers.ShrinkToFitIfNeeded();
1293   }
1294   if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::SHADER)
1295   {
1296     mImpl->shaders.ShrinkToFitIfNeeded();
1297   }
1298   if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::TEXTURE_SET)
1299   {
1300     mImpl->textureSets.ShrinkToFitIfNeeded();
1301   }
1302   if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::ANIMATION)
1303   {
1304     mImpl->animations.ShrinkToFitIfNeeded();
1305   }
1306   if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::PROPERTY_NOTIFICATION)
1307   {
1308     mImpl->propertyNotifications.ShrinkToFitIfNeeded();
1309   }
1310   if(mImpl->containerRemovedFlags & ContainerRemovedFlagBits::CUSTOM_OBJECT)
1311   {
1312     mImpl->customObjects.ShrinkToFitIfNeeded();
1313   }
1314
1315   // Reset flag
1316   mImpl->containerRemovedFlags = ContainerRemovedFlagBits::NOTHING;
1317 #endif
1318
1319   // A ResetProperties() may be required in the next frame
1320   mImpl->previousUpdateScene = updateScene;
1321
1322   // Check whether further updates are required
1323   keepUpdating |= KeepUpdatingCheck(elapsedSeconds);
1324
1325   if(keepUpdating & (KeepUpdating::STAGE_KEEP_RENDERING | KeepUpdating::FRAME_UPDATE_CALLBACK | KeepUpdating::RENDERER_CONTINUOUSLY))
1326   {
1327     // Set dirty flags for next frame to continue rendering
1328     mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
1329   }
1330
1331   // tell the update manager that we're done so the queue can be given to event thread
1332   mImpl->notificationManager.UpdateCompleted();
1333
1334   // The update has finished; swap the double-buffering indices
1335   mSceneGraphBuffers.Swap();
1336
1337   return keepUpdating;
1338 }
1339
1340 void UpdateManager::PostRender()
1341 {
1342   // Reset dirty flag
1343   for(auto&& renderer : mImpl->renderers)
1344   {
1345     renderer->SetUpdated(false);
1346   }
1347
1348   for(auto&& shader : mImpl->shaders)
1349   {
1350     shader->SetUpdated(false);
1351   }
1352
1353   for(auto&& scene : mImpl->scenes)
1354   {
1355     scene->root->SetUpdatedTree(false);
1356   }
1357 }
1358
1359 uint32_t UpdateManager::KeepUpdatingCheck(float elapsedSeconds) const
1360 {
1361   uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1362
1363   // If the rendering behavior is set to continuously render, then continue to render.
1364   // Keep updating until no messages are received and no animations are running.
1365   // If an animation has just finished, update at least once more for Discard end-actions.
1366   // No need to check for renderQueue as there is always a render after update and if that
1367   // render needs another update it will tell the adaptor to call update again
1368
1369   if(mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY)
1370   {
1371     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1372   }
1373
1374   if(IsAnimationRunning() ||
1375      mImpl->animationFinishedDuringUpdate)
1376   {
1377     keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1378   }
1379
1380   if(mImpl->renderTaskWaiting)
1381   {
1382     keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1383   }
1384
1385   return keepUpdatingRequest;
1386 }
1387
1388 void UpdateManager::SurfaceReplaced(Scene* scene)
1389 {
1390   using DerivedType = MessageValue1<RenderManager, Scene*>;
1391
1392   // Reserve some memory inside the render queue
1393   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1394
1395   // Construct message in the render queue memory; note that delete should not be called on the return value
1396   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SurfaceReplaced, scene);
1397 }
1398
1399 void UpdateManager::KeepRendering(float durationSeconds)
1400 {
1401   for(auto&& scene : mImpl->scenes)
1402   {
1403     if(scene->scene)
1404     {
1405       scene->scene->KeepRendering(durationSeconds);
1406     }
1407   }
1408 }
1409
1410 void UpdateManager::SetRenderingBehavior(DevelStage::Rendering renderingBehavior)
1411 {
1412   mImpl->renderingBehavior = renderingBehavior;
1413 }
1414
1415 void UpdateManager::RequestRendering()
1416 {
1417   mImpl->renderingRequired = true;
1418 }
1419
1420 Node* UpdateManager::GetNodePointerById(uint32_t nodeId) const
1421 {
1422   Node* foundNodePointer = nullptr;
1423   auto  iter             = mImpl->nodeIdMap.find(nodeId);
1424   if(iter != mImpl->nodeIdMap.end())
1425   {
1426     foundNodePointer = iter->second;
1427   }
1428   return foundNodePointer;
1429 }
1430
1431 void UpdateManager::SetLayerDepths(const SortedLayerPointers& layers, const Layer* rootLayer)
1432 {
1433   for(auto&& scene : mImpl->scenes)
1434   {
1435     if(scene && scene->root == rootLayer)
1436     {
1437       scene->sortedLayerList = layers;
1438       break;
1439     }
1440   }
1441 }
1442
1443 void UpdateManager::SetDepthIndices(OwnerPointer<NodeDepths>& nodeDepths)
1444 {
1445   // note, this vector is already in depth order.
1446   // So if we reverse iterate, we can assume that
1447   // my descendant node's depth index are updated.
1448
1449   // And also, This API is the last flushed message.
1450   // We can now setup the DESCENDENT_HIERARCHY_CHANGED flag here.
1451   for(auto rIter = nodeDepths->nodeDepths.rbegin(), rEndIter = nodeDepths->nodeDepths.rend(); rIter != rEndIter; rIter++)
1452   {
1453     auto* node = rIter->node;
1454     node->PropagateDescendentFlags();
1455     node->SetDepthIndex(rIter->sortedDepth);
1456     if(node->IsChildrenReorderRequired())
1457     {
1458       // Reorder children container only if sibiling order changed.
1459       NodeContainer& container = node->GetChildren();
1460       std::sort(container.Begin(), container.End(), [](Node* a, Node* b) { return a->GetDepthIndex() < b->GetDepthIndex(); });
1461     }
1462   }
1463 }
1464
1465 void UpdateManager::AddFrameCallback(OwnerPointer<FrameCallback>& frameCallback, const Node* rootNode)
1466 {
1467   mImpl->GetFrameCallbackProcessor(*this).AddFrameCallback(frameCallback, rootNode);
1468 }
1469
1470 void UpdateManager::RemoveFrameCallback(FrameCallbackInterface* frameCallback)
1471 {
1472   mImpl->GetFrameCallbackProcessor(*this).RemoveFrameCallback(frameCallback);
1473 }
1474
1475 void UpdateManager::NotifyFrameCallback(FrameCallbackInterface* frameCallback, Dali::UpdateProxy::NotifySyncPoint syncPoint)
1476 {
1477   mImpl->GetFrameCallbackProcessor(*this).NotifyFrameCallback(frameCallback, syncPoint);
1478 }
1479
1480 void UpdateManager::AddSampler(OwnerPointer<Render::Sampler>& sampler)
1481 {
1482   // Message has ownership of Sampler while in transit from update to render
1483   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Sampler>>;
1484
1485   // Reserve some memory inside the render queue
1486   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1487
1488   // Construct message in the render queue memory; note that delete should not be called on the return value
1489   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AddSampler, sampler);
1490 }
1491
1492 void UpdateManager::RemoveSampler(Render::Sampler* sampler)
1493 {
1494   using DerivedType = MessageValue1<RenderManager, Render::Sampler*>;
1495
1496   // Reserve some memory inside the render queue
1497   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1498
1499   // Construct message in the render queue memory; note that delete should not be called on the return value
1500   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::RemoveSampler, sampler);
1501 }
1502
1503 void UpdateManager::SetFilterMode(Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode)
1504 {
1505   using DerivedType = MessageValue3<RenderManager, Render::Sampler*, uint32_t, uint32_t>;
1506
1507   // Reserve some memory inside the render queue
1508   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1509
1510   // Construct message in the render queue memory; note that delete should not be called on the return value
1511   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode);
1512 }
1513
1514 void UpdateManager::SetWrapMode(Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode)
1515 {
1516   using DerivedType = MessageValue4<RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t>;
1517
1518   // Reserve some memory inside the render queue
1519   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1520
1521   // Construct message in the render queue memory; note that delete should not be called on the return value
1522   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode);
1523 }
1524
1525 void UpdateManager::AddVertexBuffer(OwnerPointer<Render::VertexBuffer>& vertexBuffer)
1526 {
1527   // Message has ownership of format while in transit from update -> render
1528   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer>>;
1529
1530   // Reserve some memory inside the render queue
1531   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1532
1533   // Construct message in the render queue memory; note that delete should not be called on the return value
1534   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AddVertexBuffer, vertexBuffer);
1535 }
1536
1537 void UpdateManager::RemoveVertexBuffer(Render::VertexBuffer* vertexBuffer)
1538 {
1539   using DerivedType = MessageValue1<RenderManager, Render::VertexBuffer*>;
1540
1541   // Reserve some memory inside the render queue
1542   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1543
1544   // Construct message in the render queue memory; note that delete should not be called on the return value
1545   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::RemoveVertexBuffer, vertexBuffer);
1546 }
1547
1548 void UpdateManager::SetVertexBufferFormat(Render::VertexBuffer* vertexBuffer, OwnerPointer<Render::VertexBuffer::Format>& format)
1549 {
1550   // Message has ownership of format while in transit from update -> render
1551   using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, OwnerPointer<Render::VertexBuffer::Format>>;
1552
1553   // Reserve some memory inside the render queue
1554   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1555
1556   // Construct message in the render queue memory; note that delete should not be called on the return value
1557   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetVertexBufferFormat, vertexBuffer, format);
1558 }
1559
1560 void UpdateManager::SetVertexBufferData(Render::VertexBuffer* vertexBuffer, OwnerPointer<Vector<uint8_t>>& data, uint32_t size)
1561 {
1562   // Message has ownership of format while in transit from update -> render
1563   using DerivedType = MessageValue3<RenderManager, Render::VertexBuffer*, OwnerPointer<Dali::Vector<uint8_t>>, uint32_t>;
1564
1565   // Reserve some memory inside the render queue
1566   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1567
1568   // Construct message in the render queue memory; note that delete should not be called on the return value
1569   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetVertexBufferData, vertexBuffer, data, size);
1570 }
1571
1572 void UpdateManager::SetVertexBufferDivisor(Render::VertexBuffer* vertexBuffer, uint32_t divisor)
1573 {
1574   using LocalType = MessageValue1<Render::VertexBuffer, uint32_t>;
1575   uint32_t* slot  = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(LocalType));
1576   new(slot) LocalType(vertexBuffer, &Render::VertexBuffer::SetDivisor, divisor);
1577 }
1578
1579 void UpdateManager::SetVertexBufferUpdateCallback(Render::VertexBuffer* vertexBuffer, Dali::VertexBufferUpdateCallback* callback)
1580 {
1581   // Message has ownership of format while in transit from update -> render
1582   using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, Dali::VertexBufferUpdateCallback*>;
1583
1584   // Reserve some memory inside the render queue
1585   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1586
1587   // Construct message in the render queue memory; note that delete should not be called on the return value
1588   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetVertexBufferUpdateCallback, vertexBuffer, callback);
1589 }
1590
1591 void UpdateManager::AddGeometry(OwnerPointer<Render::Geometry>& geometry)
1592 {
1593   // Message has ownership of format while in transit from update -> render
1594   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry>>;
1595
1596   // Reserve some memory inside the render queue
1597   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1598
1599   // Construct message in the render queue memory; note that delete should not be called on the return value
1600   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AddGeometry, geometry);
1601 }
1602
1603 void UpdateManager::RemoveGeometry(Render::Geometry* geometry)
1604 {
1605   using DerivedType = MessageValue1<RenderManager, Render::Geometry*>;
1606
1607   // Reserve some memory inside the render queue
1608   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1609
1610   // Construct message in the render queue memory; note that delete should not be called on the return value
1611   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::RemoveGeometry, geometry);
1612 }
1613
1614 void UpdateManager::SetGeometryType(Render::Geometry* geometry, uint32_t geometryType)
1615 {
1616   using DerivedType = MessageValue2<RenderManager, Render::Geometry*, uint32_t>;
1617
1618   // Reserve some memory inside the render queue
1619   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1620
1621   // Construct message in the render queue memory; note that delete should not be called on the return value
1622   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType);
1623 }
1624
1625 void UpdateManager::SetIndexBuffer(Render::Geometry* geometry, Render::Geometry::Uint16ContainerType& indices)
1626 {
1627   using DerivedType = IndexBufferMessage<RenderManager, Render::Geometry::Uint16ContainerType>;
1628
1629   // Reserve some memory inside the render queue
1630   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1631
1632   // Construct message in the render queue memory; note that delete should not be called on the return value
1633   new(slot) DerivedType(&mImpl->renderManager, geometry, indices);
1634 }
1635
1636 void UpdateManager::SetIndexBuffer(Render::Geometry* geometry, Render::Geometry::Uint32ContainerType& indices)
1637 {
1638   using DerivedType = IndexBufferMessage<RenderManager, Render::Geometry::Uint32ContainerType>;
1639
1640   // Reserve some memory inside the render queue
1641   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1642
1643   // Construct message in the render queue memory; note that delete should not be called on the return value
1644   new(slot) DerivedType(&mImpl->renderManager, geometry, indices);
1645 }
1646
1647 void UpdateManager::RemoveVertexBuffer(Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer)
1648 {
1649   using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1650
1651   // Reserve some memory inside the render queue
1652   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1653
1654   // Construct message in the render queue memory; note that delete should not be called on the return value
1655   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, vertexBuffer);
1656 }
1657
1658 void UpdateManager::AttachVertexBuffer(Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer)
1659 {
1660   using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1661
1662   // Reserve some memory inside the render queue
1663   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1664
1665   // Construct message in the render queue memory; note that delete should not be called on the return value
1666   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, vertexBuffer);
1667 }
1668
1669 void UpdateManager::AddTexture(const Render::TextureKey& texture)
1670 {
1671   using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
1672
1673   // Reserve some memory inside the render queue
1674   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1675
1676   // Construct message in the render queue memory; note that delete should not be called on the return value
1677   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AddTexture, texture);
1678 }
1679
1680 void UpdateManager::RemoveTexture(const Render::TextureKey& texture)
1681 {
1682   using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
1683
1684   // Reserve some memory inside the render queue
1685   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1686
1687   // Construct message in the render queue memory; note that delete should not be called on the return value
1688   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::RemoveTexture, texture);
1689 }
1690
1691 void UpdateManager::UploadTexture(const Render::TextureKey& texture, PixelDataPtr pixelData, const Graphics::UploadParams& params)
1692 {
1693   using DerivedType = MessageValue3<RenderManager, Render::TextureKey, PixelDataPtr, Graphics::UploadParams>;
1694
1695   // Reserve some memory inside the message queue
1696   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1697
1698   // Construct message in the message queue memory; note that delete should not be called on the return value
1699   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params);
1700 }
1701
1702 void UpdateManager::GenerateMipmaps(const Render::TextureKey& texture)
1703 {
1704   using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
1705
1706   // Reserve some memory inside the render queue
1707   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1708
1709   // Construct message in the render queue memory; note that delete should not be called on the return value
1710   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::GenerateMipmaps, texture);
1711 }
1712
1713 void UpdateManager::SetTextureSize(const Render::TextureKey& texture, const Dali::ImageDimensions& size)
1714 {
1715   using DerivedType = MessageValue2<RenderManager, Render::TextureKey, Dali::ImageDimensions>;
1716
1717   // Reserve some memory inside the render queue
1718   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1719
1720   // Construct message in the render queue memory; note that delete should not be called on the return value
1721   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetTextureSize, texture, size);
1722 }
1723
1724 void UpdateManager::SetTextureFormat(const Render::TextureKey& texture, Dali::Pixel::Format pixelFormat)
1725 {
1726   using DerivedType = MessageValue2<RenderManager, Render::TextureKey, Dali::Pixel::Format>;
1727
1728   // Reserve some memory inside the render queue
1729   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1730
1731   // Construct message in the render queue memory; note that delete should not be called on the return value
1732   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetTextureFormat, texture, pixelFormat);
1733 }
1734
1735 void UpdateManager::AddFrameBuffer(OwnerPointer<Render::FrameBuffer>& frameBuffer)
1736 {
1737   using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer>>;
1738
1739   // Reserve some memory inside the render queue
1740   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1741
1742   // Construct message in the render queue memory; note that delete should not be called on the return value
1743   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer);
1744 }
1745
1746 void UpdateManager::RemoveFrameBuffer(Render::FrameBuffer* frameBuffer)
1747 {
1748   using DerivedType = MessageValue1<RenderManager, Render::FrameBuffer*>;
1749
1750   // Reserve some memory inside the render queue
1751   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1752
1753   // Construct message in the render queue memory; note that delete should not be called on the return value
1754   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer);
1755 }
1756
1757 void UpdateManager::AttachColorTextureToFrameBuffer(Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer)
1758 {
1759   using DerivedType = MessageValue4<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t>;
1760
1761   // Reserve some memory inside the render queue
1762   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1763
1764   // Construct message in the render queue memory; note that delete should not be called on the return value
1765   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer);
1766 }
1767
1768 void UpdateManager::AttachDepthTextureToFrameBuffer(Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel)
1769 {
1770   using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1771
1772   // Reserve some memory inside the render queue
1773   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1774
1775   // Construct message in the render queue memory; note that delete should not be called on the return value
1776   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AttachDepthTextureToFrameBuffer, frameBuffer, texture, mipmapLevel);
1777 }
1778
1779 void UpdateManager::AttachDepthStencilTextureToFrameBuffer(Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel)
1780 {
1781   using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1782
1783   // Reserve some memory inside the render queue
1784   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1785
1786   // Construct message in the render queue memory; note that delete should not be called on the return value
1787   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel);
1788 }
1789
1790 void UpdateManager::SetMultiSamplingLevelToFrameBuffer(Render::FrameBuffer* frameBuffer, uint8_t multiSamplingLevel)
1791 {
1792   using DerivedType = MessageValue2<RenderManager, Render::FrameBuffer*, uint8_t>;
1793
1794   // Reserve some memory inside the render queue
1795   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1796
1797   // Construct message in the render queue memory; note that delete should not be called on the return value
1798   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetMultiSamplingLevelToFrameBuffer, frameBuffer, multiSamplingLevel);
1799 }
1800
1801 } // namespace SceneGraph
1802
1803 } // namespace Internal
1804
1805 } // namespace Dali