[Tizen] Ensure release some Texture/Geometry handles after adaptor stop 28/315728/1
authorEunki, Hong <eunkiki.hong@samsung.com>
Tue, 6 Aug 2024 01:58:05 +0000 (10:58 +0900)
committerEunkiki Hong <eunkiki.hong@samsung.com>
Wed, 7 Aug 2024 06:20:20 +0000 (15:20 +0900)
Since off-screen application could be re-started without process terminate,
we should not keep some dali resources at static area.

Change-Id: Idee042f408e3cf7dd3b026b9f555ba9896cd270a
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
dali-scene3d/internal/common/image-resource-loader.cpp
dali-scene3d/internal/common/image-resource-loader.h
dali-scene3d/internal/model-components/model-primitive-impl.cpp
dali-scene3d/public-api/loader/environment-definition.cpp
dali-scene3d/public-api/loader/environment-definition.h
dali-scene3d/public-api/loader/node-definition.cpp
dali-scene3d/public-api/loader/node-definition.h
dali-toolkit/devel-api/asset-manager/asset-manager.h
dali-toolkit/devel-api/file.list

index 98acb95..7b2f45f 100644 (file)
@@ -19,6 +19,8 @@
 #include <dali-scene3d/internal/common/image-resource-loader.h>
 
 // EXTERNAL INCLUDES
+#include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
+#include <dali/devel-api/adaptor-framework/environment-variable.h>
 #include <dali/devel-api/adaptor-framework/image-loading.h>
 #include <dali/devel-api/adaptor-framework/lifecycle-controller.h>
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
@@ -48,6 +50,8 @@ namespace
 constexpr uint32_t MAXIMUM_COLLECTING_ITEM_COUNTS_PER_GC_CALL = 5u;
 constexpr uint32_t GC_PERIOD_MILLISECONDS                     = 1000u;
 
+constexpr std::string_view PRE_COMPUTED_BRDF_TEXTURE_FILE_NAME = "brdfLUT.png";
+
 #ifdef DEBUG_ENABLED
 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_IMAGE_RESOURCE_LOADER");
 #endif
@@ -516,8 +520,11 @@ private:
 };
 
 static std::shared_ptr<CacheImpl> gCacheImpl{nullptr};
-static Dali::Texture              gEmptyTextureWhiteRGB{};
-static Dali::Texture              gEmptyCubeTextureWhiteRGB{};
+
+// Static singletone instance what we usually used.
+static Dali::Texture gEmptyTextureWhiteRGB{};
+static Dali::Texture gEmptyCubeTextureWhiteRGB{};
+static Dali::Texture gDefaultBrdfTexture{};
 
 std::shared_ptr<CacheImpl> GetCacheImpl()
 {
@@ -535,6 +542,7 @@ void DestroyCacheImpl()
   // Remove texture object when application stopped.
   gEmptyTextureWhiteRGB.Reset();
   gEmptyCubeTextureWhiteRGB.Reset();
+  gDefaultBrdfTexture.Reset();
 }
 
 } // namespace
