From 00adb6e1d991b11db9645e7fa3448127ade8af21 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 6 Aug 2024 10:58:05 +0900 Subject: [PATCH] [Tizen] Ensure release some Texture/Geometry handles after adaptor stop 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 --- .../internal/common/image-resource-loader.cpp | 47 ++++++++++++++++-- .../internal/common/image-resource-loader.h | 12 +++++ .../model-components/model-primitive-impl.cpp | 2 +- .../public-api/loader/environment-definition.cpp | 56 ++++------------------ .../public-api/loader/environment-definition.h | 14 +----- dali-scene3d/public-api/loader/node-definition.cpp | 29 ++++++----- dali-scene3d/public-api/loader/node-definition.h | 5 +- .../devel-api/asset-manager/asset-manager.h | 5 +- dali-toolkit/devel-api/file.list | 6 +++ 9 files changed, 97 insertions(+), 79 deletions(-) diff --git a/dali-scene3d/internal/common/image-resource-loader.cpp b/dali-scene3d/internal/common/image-resource-loader.cpp index 98acb95..7b2f45f 100644 --- a/dali-scene3d/internal/common/image-resource-loader.cpp +++ b/dali-scene3d/internal/common/image-resource-loader.cpp @@ -19,6 +19,8 @@ #include // EXTERNAL INCLUDES +#include +#include #include #include #include @@ -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 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 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); diff --git a/dali-scene3d/internal/common/image-resource-loader.h b/dali-scene3d/internal/common/image-resource-loader.h index 3957009..b498b30 100644 --- a/dali-scene3d/internal/common/image-resource-loader.h +++ b/dali-scene3d/internal/common/image-resource-loader.h @@ -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 diff --git a/dali-scene3d/internal/model-components/model-primitive-impl.cpp b/dali-scene3d/internal/model-components/model-primitive-impl.cpp index 844f0b9..80f215e 100644 --- a/dali-scene3d/internal/model-components/model-primitive-impl.cpp +++ b/dali-scene3d/internal/model-components/model-primitive-impl.cpp @@ -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(); diff --git a/dali-scene3d/public-api/loader/environment-definition.cpp b/dali-scene3d/public-api/loader/environment-definition.cpp index 9c74f23..65a3271 100644 --- a/dali-scene3d/public-api/loader/environment-definition.cpp +++ b/dali-scene3d/public-api/loader/environment-definition.cpp @@ -30,40 +30,21 @@ 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 diff --git a/dali-scene3d/public-api/loader/environment-definition.h b/dali-scene3d/public-api/loader/environment-definition.h index 39aa53a..99931d7 100644 --- a/dali-scene3d/public-api/loader/environment-definition.h +++ b/dali-scene3d/public-api/loader/environment-definition.h @@ -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 diff --git a/dali-scene3d/public-api/loader/node-definition.cpp b/dali-scene3d/public-api/loader/node-definition.cpp index 013b4f3..48a222a 100644 --- a/dali-scene3d/public-api/loader/node-definition.cpp +++ b/dali-scene3d/public-api/loader/node-definition.cpp @@ -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) diff --git a/dali-scene3d/public-api/loader/node-definition.h b/dali-scene3d/public-api/loader/node-definition.h index c1cea09..729ca6e 100644 --- a/dali-scene3d/public-api/loader/node-definition.h +++ b/dali-scene3d/public-api/loader/node-definition.h @@ -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 diff --git a/dali-toolkit/devel-api/asset-manager/asset-manager.h b/dali-toolkit/devel-api/asset-manager/asset-manager.h index ecc56de..683e070 100644 --- a/dali-toolkit/devel-api/asset-manager/asset-manager.h +++ b/dali-toolkit/devel-api/asset-manager/asset-manager.h @@ -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 #include // 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: /** diff --git a/dali-toolkit/devel-api/file.list b/dali-toolkit/devel-api/file.list index 43d805b..f8a9d42 100755 --- a/dali-toolkit/devel-api/file.list +++ b/dali-toolkit/devel-api/file.list @@ -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} -- 2.7.4