Delete Renderers before Shaders
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-manager.cpp
index abad331..879707b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
 //#define NODE_TREE_LOGGING 1
 
 #if(defined(DEBUG_ENABLED) && defined(NODE_TREE_LOGGING))
-#define SNAPSHOT_NODE_LOGGING                    \
-  const uint32_t FRAME_COUNT_TRIGGER = 16;       \
-  if(mImpl->frameCounter >= FRAME_COUNT_TRIGGER) \
-  {                                              \
-    for(auto&& scene : mImpl->scenes)
-{
-  if(scene && scene->root)
-  {
-    mImpl->frameCounter = 0;
-    PrintNodeTree(*scene->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "");
-  }
-}
-}
-mImpl->frameCounter++;
+#define SNAPSHOT_NODE_LOGGING                                                   \
+  const uint32_t FRAME_COUNT_TRIGGER = 16;                                      \
+  if(mImpl->frameCounter >= FRAME_COUNT_TRIGGER)                                \
+  {                                                                             \
+    for(auto&& scene : mImpl->scenes)                                           \
+    {                                                                           \
+      if(scene && scene->root)                                                  \
+      {                                                                         \
+        mImpl->frameCounter = 0;                                                \
+        PrintNodes(*scene->root, mSceneGraphBuffers.GetUpdateBufferIndex(), 0); \
+      }                                                                         \
+    }                                                                           \
+  }                                                                             \
+  mImpl->frameCounter++;
 #else
 #define SNAPSHOT_NODE_LOGGING
 #endif
@@ -228,6 +228,10 @@ struct UpdateManager::Impl
     scenes.clear();
 
     delete sceneController;