@@ -546,7 +554,7 @@ namespace ImageResourceLoader
 // Called by main thread..
 Dali::Texture GetEmptyTextureWhiteRGB()
 {
-  if(!gEmptyTextureWhiteRGB)
+  if(DALI_UNLIKELY(!gEmptyTextureWhiteRGB))
   {
     Dali::PixelData emptyPixelData = GetEmptyPixelDataWhiteRGB();
     gEmptyTextureWhiteRGB          = Texture::New(TextureType::TEXTURE_2D, emptyPixelData.GetPixelFormat(), emptyPixelData.GetWidth(), emptyPixelData.GetHeight());
@@ -557,7 +565,7 @@ Dali::Texture GetEmptyTextureWhiteRGB()
 
 Dali::Texture GetEmptyCubeTextureWhiteRGB()
 {
-  if(!gEmptyCubeTextureWhiteRGB)
+  if(DALI_UNLIKELY(!gEmptyCubeTextureWhiteRGB))
   {
     Dali::PixelData emptyPixelData = GetEmptyPixelDataWhiteRGB();
     gEmptyCubeTextureWhiteRGB      = Texture::New(TextureType::TEXTURE_CUBE, emptyPixelData.GetPixelFormat(), emptyPixelData.GetWidth(), emptyPixelData.GetHeight());
@@ -569,6 +577,17 @@ Dali::Texture GetEmptyCubeTextureWhiteRGB()
   return gEmptyCubeTextureWhiteRGB;
 }
 
+Dali::Texture GetDefaultBrdfTexture()
+{
+  if(DALI_UNLIKELY(!gDefaultBrdfTexture))
+  {
+    Dali::PixelData brdfPixelData = GetDefaultBrdfPixelData();
+    gDefaultBrdfTexture           = Texture::New(TextureType::TEXTURE_2D, brdfPixelData.GetPixelFormat(), brdfPixelData.GetWidth(), brdfPixelData.GetHeight());
+    gDefaultBrdfTexture.Upload(brdfPixelData, 0, 0, 0, 0, brdfPixelData.GetWidth(), brdfPixelData.GetHeight());
+  }
+  return gDefaultBrdfTexture;
+}
+
 Dali::Texture GetCachedTexture(Dali::PixelData pixelData, bool mipmapRequired)
 {
   if(Dali::Adaptor::IsAvailable() && SupportPixelDataCache(pixelData))
@@ -622,6 +641,26 @@ Dali::PixelData GetEmptyPixelDataZAxisAndAlphaRGBA()
   return emptyPixelData;
 }
 
+Dali::PixelData GetDefaultBrdfPixelData()
+{
+  static Dali::Mutex sPixelDataMutex;
+  {
+    Dali::Mutex::ScopedLock lock(sPixelDataMutex);
+
+    static Dali::PixelData defaultBrdfPixelData;
+
+    if(DALI_UNLIKELY(!defaultBrdfPixelData))
+    {
+      Devel::PixelBuffer pixelBuffer = Dali::LoadImageFromFile(Dali::Toolkit::AssetManager::GetDaliImagePath() + std::string(PRE_COMPUTED_BRDF_TEXTURE_FILE_NAME));
+      if(pixelBuffer)
+      {
+        defaultBrdfPixelData = Devel::PixelBuffer::Convert(pixelBuffer);
+      }
+    }
+    return defaultBrdfPixelData;
+  }
+}
+
 Dali::PixelData GetCachedPixelData(const std::string& url)
 {
   return GetCachedPixelData(url, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true);
index 3957009..b498b30 100644 (file)
@@ -54,6 +54,12 @@ Dali::Texture GetEmptyTextureWhiteRGB();
 Dali::Texture GetEmptyCubeTextureWhiteRGB();
 
 /**
+ * @brief Get default BRDF texture.
+ * @return A Texture object containing the default BRDF texture.
+ */
+Dali::Texture GetDefaultBrdfTexture();
+
+/**
  * @brief Get cached texture handle, or create new texture and upload.
  * @param[in] pixelData The PixelData of image to upload
  * @param[in] mipmapRequired True if this texture need to generate mipmap
@@ -99,6 +105,12 @@ Dali::PixelData GetEmptyPixelDataZAxisRGB();
 Dali::PixelData GetEmptyPixelDataZAxisAndAlphaRGBA();
 
 /**
+ * @brief Get cached pixelData handle with brdf pixel data has.
+ * @return A PixelData object containing brdf data.
+ */
+Dali::PixelData GetDefaultBrdfPixelData();
+
+/**
  * @brief Get cached image, or loads an image synchronously.
  * @note If cache handler is not created yet, or destroyed due to app terminated, it will load image synchronously without cache.
  * @param[in] url The URL of the image file to load
index 844f0b9..80f215e 100644 (file)
@@ -417,7 +417,7 @@ void ModelPrimitive::ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag
     }
     mTextureSet.SetTexture(textureCount++, mShadowMapTexture);
 
-    Texture brdfTexture = Scene3D::Loader::EnvironmentDefinition::GetBrdfTexture();
+    Texture brdfTexture = Dali::Scene3D::Internal::ImageResourceLoader::GetDefaultBrdfTexture();
     if(!mSpecularTexture || !mDiffuseTexture)
     {
       Texture iblTexture = Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyCubeTextureWhiteRGB();
index 9c74f23..65a3271 100644 (file)
 
 namespace
 {
-#define TOKEN_STRING(x) #x
-std::string GetDaliImagePath()
+static constexpr float DEFAULT_INTENSITY = 1.0f;
+
+/**
+ * @brief Request to load default brdf pixel data at worker thread.
+ */
+static void RequestLoadBrdfPixelData()
 {
-  return (nullptr == DALI_IMAGE_DIR) ? Dali::EnvironmentVariable::GetEnvironmentVariable(TOKEN_STRING(DALI_IMAGE_DIR)) : DALI_IMAGE_DIR;
+  /// GetDefaultBrdfPixelData() will load the brdf pixel data if we don't load it before.
+  [[maybe_unused]] auto ret = Dali::Scene3D::Internal::ImageResourceLoader::GetDefaultBrdfPixelData();
 }
 
-static constexpr float DEFAULT_INTENSITY = 1.0f;
-
 } // unnamed namespace
 
 namespace Dali::Scene3D::Loader
 {
-namespace
-{
-const char* PRE_COMPUTED_BRDF_TEXTURE_FILE_NAME = "brdfLUT.png";
-}
-PixelData EnvironmentDefinition::mBrdfPixelData;
-Texture   EnvironmentDefinition::mBrdfTexture;
-bool      EnvironmentDefinition::mIsBrdfLoaded = false;
-
-Dali::Texture EnvironmentDefinition::GetBrdfTexture()
-{
-  if(!mBrdfTexture)
-  {
-    if(!mIsBrdfLoaded)
-    {
-      LoadBrdfTexture();
-    }
-    mBrdfTexture = Texture::New(TextureType::TEXTURE_2D, mBrdfPixelData.GetPixelFormat(), mBrdfPixelData.GetWidth(), mBrdfPixelData.GetHeight());
-    mBrdfTexture.Upload(mBrdfPixelData);
-  }
-  return mBrdfTexture;
-}
-
 EnvironmentDefinition::RawData
 EnvironmentDefinition::LoadRaw(const std::string& environmentsPath)
 {
@@ -89,7 +70,7 @@ EnvironmentDefinition::LoadRaw(const std::string& environmentsPath)
 
   if(mUseBrdfTexture)
   {
-    LoadBrdfTexture();
+    RequestLoadBrdfPixelData();
   }
   return raw;
 }
@@ -113,7 +94,7 @@ EnvironmentDefinition::Textures EnvironmentDefinition::Load(RawData&& raw)
 
   if(mUseBrdfTexture)
   {
-    textures.mBrdf = GetBrdfTexture();
+    textures.mBrdf = Dali::Scene3D::Internal::ImageResourceLoader::GetDefaultBrdfTexture();
   }
   return textures;
 }
@@ -123,21 +104,4 @@ float EnvironmentDefinition::GetDefaultIntensity()
   return DEFAULT_INTENSITY;
 }
 
-void EnvironmentDefinition::LoadBrdfTexture()
-{
-  static Dali::Mutex mutex;
-  {
-    Mutex::ScopedLock lock(mutex);
-    if(!mIsBrdfLoaded)
-    {
-      Devel::PixelBuffer pixelBuffer = LoadImageFromFile(GetDaliImagePath() + PRE_COMPUTED_BRDF_TEXTURE_FILE_NAME);
-      if(pixelBuffer)
-      {
-        mBrdfPixelData = Devel::PixelBuffer::Convert(pixelBuffer);
-        mIsBrdfLoaded  = true;
-      }
-    }
-  }
-}
-
 } // namespace Dali::Scene3D::Loader
\ No newline at end of file
index 39aa53a..99931d7 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_ENVIRONMENT_DEFINITION_H
 #define DALI_SCENE3D_LOADER_ENVIRONMENT_DEFINITION_H
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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,8 +65,6 @@ struct DALI_SCENE3D_API EnvironmentDefinition
   EnvironmentDefinition(EnvironmentDefinition&&) = default;
   EnvironmentDefinition& operator=(EnvironmentDefinition&&) = default;
 
-  static Dali::Texture GetBrdfTexture();
-
   /**
    * @brief Loads raw pixel data for the given diffuse and specular maps.
    * @SINCE_2_0.7
@@ -90,11 +88,6 @@ struct DALI_SCENE3D_API EnvironmentDefinition
    */
   static float GetDefaultIntensity();
 
-private:
-  /// @cond internal
-  static void LoadBrdfTexture();
-  /// @endcond internal
-
 public: // DATA
   std::string              mDiffuseMapPath;
   std::string              mSpecularMapPath;
@@ -103,11 +96,6 @@ public: // DATA
   Vector3                  mYDirection      = Vector3::ONE;
   float                    mIblIntensity    = 1.0f;
   bool                     mUseBrdfTexture  = false;
-
-private:
-  static PixelData mBrdfPixelData;
-  static Texture   mBrdfTexture;
-  static bool      mIsBrdfLoaded;
 };
 
 } // namespace Dali::Scene3D::Loader
