Merge "Reorder node's children only required case." into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-manager.cpp
index 2873011..72304ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,8 @@
 // INTERNAL INCLUDES
 #include <dali/integration-api/core.h>
 
+#include <dali/internal/common/owner-key-container.h>
+
 #include <dali/internal/event/animation/animation-playlist.h>
 #include <dali/internal/event/common/notification-manager.h>
 #include <dali/internal/event/common/property-notifier.h>
@@ -88,8 +90,8 @@ namespace
  * @param discardQueue to put the object to
  * @param updateBufferIndex to use
  */
-template<class T>
-inline void EraseUsingDiscardQueue(OwnerContainer<T*>& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex)
+template<class Type>
+inline void EraseUsingDiscardQueue(OwnerContainer<Type*>& container, Type* object, DiscardQueue<Type*, OwnerContainer<Type*>>& discardQueue, BufferIndex updateBufferIndex)
 {
   DALI_ASSERT_DEBUG(object && "NULL object not allowed");
 
@@ -106,19 +108,25 @@ inline void EraseUsingDiscardQueue(OwnerContainer<T*>& container, T* object, Dis
 }
 
 /**
- * Descends into node's hierarchy and sorts the children of each child according to their depth-index.
- * @param[in] node The node whose hierarchy to descend
+ * Helper to Erase an object from std::vector using discard queue
+ * @param container to remove from
+ * @param object to remove
+ * @param discardQueue to put the object to
+ * @param updateBufferIndex to use
  */
-void SortSiblingNodesRecursively(Node& node)
+template<class Type>
+inline void EraseUsingDiscardQueue(OwnerKeyContainer<Type>& container, const MemoryPoolKey<Type>& key, DiscardQueue<MemoryPoolKey<Type>, OwnerKeyContainer<Type>>& discardQueue, BufferIndex updateBufferIndex)
 {
-  NodeContainer& container = node.GetChildren();
-  std::sort(container.Begin(), container.End(), [](Node* a, Node* b)
-            { return a->GetDepthIndex() < b->GetDepthIndex(); });
+  DALI_ASSERT_DEBUG(key && "INVALID Key not allowed");
 
-  // Descend tree and sort as well
-  for(auto&& iter : container)
+  for(auto iter = container.begin(), end = container.end(); iter != end; ++iter)
   {
-    SortSiblingNodesRecursively(*iter);
+    if(*iter == key)
+    {
+      // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it
+      discardQueue.Add(updateBufferIndex, container.Release(iter));
+      return; // return as we only ever remove one object. Iterators to container are now invalidated as well so cannot continue
+    }
   }
 }
 
@@ -137,11 +145,11 @@ struct UpdateManager::Impl
     {
     }
 
-    ~SceneInfo()                               = default; ///< Default non-virtual destructor
-    SceneInfo(SceneInfo&& rhs)                 = default; ///< Move constructor
-    SceneInfo& operator=(SceneInfo&& rhs)      = default; ///< Move assignment operator
-    SceneInfo& operator=(const SceneInfo& rhs) = delete;  ///< Assignment operator
-    SceneInfo(const SceneInfo& rhs)            = delete;  ///< Copy constructor
+    ~SceneInfo()               = default;                ///< Default non-virtual destructor
+    SceneInfo(SceneInfo&& rhs) = default;                ///< Move constructor
+    SceneInfo& operator=(SceneInfo&& rhs) = default;     ///< Move assignment operator
+    SceneInfo& operator=(const SceneInfo& rhs) = delete; ///< Assignment operator
+    SceneInfo(const SceneInfo& rhs)            = delete; ///< Copy constructor
 
     Layer*                       root{nullptr};   ///< Root node (root is a layer). The layer is not stored in the node memory pool.
     OwnerPointer<RenderTaskList> taskList;        ///< Scene graph render task list
@@ -152,7 +160,6 @@ struct UpdateManager::Impl
   Impl(NotificationManager&           notificationManager,
        CompleteNotificationInterface& animationPlaylist,
        PropertyNotifier&              propertyNotifier,
-       DiscardQueue&                  discardQueue,
        RenderController&              renderController,
        RenderManager&                 renderManager,
        RenderQueue&                   renderQueue,
@@ -164,7 +171,6 @@ struct UpdateManager::Impl
     animationPlaylist(animationPlaylist),
     propertyNotifier(propertyNotifier),
     shaderSaver(nullptr),
-    discardQueue(discardQueue),
     renderController(renderController),
     sceneController(nullptr),
     renderManager(renderManager),
@@ -187,7 +193,7 @@ struct UpdateManager::Impl
     renderersAdded(false),
     renderingRequired(false)
   {
-    sceneController = new SceneControllerImpl(renderMessageDispatcher, renderQueue, discardQueue);
+    sceneController = new SceneControllerImpl(renderMessageDispatcher, renderQueue);
 
     // create first 'dummy' node
     nodes.PushBack(nullptr);
@@ -255,7 +261,6 @@ struct UpdateManager::Impl
   CompleteNotificationInterface& animationPlaylist;       ///< Holds handles to all the animations
   PropertyNotifier&              propertyNotifier;        ///< Provides notification to applications when properties are modified.
   ShaderSaver*                   shaderSaver;             ///< Saves shader binaries.
-  DiscardQueue&                  discardQueue;            ///< Nodes are added here when disconnected from the scene-graph.
   RenderController&              renderController;        ///< render controller
   SceneControllerImpl*           sceneController;         ///< scene controller
   RenderManager&                 renderManager;           ///< This is responsible for rendering the results of each "update"
@@ -277,10 +282,16 @@ struct UpdateManager::Impl
   OwnerContainer<NodeResetter*>         nodeResetters;         ///< A container of node resetters
   OwnerContainer<Animation*>            animations;            ///< A container of owned animations
   PropertyNotificationContainer         propertyNotifications; ///< A container of owner property notifications.
-  OwnerContainer<Renderer*>             renderers;             ///< A container of owned renderers
+  OwnerKeyContainer<Renderer>           renderers;             ///< A container of owned renderers
   OwnerContainer<TextureSet*>           textureSets;           ///< A container of owned texture sets
   OwnerContainer<Shader*>               shaders;               ///< A container of owned shaders
-  OwnerPointer<PanGesture>              panGestureProcessor;   ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
+
+  DiscardQueue<Node*, OwnerContainer<Node*>>                         nodeDiscardQueue; ///< Nodes are added here when disconnected from the scene-graph.
+  DiscardQueue<Shader*, OwnerContainer<Shader*>>                     shaderDiscardQueue;
+  DiscardQueue<MemoryPoolKey<Renderer>, OwnerKeyContainer<Renderer>> rendererDiscardQueue;
+  DiscardQueue<Scene*, OwnerContainer<Scene*>>                       sceneDiscardQueue;
+
+  OwnerPointer<PanGesture> panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
 
   MessageQueue                         messageQueue;          ///< The messages queued from the event-thread
   std::vector<Internal::ShaderDataPtr> renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
@@ -309,7 +320,6 @@ private:
 UpdateManager::UpdateManager(NotificationManager&           notificationManager,
                              CompleteNotificationInterface& animationFinishedNotifier,
                              PropertyNotifier&              propertyNotifier,
-                             DiscardQueue&                  discardQueue,
                              RenderController&              controller,
                              RenderManager&                 renderManager,
                              RenderQueue&                   renderQueue,
@@ -319,7 +329,6 @@ UpdateManager::UpdateManager(NotificationManager&           notificationManager,
   mImpl = new Impl(notificationManager,
                    animationFinishedNotifier,
                    propertyNotifier,
-                   discardQueue,
                    controller,
                    renderManager,
                    renderQueue,
@@ -339,8 +348,7 @@ void UpdateManager::InstallRoot(OwnerPointer<Layer>& layer)
 
   Layer* rootLayer = layer.Release();
 
-  DALI_ASSERT_DEBUG(std::find_if(mImpl->scenes.begin(), mImpl->scenes.end(), [rootLayer](Impl::SceneInfoPtr& scene)
-                                 { return scene && scene->root == rootLayer; }) == mImpl->scenes.end() &&
+  DALI_ASSERT_DEBUG(std::find_if(mImpl->scenes.begin(), mImpl->scenes.end(), [rootLayer](Impl::SceneInfoPtr& scene) { return scene && scene->root == rootLayer; }) == mImpl->scenes.end() &&
                     "Root Node already installed");
 
   rootLayer->CreateTransform(&mImpl->transformManager);
@@ -365,7 +373,7 @@ void UpdateManager::UninstallRoot(Layer* layer)
     }
   }
 
-  mImpl->discardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), layer);
+  mImpl->nodeDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), layer);
 
   // Notify the layer about impending destruction
   layer->OnDestroy();
@@ -448,7 +456,7 @@ void UpdateManager::DestroyNode(Node* node)
     RemoveCamera(static_cast<Camera*>(node));
   }
 
