Fix surface deletion order issue 49/288749/2
authorHeeyong Song <heeyong.song@samsung.com>
Wed, 22 Feb 2023 08:37:31 +0000 (17:37 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Wed, 22 Feb 2023 23:22:46 +0000 (08:22 +0900)
Change-Id: I1fb3a2934ed6a36553421f002d6cc7821abc45dc

dali/integration-api/scene.cpp
dali/integration-api/scene.h
dali/internal/event/common/scene-impl.cpp
dali/internal/event/common/scene-impl.h
dali/internal/render/common/render-manager.cpp
dali/internal/update/common/scene-graph-scene.h
dali/internal/update/manager/update-manager.cpp

index 5eedf5c..a836ad8 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.
@@ -128,6 +128,11 @@ void Scene::SurfaceReplaced()
   GetImplementation(*this).SurfaceReplaced();
 }
 
+void Scene::RemoveSceneObject()
+{
+  GetImplementation(*this).RemoveSceneObject();
+}
+
 void Scene::Discard()
 {
   GetImplementation(*this).Discard();
index 51a8572..a54b0dd 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_SCENE_H
 
 /*
- * 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.
@@ -245,6 +245,11 @@ public:
   void SurfaceReplaced();
 
   /**
+   * @brief Removes the scene graph object.
+   */
+  void RemoveSceneObject();
+
+  /**
    * @brief Discards this Scene from the Core.
    */
   void Discard();
index 56ed507..d60e48b 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.
@@ -65,12 +65,6 @@ Scene::Scene()
 
 Scene::~Scene()
 {
-  if(EventThreadServices::IsCoreRunning() && mSceneObject)
-  {
-    ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
-    RemoveSceneMessage(tls->GetUpdateManager(), *mSceneObject);
-  }
-
   if(mDefaultCamera)
   {
     // its enough to release the handle so the object is released
@@ -241,9 +235,19 @@ void Scene::SurfaceReplaced()
   }
 }
 
+void Scene::RemoveSceneObject()
+{
+  if(EventThreadServices::IsCoreRunning() && mSceneObject)
+  {
+    ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
+    RemoveSceneMessage(tls->GetUpdateManager(), *mSceneObject);
+    mSceneObject = nullptr;
+  }
+}
+
 void Scene::Discard()
 {
-  if(ThreadLocalStorage::Created())
+  if(EventThreadServices::IsCoreRunning())
   {
     ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
     tls->RemoveScene(this);
@@ -310,22 +314,23 @@ void Scene::SurfaceRotated(float width, float height, int32_t windowOrientation,
 
 int32_t Scene::GetCurrentSurfaceOrientation() const
 {
-  return mSceneObject->GetSurfaceOrientation();
+  return mSceneObject ? mSceneObject->GetSurfaceOrientation() : 0;
 }
 
 int32_t Scene::GetCurrentScreenOrientation() const
 {
-  return mSceneObject->GetScreenOrientation();
+  return mSceneObject ? mSceneObject->GetScreenOrientation() : 0;
 }
 
 const Rect<int32_t>& Scene::GetCurrentSurfaceRect() const
 {
-  return mSceneObject->GetSurfaceRect();
+  static Rect<int32_t> emptyRect{};
+  return mSceneObject ? mSceneObject->GetSurfaceRect() : emptyRect;
 }
 
 void Scene::ChangedSurface(float width, float height, int32_t windowOrientation, int32_t screenOrientation)
 {
-  bool changedOrientation = false;
+  bool          changedOrientation = false;
   Rect<int32_t> newSize(0, 0, static_cast<int32_t>(width), static_cast<int32_t>(height)); // truncated
   mSize.width  = width;
   mSize.height = height;
@@ -336,7 +341,7 @@ void Scene::ChangedSurface(float width, float height, int32_t windowOrientation,
   }
 
   mSurfaceOrientation = windowOrientation;
-  mScreenOrientation = screenOrientation;
+  mScreenOrientation  = screenOrientation;
 
   // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
   mDefaultCamera->SetPerspectiveProjection(mSize);
@@ -372,12 +377,12 @@ void Scene::ChangedSurface(float width, float height, int32_t windowOrientation,
 
 bool Scene::IsSurfaceRectChanged() const
 {
-  return mSceneObject->IsSurfaceRectChanged();
+  return mSceneObject ? mSceneObject->IsSurfaceRectChanged() : false;
 }
 
 bool Scene::IsRotationCompletedAcknowledgementSet() const
 {
-  return mSceneObject->IsRotationCompletedAcknowledgementSet();
+  return mSceneObject ? mSceneObject->IsRotationCompletedAcknowledgementSet() : false;
 }
 
 void Scene::SetRotationCompletedAcknowledgement()
@@ -455,12 +460,18 @@ void Scene::AddFramePresentedCallback(std::unique_ptr<CallbackBase> callback, in
 
 void Scene::GetFrameRenderedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks)
 {
-  mSceneObject->GetFrameRenderedCallback(callbacks);
+  if(mSceneObject)
+  {
+    mSceneObject->GetFrameRenderedCallback(callbacks);
+  }
 }
 
 void Scene::GetFramePresentedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks)
 {
-  mSceneObject->GetFramePresentedCallback(callbacks);
+  if(mSceneObject)
+  {
+    mSceneObject->GetFramePresentedCallback(callbacks);
+  }
 }
 
 Integration::Scene::KeyEventSignalType& Scene::KeyEventSignal()
index cda29a2..c431fee 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_H
 
 /*
- * 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.
@@ -133,6 +133,11 @@ public:
   void SurfaceReplaced();
 
   /**
+   * @copydoc Dali::Integration::Scene::RemoveSceneObject
+   */
+  void RemoveSceneObject();
+
+  /**
    * @copydoc Dali::Integration::Scene::Discard
    */
   void Discard();
index 3a1466d..4464e83 100644 (file)
@@ -480,7 +480,7 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector<Rect<int>>&
   Internal::Scene&   sceneInternal = GetImplementation(scene);
   SceneGraph::Scene* sceneObject   = sceneInternal.GetSceneObject();
 
-  if(sceneObject->IsRenderingSkipped())
+  if(!sceneObject || sceneObject->IsRenderingSkipped())
   {
     // We don't need to calculate dirty rects
     return;
@@ -713,9 +713,13 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector<Rect<int>>&
 
 void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::Scene& scene, bool renderToFbo)
 {
-  SceneGraph::Scene* sceneObject  = GetImplementation(scene).GetSceneObject();
-  Rect<int>          clippingRect = sceneObject->GetSurfaceRect();
+  SceneGraph::Scene* sceneObject = GetImplementation(scene).GetSceneObject();
+  if(!sceneObject)
+  {
+    return;
+  }
 
+  Rect<int> clippingRect = sceneObject->GetSurfaceRect();
   RenderScene(status, scene, renderToFbo, clippingRect);
 }
 
@@ -734,6 +738,10 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
 
   Internal::Scene&   sceneInternal = GetImplementation(scene);
   SceneGraph::Scene* sceneObject   = sceneInternal.GetSceneObject();
+  if(!sceneObject)
+  {
+    return;
+  }
 
   uint32_t count = sceneObject->GetRenderInstructions().Count(mImpl->renderBufferIndex);
 
index d004f16..88e93dd 100644 (file)
@@ -250,6 +250,14 @@ public:
   }
 
   /**
+   * Remove the render target of the surface
+   */
+  void RemoveSurfaceRenderTarget()
+  {
+    mRenderTarget.reset();
+  }
+
+  /**
    * Get the graphics render pass created for the scene
    *
    * @return the graphics render pass
index 184573b..e8f2867 100644 (file)
@@ -146,11 +146,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
@@ -350,8 +350,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);
@@ -549,6 +548,8 @@ void UpdateManager::RemoveScene(Scene* scene)
   // Construct message in the render queue memory; note that delete should not be called on the return value
   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::UninitializeScene, scene);
 
+  scene->RemoveSurfaceRenderTarget();
+
   for(auto&& sceneInfo : mImpl->scenes)
   {
     if(sceneInfo && sceneInfo->scene && sceneInfo->scene.Get() == scene)
@@ -1248,8 +1249,7 @@ void UpdateManager::SetDepthIndices(OwnerPointer<NodeDepths>& nodeDepths)
     {
       // 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(); });
+      std::sort(container.Begin(), container.End(), [](Node* a, Node* b) { return a->GetDepthIndex() < b->GetDepthIndex(); });
     }
   }
 }