+
+    // Ensure to clear renderers
+    renderers.Clear();
+    shaders.Clear();
   }
 
   /**
@@ -268,6 +272,7 @@ struct UpdateManager::Impl
   OwnerContainer<PropertyOwner*> customObjects; ///< A container of owned objects (with custom properties)
 
   OwnerContainer<PropertyResetterBase*> propertyResetters;     ///< A container of property resetters
+  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
@@ -340,6 +345,8 @@ void UpdateManager::InstallRoot(OwnerPointer<Layer>& layer)
   rootLayer->CreateTransform(&mImpl->transformManager);
   rootLayer->SetRoot(true);
 
+  AddNodeResetter(*rootLayer);
+
   mImpl->scenes.emplace_back(new Impl::SceneInfo(rootLayer));
 }
 
@@ -384,6 +391,8 @@ void UpdateManager::ConnectNode(Node* parent, Node* node)
 
   parent->ConnectChild(node);
 
+  AddNodeResetter(*node);
+
   // Inform the frame-callback-processor, if set, about the node-hierarchy changing
   if(mImpl->frameCallbackProcessor)
   {
@@ -475,7 +484,11 @@ void UpdateManager::RemoveRenderTaskList(RenderTaskList* taskList)
 
 void UpdateManager::AddScene(OwnerPointer<Scene>& scene)
 {
-  mImpl->scenes.back()->scene = scene.Release();
+  auto& sceneInfo  = mImpl->scenes.back();
+  sceneInfo->scene = scene.Release();
+
+  // Set root to the Scene
+  sceneInfo->scene->SetRoot(sceneInfo->root);
 
   // Initialize the context from render manager
   typedef MessageValue1<RenderManager, SceneGraph::Scene*> DerivedType;
@@ -484,7 +497,7 @@ void UpdateManager::AddScene(OwnerPointer<Scene>& scene)
   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
 
   // Construct message in the render queue memory; note that delete should not be called on the return value
-  SceneGraph::Scene& sceneObject = *mImpl->scenes.back()->scene;
+  SceneGraph::Scene& sceneObject = *sceneInfo->scene;
   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::InitializeScene, &sceneObject);
 }
 
@@ -555,6 +568,13 @@ void UpdateManager::AddPropertyResetter(OwnerPointer<PropertyResetterBase>& prop
   mImpl->propertyResetters.PushBack(propertyResetter.Release());
 }
 
+void UpdateManager::AddNodeResetter(const Node& node)
+{
+  OwnerPointer<SceneGraph::NodeResetter> nodeResetter = SceneGraph::NodeResetter::New(node);
+  nodeResetter->Initialize();
+  mImpl->nodeResetters.PushBack(nodeResetter.Release());
+}
+
 void UpdateManager::AddPropertyNotification(OwnerPointer<PropertyNotification>& propertyNotification)
 {
   mImpl->propertyNotifications.PushBack(propertyNotification.Release());
@@ -659,19 +679,36 @@ void UpdateManager::ResetProperties(BufferIndex bufferIndex)
   // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
   mImpl->animationFinishedDuringUpdate = false;
 
+  // Reset node properties
+  std::vector<NodeResetter*> nodeResetterToDelete;
+  for(auto&& element : mImpl->nodeResetters)
+  {
+    element->ResetToBaseValue(bufferIndex);
+    if(element->IsFinished())
+    {
+      nodeResetterToDelete.push_back(element);
+    }
+  }
+
+  // If a node resetter is no longer required, delete it.
+  for(auto&& elementPtr : nodeResetterToDelete)
+  {
+    mImpl->nodeResetters.EraseObject(elementPtr);
+  }
+
   // Reset all animating / constrained properties
-  std::vector<PropertyResetterBase*> toDelete;
+  std::vector<PropertyResetterBase*> propertyResettertoDelete;
   for(auto&& element : mImpl->propertyResetters)
   {
     element->ResetToBaseValue(bufferIndex);
     if(element->IsFinished())
     {
-      toDelete.push_back(element);
+      propertyResettertoDelete.push_back(element);
     }
   }
 
-  // If a resetter is no longer required (the animator or constraint has been removed), delete it.
-  for(auto&& elementPtr : toDelete)
+  // If a property resetter is no longer required (the animator or constraint has been removed), delete it.
+  for(auto&& elementPtr : propertyResettertoDelete)
   {
     mImpl->propertyResetters.EraseObject(elementPtr);
   }
@@ -851,11 +888,23 @@ void UpdateManager::UpdateNodes(BufferIndex bufferIndex)
   }
 }
 
+void UpdateManager::UpdateLayers(BufferIndex bufferIndex)
+{
+  for(auto&& scene : mImpl->scenes)
+  {
+    if(scene && scene->root)
+    {
+      SceneGraph::UpdateLayerTree(*scene->root, bufferIndex);
+    }
+  }
+}
+
 uint32_t UpdateManager::Update(float    elapsedSeconds,
                                uint32_t lastVSyncTimeMilliseconds,
                                uint32_t nextVSyncTimeMilliseconds,
                                bool     renderToFboEnabled,
-                               bool     isRenderingToFbo)
+                               bool     isRenderingToFbo,
+                               bool     uploadOnly)
 {
   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
 
@@ -926,8 +975,7 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
       mImpl->frameCallbackProcessor->Update(bufferIndex, elapsedSeconds);
     }
 
-    //Update node hierarchy, apply constraints and perform sorting / culling.
-    //This will populate each Layer with a list of renderers which are ready.
+    //Update node hierarchy, apply constraints,
     UpdateNodes(bufferIndex);
 
     //Apply constraints to RenderTasks, shaders
@@ -943,6 +991,9 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
       mImpl->nodeDirtyFlags |= NodePropertyFlags::TRANSFORM;
     }
 
+    //Initialise layer renderable reuse
+    UpdateLayers(bufferIndex);
+
     //Process Property Notifications
     ProcessPropertyNotifications(bufferIndex);
 
@@ -1001,36 +1052,39 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
     }
   }
 
-  for(auto&& scene : mImpl->scenes)
+  if(!uploadOnly)
   {
-    if(scene && scene->root && scene->taskList)
+    for(auto&& scene : mImpl->scenes)
     {
-      RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
-
-      // check the countdown and notify
-      bool doRenderOnceNotify  = false;
-      mImpl->renderTaskWaiting = false;
-      for(auto&& renderTask : tasks)
+      if(scene && scene->root && scene->taskList)
       {
-        renderTask->UpdateState();
+        RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
 
-        if(renderTask->IsWaitingToRender() &&
-           renderTask->ReadyToRender(bufferIndex) /*avoid updating forever when source actor is off-stage*/)
+        // check the countdown and notify
+        bool doRenderOnceNotify  = false;
+        mImpl->renderTaskWaiting = false;
+        for(auto&& renderTask : tasks)
         {
-          mImpl->renderTaskWaiting = true; // keep update/render threads alive
+          renderTask->UpdateState();
+
+          if(renderTask->IsWaitingToRender() &&
+             renderTask->ReadyToRender(bufferIndex) /*avoid updating forever when source actor is off-stage*/)
+          {
+            mImpl->renderTaskWaiting = true; // keep update/render threads alive
+          }
+
+          if(renderTask->HasRendered())
+          {
+            doRenderOnceNotify = true;
+          }
         }
 
-        if(renderTask->HasRendered())
+        if(doRenderOnceNotify)
         {
-          doRenderOnceNotify = true;
+          DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
+          mImpl->notificationManager.QueueCompleteNotification(scene->taskList->GetCompleteNotificationInterface());
         }
       }
-
-      if(doRenderOnceNotify)
-      {
-        DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
-        mImpl->notificationManager.QueueCompleteNotification(scene->taskList->GetCompleteNotificationInterface());
-      }
     }
   }