From: Eunki, Hong Date: Wed, 11 Oct 2023 08:04:44 +0000 (+0900) Subject: [Tizen] Keep reference when member callback excute X-Git-Tag: accepted/tizen/8.0/unified/20231103.040855~25 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F65%2F299865%2F1;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git [Tizen] Keep reference when member callback excute Some CallbackBase didn't hold the reference of itself. So it was possible to call destructor of itself during it's API was running. It might makes some unknown issues. So let we keep reference for some issue-comes known APIs. Change-Id: Ibeab31bc309869aa7c2ee65cbff8789e7bb2a721 Signed-off-by: Eunki, Hong --- diff --git a/dali-scene3d/internal/controls/model/model-impl.cpp b/dali-scene3d/internal/controls/model/model-impl.cpp index 2763de6..1823476 100644 --- a/dali-scene3d/internal/controls/model/model-impl.cpp +++ b/dali-scene3d/internal/controls/model/model-impl.cpp @@ -1068,6 +1068,8 @@ void Model::NotifyImageBasedLightScaleFactor(float scaleFactor) void Model::OnModelLoadComplete() { + IntrusivePtr self = this; // Keep reference until this API finished + if(!mModelLoadTask->HasSucceeded()) { ResetResourceTasks(); @@ -1105,8 +1107,8 @@ void Model::OnModelLoadComplete() Self().SetProperty(Dali::Actor::Property::ANCHOR_POINT, Vector3(mModelPivot.x, 1.0f - mModelPivot.y, mModelPivot.z)); mModelResourceReady = true; - NotifyResourceReady(); ResetResourceTask(mModelLoadTask); + NotifyResourceReady(); } void Model::OnIblDiffuseLoadComplete() diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp index c68e1a4..4f093ad 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp @@ -589,6 +589,8 @@ void AnimatedVectorImageVisual::OnDoActionExtension(const Property::Index action void AnimatedVectorImageVisual::OnResourceReady(VectorAnimationTask::ResourceStatus status) { + AnimatedVectorImageVisualPtr self = this; // Keep reference until this API finished + if(status == VectorAnimationTask::ResourceStatus::LOADED) { if(mImpl->mEventObserver) @@ -626,6 +628,8 @@ void AnimatedVectorImageVisual::OnResourceReady(VectorAnimationTask::ResourceSta void AnimatedVectorImageVisual::OnAnimationFinished() { + AnimatedVectorImageVisualPtr self = this; // Keep reference until this API finished + if(DALI_UNLIKELY(mImpl == nullptr)) { DALI_LOG_ERROR("Fatal error!! already destroyed object callback called! AnimatedVectorImageVisual : %p, url : %s\n", this, mUrl.GetUrl().c_str()); diff --git a/dali-toolkit/internal/visuals/npatch-data.cpp b/dali-toolkit/internal/visuals/npatch-data.cpp index 5c0c474..72f058b 100644 --- a/dali-toolkit/internal/visuals/npatch-data.cpp +++ b/dali-toolkit/internal/visuals/npatch-data.cpp @@ -19,6 +19,7 @@ #include // INTERNAL HEADERS +#include ///< for NPatchLoader #include // EXTERNAL HEADERS @@ -30,8 +31,9 @@ namespace Toolkit { namespace Internal { -NPatchData::NPatchData() +NPatchData::NPatchData(NPatchLoader& loader) : mId(INVALID_NPATCH_DATA_ID), + mNPatchLoader(loader), mUrl(), mTextureSet(), mHash(0), @@ -257,6 +259,9 @@ void NPatchData::NotifyObserver(TextureUploadObserver* observer, const bool& loa void NPatchData::LoadComplete(bool loadSuccess, TextureInformation textureInformation) { + // Increase reference count of itself + mNPatchLoader.IncreaseReference(mId); + if(loadSuccess) { if(mLoadingState != LoadingState::LOAD_COMPLETE) @@ -300,6 +305,9 @@ void NPatchData::LoadComplete(bool loadSuccess, TextureInformation textureInform // (If mLoadingState was LOAD_COMPLETE, NotifyObserver will be called directly. @todo : Should we fix this logic, matched with texture manager?) // So LoadComplete will be called. mObserverList.Swap(mQueuedObservers); + + // Decrease reference count of itself + mNPatchLoader.RequestRemove(mId, nullptr); } void NPatchData::ObserverDestroyed(TextureUploadObserver* observer) diff --git a/dali-toolkit/internal/visuals/npatch-data.h b/dali-toolkit/internal/visuals/npatch-data.h index 3df4b29..f50392b 100644 --- a/dali-toolkit/internal/visuals/npatch-data.h +++ b/dali-toolkit/internal/visuals/npatch-data.h @@ -33,6 +33,8 @@ namespace Toolkit { namespace Internal { +class NPatchLoader; + class NPatchData : public ConnectionTracker, public Dali::Toolkit::TextureUploadObserver { public: @@ -53,8 +55,10 @@ public: public: /** * Constructor + * + * @param[in] loader NPatchLoader who create this data. */ - NPatchData(); + NPatchData(NPatchLoader& loader); /** * Destructor, non-virtual as not a base class @@ -279,19 +283,21 @@ private: private: using ObserverListType = Dali::Vector; - NPatchDataId mId; - ObserverListType mObserverList; ///< Container used to store all observer clients of this Texture - ObserverListType mQueuedObservers; ///< Container observers when user try to add during notify observers - VisualUrl mUrl; ///< Url of the N-Patch - TextureSet mTextureSet; ///< Texture containing the cropped image - NPatchUtility::StretchRanges mStretchPixelsX; ///< X stretch pixels - NPatchUtility::StretchRanges mStretchPixelsY; ///< Y stretch pixels - std::size_t mHash; ///< Hash code for the Url - uint32_t mCroppedWidth; ///< Width of the cropped middle part of N-patch - uint32_t mCroppedHeight; ///< Height of the cropped middle part of N-patch - Rect mBorder; ///< The size of the border - LoadingState mLoadingState; ///< True if the data loading is completed - void* mRenderingMap; ///< NPatch rendering data + NPatchDataId mId; + ObserverListType mObserverList; ///< Container used to store all observer clients of this Texture + ObserverListType mQueuedObservers; ///< Container observers when user try to add during notify observers + NPatchLoader& mNPatchLoader; ///< NPatchLoader who keep this data + + VisualUrl mUrl; ///< Url of the N-Patch + TextureSet mTextureSet; ///< Texture containing the cropped image + NPatchUtility::StretchRanges mStretchPixelsX; ///< X stretch pixels + NPatchUtility::StretchRanges mStretchPixelsY; ///< Y stretch pixels + std::size_t mHash; ///< Hash code for the Url + uint32_t mCroppedWidth; ///< Width of the cropped middle part of N-patch + uint32_t mCroppedHeight; ///< Height of the cropped middle part of N-patch + Rect mBorder; ///< The size of the border + LoadingState mLoadingState; ///< True if the data loading is completed + void* mRenderingMap; ///< NPatch rendering data bool mPreMultiplyOnLoad : 1; ///< Whether to multiply alpha into color channels on load bool mObserverNotifying : 1; ///< Whether this NPatchData notifying observers or not. diff --git a/dali-toolkit/internal/visuals/npatch-loader.cpp b/dali-toolkit/internal/visuals/npatch-loader.cpp index 24d919a..340188b 100644 --- a/dali-toolkit/internal/visuals/npatch-loader.cpp +++ b/dali-toolkit/internal/visuals/npatch-loader.cpp @@ -162,6 +162,19 @@ void NPatchLoader::RequestRemove(NPatchData::NPatchDataId id, TextureUploadObser } } +void NPatchLoader::IncreaseReference(NPatchData::NPatchDataId id) +{ + int32_t cacheIndex = GetCacheIndexFromId(id); + if(cacheIndex == INVALID_CACHE_INDEX) + { + return; + } + + NPatchInfo& info(mCache[cacheIndex]); + + ++info.mReferenceCount; +} + void NPatchLoader::Remove(NPatchData::NPatchDataId id, TextureUploadObserver* textureObserver) { int32_t cacheIndex = GetCacheIndexFromId(id); @@ -247,7 +260,7 @@ std::shared_ptr NPatchLoader::GetNPatchData(const VisualUrl& url, co // If this is new image loading, make new cache data if(infoPtr == nullptr) { - NPatchInfo info(std::make_shared()); + NPatchInfo info(std::make_shared(*this)); info.mData->SetId(GenerateUniqueNPatchDataId()); info.mData->SetHash(hash); info.mData->SetUrl(url); @@ -260,7 +273,7 @@ std::shared_ptr NPatchLoader::GetNPatchData(const VisualUrl& url, co // Else if LOAD_COMPLETE, Same url but border is different - use the existing texture else if(infoPtr->mData->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE) { - NPatchInfo info(std::make_shared()); + NPatchInfo info(std::make_shared(*this)); info.mData->SetId(GenerateUniqueNPatchDataId()); info.mData->SetHash(hash); diff --git a/dali-toolkit/internal/visuals/npatch-loader.h b/dali-toolkit/internal/visuals/npatch-loader.h index a55ab6f..59e52dc 100644 --- a/dali-toolkit/internal/visuals/npatch-loader.h +++ b/dali-toolkit/internal/visuals/npatch-loader.h @@ -90,6 +90,13 @@ public: */ void RequestRemove(NPatchData::NPatchDataId id, TextureUploadObserver* textureObserver); + /** + * @brief Increase reference count of a texture matching id. + * + * @param [in] id cache data id + */ + void IncreaseReference(NPatchData::NPatchDataId id); + protected: // Implementation of Processor /** * @copydoc Dali::Integration::Processor::Process() diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.cpp b/dali-toolkit/internal/visuals/svg/svg-visual.cpp index a5bb63d..60c2141 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-visual.cpp @@ -337,11 +337,24 @@ void SvgVisual::AddRasterizationTask(const Vector2& size) void SvgVisual::ApplyRasterizedImage(SvgTaskPtr task) { + SvgVisualPtr self = this; // Keep reference until this API finished + if(DALI_UNLIKELY(mImpl == nullptr)) { DALI_LOG_ERROR("Fatal error!! already destroyed object callback called! SvgVisual : %p, url : %s, task : %p\n", this, mImageUrl.GetUrl().c_str(), task.Get()); return; } + + // We don't need to keep tasks anymore. reset now. + if(task == mLoadingTask) + { + mLoadingTask.Reset(); + } + if(task == mRasterizingTask) + { + mRasterizingTask.Reset(); + } + if(task->HasSucceeded()) { PixelData rasterizedPixelData = task->GetPixelData(); @@ -433,16 +446,6 @@ void SvgVisual::ApplyRasterizedImage(SvgTaskPtr task) ResourceReady(Toolkit::Visual::ResourceStatus::FAILED); } - - // We don't need to keep tasks anymore. reset now. - if(task == mLoadingTask) - { - mLoadingTask.Reset(); - } - if(task == mRasterizingTask) - { - mRasterizingTask.Reset(); - } } void SvgVisual::OnSetTransform()