[Tizen] Keep reference when member callback excute 65/299865/1
authorEunki, Hong <eunkiki.hong@samsung.com>
Wed, 11 Oct 2023 08:04:44 +0000 (17:04 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Wed, 11 Oct 2023 08:04:44 +0000 (17:04 +0900)
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 <eunkiki.hong@samsung.com>
dali-scene3d/internal/controls/model/model-impl.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/npatch-data.cpp
dali-toolkit/internal/visuals/npatch-data.h
dali-toolkit/internal/visuals/npatch-loader.cpp
dali-toolkit/internal/visuals/npatch-loader.h
dali-toolkit/internal/visuals/svg/svg-visual.cpp

index 2763de6..1823476 100644 (file)
@@ -1068,6 +1068,8 @@ void Model::NotifyImageBasedLightScaleFactor(float scaleFactor)
 
 void Model::OnModelLoadComplete()
 {
+  IntrusivePtr<Model> 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()
index c68e1a4..4f093ad 100644 (file)
@@ -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());
index 5c0c474..72f058b 100644 (file)
@@ -19,6 +19,7 @@
 #include <dali-toolkit/internal/visuals/npatch-data.h>
 
 // INTERNAL HEADERS
+#include <dali-toolkit/internal/visuals/npatch-loader.h> ///< for NPatchLoader
 #include <dali-toolkit/internal/visuals/rendering-addon.h>
 
 // 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)
index 3df4b29..f50392b 100644 (file)
@@ -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<TextureUploadObserver*>;
 
-  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<int>                    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<int>                    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.
index 24d919a..340188b 100644 (file)
@@ -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<NPatchData> NPatchLoader::GetNPatchData(const VisualUrl& url, co
   // If this is new image loading, make new cache data
   if(infoPtr == nullptr)
   {
-    NPatchInfo info(std::make_shared<NPatchData>());
+    NPatchInfo info(std::make_shared<NPatchData>(*this));
     info.mData->SetId(GenerateUniqueNPatchDataId());
     info.mData->SetHash(hash);
     info.mData->SetUrl(url);
@@ -260,7 +273,7 @@ std::shared_ptr<NPatchData> 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<NPatchData>());
+    NPatchInfo info(std::make_shared<NPatchData>(*this));
 
     info.mData->SetId(GenerateUniqueNPatchDataId());
     info.mData->SetHash(hash);
index a55ab6f..59e52dc 100644 (file)
@@ -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()
index a5bb63d..60c2141 100644 (file)
@@ -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()