-  mImpl->discardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), node);
+  mImpl->nodeDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), node);
 
   // Notify the Node about impending destruction
   node->OnDestroy();
@@ -542,7 +550,7 @@ void UpdateManager::RemoveScene(Scene* scene)
   {
     if(sceneInfo && sceneInfo->scene && sceneInfo->scene.Get() == scene)
     {
-      mImpl->discardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), sceneInfo->scene.Release()); // take the address of the reference to a pointer
+      mImpl->sceneDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), sceneInfo->scene.Release()); // take the address of the reference to a pointer
       break;
     }
   }
@@ -625,7 +633,7 @@ void UpdateManager::AddShader(OwnerPointer<Shader>& shader)
 void UpdateManager::RemoveShader(Shader* shader)
 {
   // Find the shader and destroy it
-  EraseUsingDiscardQueue(mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
+  EraseUsingDiscardQueue(mImpl->shaders, shader, mImpl->shaderDiscardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
 }
 
 void UpdateManager::SaveBinary(Internal::ShaderDataPtr shaderData)
@@ -644,27 +652,29 @@ void UpdateManager::SetShaderSaver(ShaderSaver& upstream)
   mImpl->shaderSaver = &upstream;
 }
 
-void UpdateManager::AddRenderer(OwnerPointer<Renderer>& renderer)
+void UpdateManager::AddRenderer(const RendererKey& rendererKey)
 {
-  DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer.Get());
+  SceneGraph::Renderer* renderer = rendererKey.Get();
+
+  DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer);
 
   renderer->ConnectToSceneGraph(*mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex());