index 013b4f3..48a222a 100644 (file)
@@ -115,12 +115,18 @@ void NodeDefinition::Renderable::ReflectResources(IResourceReflector& reflector)
 
 void NodeDefinition::Renderable::OnCreate(const NodeDefinition& nodeDefinition, CreateParams& params, ModelNode& node) const
 {
+  // TODO : Need to keep this default geometry only 1 times per each adaptor.
+  Geometry defaultGeometry = Geometry::New();
+  CreateRenderer(nodeDefinition, params, defaultGeometry, node);
+}
+
+void NodeDefinition::Renderable::CreateRenderer(const NodeDefinition& nodeDefinition, CreateParams& params, Geometry& geometry, ModelNode& node) const
+{
   DALI_ASSERT_DEBUG(mShaderIdx != INVALID_INDEX);
   auto&  resources = params.mResources;
   Shader shader    = resources.mShaders[mShaderIdx].second;
 
-  static Geometry defaultGeometry = Geometry::New();
-  Renderer        renderer        = Renderer::New(defaultGeometry, shader);
+  Renderer renderer = Renderer::New(geometry, shader);
 
   RendererState::Apply(resources.mShaders[mShaderIdx].first.mRendererState, renderer);
 
@@ -257,7 +263,12 @@ void ModelRenderable::ReflectResources(IResourceReflector& reflector)
 void ModelRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinition::CreateParams& params, ModelNode& node) const
 {
   DALI_ASSERT_DEBUG(mMeshIdx != INVALID_INDEX);
+
+  auto& resources = params.mResources;
+  auto& mesh      = resources.mMeshes[mMeshIdx];
+
   ShaderOption::HashType shaderOptionHash{0u};
+  Renderer               renderer;
   if(mShaderIdx == INVALID_INDEX)
   {
     ShaderOption option = params.mShaderManager->ProduceShaderOption(params.mResources.mMaterials[mMaterialIdx].first,
@@ -265,8 +276,7 @@ void ModelRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinit
     shaderOptionHash    = option.GetOptionHash();
     Shader shader       = params.mShaderManager->ProduceShader(option);
 
-    static Geometry defaultGeometry = Geometry::New();
-    Renderer        renderer        = Renderer::New(defaultGeometry, shader);
+    renderer = Renderer::New(mesh.second.geometry, shader);
 
     RendererState::Apply(params.mShaderManager->GetRendererState(params.mResources.mMaterials[mMaterialIdx].first), renderer);
     Internal::GetImplementation(node).UpdateShader(params.mShaderManager);
@@ -274,16 +284,11 @@ void ModelRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinit
   }
   else
   {
-    Renderable::OnCreate(nodeDefinition, params, node);
+    Renderable::CreateRenderer(nodeDefinition, params, mesh.second.geometry, node);
+    DALI_ASSERT_ALWAYS(node.GetRendererCount() > 0u && "CreateRenderer failed!");
+    renderer = node.GetRendererAt(node.GetRendererCount() - 1u);
   }
 
-  auto& resources = params.mResources;
-  auto& mesh      = resources.mMeshes[mMeshIdx];
-
-  auto     renderer = node.GetRendererAt(node.GetRendererCount() - 1u);
-  Geometry geometry = mesh.second.geometry;
-  renderer.SetGeometry(geometry);
-
   TextureSet textures = resources.mMaterials[mMaterialIdx].second;
   // Set the blend shape texture.
   if(mesh.second.blendShapeGeometry)
index c1cea09..729ca6e 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_NODE_DEFINITION_H_
 #define DALI_SCENE3D_LOADER_NODE_DEFINITION_H_
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -180,6 +180,9 @@ public: // TYPES
     virtual void RegisterResources(IResourceReceiver& receiver) const;
     virtual void ReflectResources(IResourceReflector& reflector);
     virtual void OnCreate(const NodeDefinition& nodeDefinition, CreateParams& params, ModelNode& node) const;
+
+  protected:
+    void CreateRenderer(const NodeDefinition& nodeDefinition, CreateParams& params, Geometry& geometry, ModelNode& node) const;
   };
 
   struct CustomizationDefinition
index ecc56de..683e070 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_ASSET_MANAGER_DEVEL_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -19,6 +19,7 @@
  */
 
 // EXTERNAL INCLUDES
+#include <dali-toolkit/public-api/dali-toolkit-common.h>
 #include <string>
 
 // INTERNAL INCLUDES
@@ -30,7 +31,7 @@ namespace Toolkit
 /**
  * @brief Retrieves the file system path of the assets.
  */
-class AssetManager
+class DALI_TOOLKIT_API AssetManager
 {
 public:
   /**
index 43d805b..f8a9d42 100755 (executable)
@@ -100,6 +100,11 @@ SET( devel_api_accessibility-manager_header_files
   ${devel_api_src_dir}/accessibility-manager/accessibility-manager.h
 )
 
+SET( devel_api_asset-manager_header_files
+  ${devel_api_src_dir}/asset-manager/asset-manager.h
+)
+
+
 SET( devel_api_controls_header_files
   ${devel_api_src_dir}/controls/canvas-view/canvas-view.h
   ${devel_api_src_dir}/controls/control-accessible.h
@@ -311,6 +316,7 @@ SET( SOURCES ${SOURCES}
 SET( DEVEL_API_HEADERS ${DEVEL_API_HEADERS}
   ${devel_api_header_files}
   ${devel_api_accessibility-manager_header_files}
+  ${devel_api_asset-manager_header_files}
   ${devel_api_alignment_header_files}
   ${devel_api_controls_header_files}
   ${devel_api_bloom_view_header_files}