From: Eunki Hong Date: Wed, 29 Nov 2023 14:02:08 +0000 (+0900) Subject: [Tizen] (Scene3D) Ensure remove image-resource-loader cache when app terminated X-Git-Tag: accepted/tizen/8.0/unified/20231214.075334~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=37ed78450ca0b76ad3bf7dd94e190aaf9a322e26;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git [Tizen] (Scene3D) Ensure remove image-resource-loader cache when app terminated Since ImageResourceLoader use static global value internally, it might have some problem when we use OffscreenApplication multiple time. Since even Dali::Application destroyed, the static value can be alived. At this time, If we create new Dali::Application one more time, the cache system break down. To ensure we follow up the cache system, let we connect the signal to LifecycleController, and then delete self. It will ensure we can re-create this cache after Dali::Application recreated. Change-Id: I6178a91dfff2a435eb95d11e7ca8ef7479c125ed Signed-off-by: Eunki Hong --- diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-lifecycle-controller.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-lifecycle-controller.cpp index 1e29a1c..e05f9f7 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-lifecycle-controller.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-lifecycle-controller.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 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. @@ -23,7 +23,6 @@ namespace Dali { - /******************************************************************************** * Stub for Dali::Internal::Adaptor::LifecycleController ********************************************************************************/ @@ -34,18 +33,18 @@ namespace Adaptor class LifecycleController : public BaseObject { public: // Creation & Destruction - LifecycleController(); ~LifecycleController(); static Dali::LifecycleController Get(); - public: // Signals Dali::LifecycleController::LifecycleSignalType& InitSignal(); + Dali::LifecycleController::LifecycleSignalType& TerminateSignal(); private: Dali::LifecycleController::LifecycleSignalType mInitSignal; - static Dali::LifecycleController mLifecycleController; + Dali::LifecycleController::LifecycleSignalType mTerminateSignal; + static Dali::LifecycleController mLifecycleController; }; Dali::LifecycleController LifecycleController::mLifecycleController; @@ -60,7 +59,7 @@ LifecycleController::~LifecycleController() Dali::LifecycleController LifecycleController::Get() { - if( ! mLifecycleController ) + if(!mLifecycleController) { mLifecycleController = Dali::LifecycleController(new Internal::Adaptor::LifecycleController()); } @@ -72,16 +71,24 @@ Dali::LifecycleController::LifecycleSignalType& LifecycleController::InitSignal( return mInitSignal; } +Dali::LifecycleController::LifecycleSignalType& LifecycleController::TerminateSignal() +{ + return mTerminateSignal; +} + } // namespace Adaptor } // namespace Internal - /******************************************************************************** * Stub for Dali::LifecycleController ********************************************************************************/ -LifecycleController::LifecycleController(){} -LifecycleController::~LifecycleController(){} +LifecycleController::LifecycleController() +{ +} +LifecycleController::~LifecycleController() +{ +} LifecycleController LifecycleController::Get() { @@ -92,12 +99,19 @@ LifecycleController LifecycleController::Get() LifecycleController::LifecycleSignalType& LifecycleController::InitSignal() { - BaseObject& object = GetBaseObject(); - Internal::Adaptor::LifecycleController& controller = static_cast< Internal::Adaptor::LifecycleController& >( object ); + BaseObject& object = GetBaseObject(); + Internal::Adaptor::LifecycleController& controller = static_cast(object); return controller.InitSignal(); } -LifecycleController::LifecycleController( Internal::Adaptor::LifecycleController *impl ) +LifecycleController::LifecycleSignalType& LifecycleController::TerminateSignal() +{ + BaseObject& object = GetBaseObject(); + Internal::Adaptor::LifecycleController& controller = static_cast(object); + return controller.TerminateSignal(); +} + +LifecycleController::LifecycleController(Internal::Adaptor::LifecycleController* impl) : BaseHandle(impl) { } diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-lifecycle-controller.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-lifecycle-controller.h index 3069b15..ec3c64ec 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-lifecycle-controller.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-lifecycle-controller.h @@ -2,7 +2,7 @@ #define TOOLKIT_LIFECYCLE_CONTROLLER_H /* - * Copyright (c) 2019 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. @@ -19,9 +19,9 @@ */ // EXTERNAL INCLUDES -#include #include #include +#include namespace Dali { @@ -31,20 +31,20 @@ namespace Adaptor { class LifecycleController; } -} +} // namespace Internal class LifecycleController : public BaseHandle { public: - typedef Signal< void (void) > LifecycleSignalType; + typedef Signal LifecycleSignalType; LifecycleController(); ~LifecycleController(); static LifecycleController Get(); - LifecycleSignalType& InitSignal(); - LifecycleController( Internal::Adaptor::LifecycleController* impl ); + LifecycleSignalType& InitSignal(); + LifecycleSignalType& TerminateSignal(); + LifecycleController(Internal::Adaptor::LifecycleController* impl); }; - } // namespace Dali #endif // TOOLKIT_LIFECYCLE_CONTROLLER_H diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-test-application.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-test-application.cpp index ac967f8..840cc13 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-test-application.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-test-application.cpp @@ -42,7 +42,7 @@ ToolkitTestApplication::ToolkitTestApplication(size_t surfaceWidth, size_t surfa // Override Scene creation in TestApplication by creating a window. // The window will create a Scene & surface and set up the scene's surface appropriately. mMainWindow = Window::New(PositionSize(0, 0, surfaceWidth, surfaceHeight), ""); - mScene = AdaptorImpl::GetScene(mMainWindow); + mScene = AdaptorImpl::GetScene(mMainWindow); mScene.SetDpi(Vector2(horizontalDpi, verticalDpi)); // Create render target for the scene @@ -73,6 +73,9 @@ ToolkitTestApplication::ToolkitTestApplication(size_t surfaceWidth, size_t surfa ToolkitTestApplication::~ToolkitTestApplication() { + Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get(); + lifecycleController.TerminateSignal().Emit(); + // Need to delete core before we delete the adaptor. delete mCore; mCore = NULL; diff --git a/dali-scene3d/internal/common/image-resource-loader.cpp b/dali-scene3d/internal/common/image-resource-loader.cpp index 7677e30..f5d15c5 100644 --- a/dali-scene3d/internal/common/image-resource-loader.cpp +++ b/dali-scene3d/internal/common/image-resource-loader.cpp @@ -20,6 +20,7 @@ // EXTERNAL INCLUDES #include +#include #include #include #include @@ -31,6 +32,7 @@ #include #include ///< for std::function +#include ///< for std::shared_ptr #include #include #include ///< for std::pair @@ -172,6 +174,10 @@ Dali::Texture CreateCubeTextureFromPixelDataList(const std::vector(mCubeTextureCache, fullCollect, mCubeTextureContainerUpdated, mLatestCollectedCubeTextureIter, checkedCount); + // Try to collect Texture GC first, due to the reference count of pixelData who become key of textures. + // After all texture GC finished, then check PixelData cache. + uint32_t checkedCount = 0u; - // GC Texture - continueTimer |= CollectGarbages(mTextureCache, fullCollect, mTextureContainerUpdated, mLatestCollectedTextureIter, checkedCount); + // GC Cube Texture + continueTimer |= CollectGarbages(mCubeTextureCache, fullCollect, mCubeTextureContainerUpdated, mLatestCollectedCubeTextureIter, checkedCount); - // GC PixelData. We should lock mutex during GC pixelData. - continueTimer |= CollectGarbages(mPixelDataCache, fullCollect, mPixelDataContainerUpdated, mLatestCollectedPixelDataIter, checkedCount); - } + // GC Texture + continueTimer |= CollectGarbages(mTextureCache, fullCollect, mTextureContainerUpdated, mLatestCollectedTextureIter, checkedCount); + + // GC PixelData. We should lock mutex during GC pixelData. + continueTimer |= CollectGarbages(mPixelDataCache, fullCollect, mPixelDataContainerUpdated, mLatestCollectedPixelDataIter, checkedCount); return continueTimer; } @@ -496,12 +505,22 @@ private: bool mFullCollectRequested : 1; }; -CacheImpl& GetCacheImpl() +static std::shared_ptr gCacheImpl{nullptr}; + +std::shared_ptr GetCacheImpl() { - static CacheImpl gCacheImpl; + if(DALI_UNLIKELY(!gCacheImpl)) + { + gCacheImpl = std::make_shared(); + } return gCacheImpl; } +void DestroyCacheImpl() +{ + gCacheImpl.reset(); +} + } // namespace namespace Dali::Scene3D::Internal @@ -529,17 +548,22 @@ Dali::Texture GetEmptyTextureWhiteRGB() Dali::Texture GetCachedTexture(Dali::PixelData pixelData, bool mipmapRequired) { - return GetCacheImpl().GetOrCreateCachedTexture(pixelData, mipmapRequired); + return GetCacheImpl()->GetOrCreateCachedTexture(pixelData, mipmapRequired); } Dali::Texture GetCachedCubeTexture(const std::vector>& pixelDataList, bool mipmapRequired) { - return GetCacheImpl().GetOrCreateCachedCubeTexture(pixelDataList, mipmapRequired); + return GetCacheImpl()->GetOrCreateCachedCubeTexture(pixelDataList, mipmapRequired); } void RequestGarbageCollect(bool fullCollect) { - GetCacheImpl().RequestGarbageCollect(fullCollect); + GetCacheImpl()->RequestGarbageCollect(fullCollect); +} + +void EnsureResourceLoaderCreated() +{ + GetCacheImpl(); } // Can be called by worker thread. @@ -555,7 +579,15 @@ Dali::PixelData GetCachedPixelData(const std::string& url, bool orientationCorrection) { ImageInformation info(url, dimensions, fittingMode, samplingMode, orientationCorrection); - return GetCacheImpl().GetOrCreateCachedPixelData(info); + if(gCacheImpl == nullptr) + { + DALI_LOG_INFO(gLogFilter, Debug::Verbose, "CacheImpl not prepared! load PixelData without cache.\n"); + return CreatePixelDataFromImageInfo(info, false); + } + else + { + return GetCacheImpl()->GetOrCreateCachedPixelData(info); + } } } // namespace ImageResourceLoader } // namespace Dali::Scene3D::Internal diff --git a/dali-scene3d/internal/common/image-resource-loader.h b/dali-scene3d/internal/common/image-resource-loader.h index a7f10d4..ee6d048 100644 --- a/dali-scene3d/internal/common/image-resource-loader.h +++ b/dali-scene3d/internal/common/image-resource-loader.h @@ -41,13 +41,6 @@ namespace Internal namespace ImageResourceLoader { // Called by main thread. - -/** - * @brief Get cached pixelData handle filled as white with RGB888 format. - * @return A PixelData object containing the white RGB888 color. - */ -Dali::PixelData GetEmptyPixelDataWhiteRGB(); - /** * @brief Get cached texture handle filled as white with RGB888 format. * @return A Texture object containing the white RGB888 color. @@ -77,10 +70,21 @@ Dali::Texture GetCachedCubeTexture(const std::vector