-  mImpl->renderers.PushBack(renderer.Release());
+  mImpl->renderers.PushBack(rendererKey);
 }
 
-void UpdateManager::RemoveRenderer(Renderer* renderer)
+void UpdateManager::RemoveRenderer(const RendererKey& rendererKey)
 {
-  DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] RemoveRenderer\n", renderer);
+  DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] RemoveRenderer\n", rendererKey.Get());
 
   // Find the renderer and destroy it
-  EraseUsingDiscardQueue(mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
+  EraseUsingDiscardQueue(mImpl->renderers, rendererKey, mImpl->rendererDiscardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
   // Need to remove the render object as well
-  renderer->DisconnectFromSceneGraph(*mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex());
+  rendererKey->DisconnectFromSceneGraph(*mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex());
 }
 
 void UpdateManager::AttachRenderer(Node* node, Renderer* renderer)
 {
-  node->AddRenderer(renderer);
+  node->AddRenderer(Renderer::GetKey(renderer));
   mImpl->renderersAdded = true;
 }
 
@@ -903,9 +913,10 @@ void UpdateManager::ForwardCompiledShadersToEventThread()
 
 void UpdateManager::UpdateRenderers(BufferIndex bufferIndex)
 {
-  for(auto&& renderer : mImpl->renderers)
+  for(const auto& rendererKey : mImpl->renderers)
   {
     // Apply constraints
+    auto renderer = rendererKey.Get();
     ConstrainPropertyOwner(*renderer, bufferIndex);
 
     mImpl->renderingRequired = renderer->PrepareRender(bufferIndex) || mImpl->renderingRequired;
@@ -950,7 +961,10 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
 
   // Clear nodes/resources which were previously discarded
-  mImpl->discardQueue.Clear(bufferIndex);
+  mImpl->nodeDiscardQueue.Clear(bufferIndex);
+  mImpl->shaderDiscardQueue.Clear(bufferIndex);
+  mImpl->rendererDiscardQueue.Clear(bufferIndex);
+  mImpl->sceneDiscardQueue.Clear(bufferIndex);
 
   bool isAnimationRunning = IsAnimationRunning();
 
@@ -1248,19 +1262,18 @@ void UpdateManager::SetLayerDepths(const SortedLayerPointers& layers, const Laye
 
 void UpdateManager::SetDepthIndices(OwnerPointer<NodeDepths>& nodeDepths)
 {
-  // note,this vector is already in depth order. It could be used as-is to
-  // remove sorting in update algorithm. However, it lacks layer boundary markers.
-  for(auto&& iter : nodeDepths->nodeDepths)
-  {
-    iter.node->SetDepthIndex(iter.sortedDepth);
-  }
-
-  for(auto&& scene : mImpl->scenes)
+  // note, this vector is already in depth order.
+  // So if we reverse iterate, we can assume that
+  // my descendant node's depth index are updated.
+  for(auto rIter = nodeDepths->nodeDepths.rbegin(), rEndIter = nodeDepths->nodeDepths.rend(); rIter != rEndIter; rIter++)
   {
-    if(scene)
+    auto* node = rIter->node;
+    node->SetDepthIndex(rIter->sortedDepth);
+    if(node->IsChildrenReorderRequired())
     {
-      // Go through node hierarchy and rearrange siblings according to depth-index
-      SortSiblingNodesRecursively(*scene->root);
+      // Reorder children container only if sibiling order changed.
+      NodeContainer& container = node->GetChildren();
+      std::sort(container.Begin(), container.End(), [](Node* a, Node* b) { return a->GetDepthIndex() < b->GetDepthIndex(); });
     }
   }
 }
@@ -1278,7 +1291,7 @@ void UpdateManager::RemoveFrameCallback(FrameCallbackInterface* frameCallback)
 void UpdateManager::AddSampler(OwnerPointer<Render::Sampler>& sampler)
 {
   // Message has ownership of Sampler while in transit from update to render
-  using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Sampler> >;
+  using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Sampler>>;
 
   // Reserve some memory inside the render queue
   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
@@ -1323,7 +1336,7 @@ void UpdateManager::SetWrapMode(Render::Sampler* sampler, uint32_t rWrapMode, ui
 void UpdateManager::AddVertexBuffer(OwnerPointer<Render::VertexBuffer>& vertexBuffer)
 {
   // Message has ownership of format while in transit from update -> render
-  using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer> >;
+  using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer>>;
 
   // Reserve some memory inside the render queue
   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
@@ -1346,7 +1359,7 @@ void UpdateManager::RemoveVertexBuffer(Render::VertexBuffer* vertexBuffer)
 void UpdateManager::SetVertexBufferFormat(Render::VertexBuffer* vertexBuffer, OwnerPointer<Render::VertexBuffer::Format>& format)
 {
   // Message has ownership of format while in transit from update -> render
-  using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, OwnerPointer<Render::VertexBuffer::Format> >;
+  using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, OwnerPointer<Render::VertexBuffer::Format>>;
 
   // Reserve some memory inside the render queue
   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
@@ -1355,10 +1368,10 @@ void UpdateManager::SetVertexBufferFormat(Render::VertexBuffer* vertexBuffer, Ow
   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetVertexBufferFormat, vertexBuffer, format);
 }
 
-void UpdateManager::SetVertexBufferData(Render::VertexBuffer* vertexBuffer, OwnerPointer<Vector<uint8_t> >& data, uint32_t size)
+void UpdateManager::SetVertexBufferData(Render::VertexBuffer* vertexBuffer, OwnerPointer<Vector<uint8_t>>& data, uint32_t size)
 {
   // Message has ownership of format while in transit from update -> render
-  using DerivedType = MessageValue3<RenderManager, Render::VertexBuffer*, OwnerPointer<Dali::Vector<uint8_t> >, uint32_t>;
+  using DerivedType = MessageValue3<RenderManager, Render::VertexBuffer*, OwnerPointer<Dali::Vector<uint8_t>>, uint32_t>;
 
   // Reserve some memory inside the render queue
   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
@@ -1370,7 +1383,7 @@ void UpdateManager::SetVertexBufferData(Render::VertexBuffer* vertexBuffer, Owne
 void UpdateManager::AddGeometry(OwnerPointer<Render::Geometry>& geometry)
 {
   // Message has ownership of format while in transit from update -> render
-  using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry> >;
+  using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry>>;
 
   // Reserve some memory inside the render queue
   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
@@ -1434,10 +1447,9 @@ void UpdateManager::AttachVertexBuffer(Render::Geometry* geometry, Render::Verte
   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, vertexBuffer);
 }
 
-void UpdateManager::AddTexture(OwnerPointer<Render::Texture>& texture)
+void UpdateManager::AddTexture(const Render::TextureKey& texture)
 {
-  // Message has ownership of Texture while in transit from update -> render
-  using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Texture> >;
+  using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
 
   // Reserve some memory inside the render queue
   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
@@ -1446,9 +1458,9 @@ void UpdateManager::AddTexture(OwnerPointer<Render::Texture>& texture)
   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AddTexture, texture);
 }
 
-void UpdateManager::RemoveTexture(Render::Texture* texture)
+void UpdateManager::RemoveTexture(const Render::TextureKey& texture)
 {
-  using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
+  using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
 
   // Reserve some memory inside the render queue
   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
@@ -1457,9 +1469,9 @@ void UpdateManager::RemoveTexture(Render::Texture* texture)
   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::RemoveTexture, texture);
 }
 
-void UpdateManager::UploadTexture(Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params)
+void UpdateManager::UploadTexture(const Render::TextureKey& texture, PixelDataPtr pixelData, const Texture::UploadParams& params)
 {
-  using DerivedType = MessageValue3<RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams>;
+  using DerivedType = MessageValue3<RenderManager, Render::TextureKey, PixelDataPtr, Texture::UploadParams>;
 
   // Reserve some memory inside the message queue
   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
@@ -1468,9 +1480,9 @@ void UpdateManager::UploadTexture(Render::Texture* texture, PixelDataPtr pixelDa
   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params);
 }
 
-void UpdateManager::GenerateMipmaps(Render::Texture* texture)
+void UpdateManager::GenerateMipmaps(const Render::TextureKey& texture)
 {
-  using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
+  using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
 
   // Reserve some memory inside the render queue
   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
@@ -1481,7 +1493,7 @@ void UpdateManager::GenerateMipmaps(Render::Texture* texture)
 
 void UpdateManager::AddFrameBuffer(OwnerPointer<Render::FrameBuffer>& frameBuffer)
 {
-  using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer> >;
+  using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer>>;
 
   // Reserve some memory inside the render queue
   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));