Keep reference when member callback excute + Make NPatchData as RefObject 68/299868/2
authorEunki, Hong <eunkiki.hong@samsung.com>
Wed, 11 Oct 2023 08:04:44 +0000 (17:04 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Thu, 12 Oct 2023 02:11:08 +0000 (11:11 +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 : SvgVisual, NPatchData, and lottie

It future, we should discard visuals rather than delate it directly.

Change-Id: Ibeab31bc309869aa7c2ee65cbff8789e7bb2a721
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
13 files changed:
dali-scene3d/internal/controls/model/model-impl.cpp
dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp
dali-toolkit/devel-api/utility/npatch-helper.cpp
dali-toolkit/devel-api/utility/npatch-helper.h
dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.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/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.cpp
dali-toolkit/internal/visuals/visual-factory-cache.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 d630b24..75c9b51 100644 (file)
@@ -160,123 +160,122 @@ void SetShadowLightConstraint(Dali::CameraActor selectedCamera, Dali::CameraActo
   shadowLightCamera.RemoveConstraints();
 
   // Compute ViewProjectionMatrix and store it to "tempViewProjectionMatrix" property
-  auto       tempViewProjectionMatrixIndex  = shadowLightCamera.RegisterProperty("tempViewProjectionMatrix", Matrix::IDENTITY);
-  Constraint projectionMatrixConstraint = Constraint::New<Matrix>(shadowLightCamera, tempViewProjectionMatrixIndex, [](Matrix& output, const PropertyInputContainer& inputs)
-                                                                  {
-                                                                    Matrix worldMatrix = inputs[0]->GetMatrix();
-                                                                    float tangentFov_2 = tanf(inputs[4]->GetFloat());
-                                                                    float  nearDistance = inputs[5]->GetFloat();
-                                                                    float  farDistance  = inputs[6]->GetFloat();
-                                                                    float  aspectRatio  = inputs[7]->GetFloat();
-                                                                    float  nearY        = 0.0f;
-                                                                    float  nearX        = 0.0f;
-                                                                    float  farY         = 0.0f;
-                                                                    float  farX         = 0.0f;
-                                                                    if(inputs[1]->GetInteger() == Dali::Camera::ProjectionMode::PERSPECTIVE_PROJECTION)
-                                                                    {
-                                                                      if(inputs[2]->GetInteger() == Dali::DevelCameraActor::ProjectionDirection::VERTICAL)
-                                                                      {
-                                                                        nearY = tangentFov_2 * nearDistance;
-                                                                        nearX = nearY * aspectRatio;
-                                                                        farY  = tangentFov_2 * farDistance;
-                                                                        farX  = farY * aspectRatio;
-                                                                      }
-                                                                      else
-                                                                      {
-                                                                        nearX = tangentFov_2 * nearDistance;
-                                                                        nearY = nearX / aspectRatio;
-                                                                        farX  = tangentFov_2 * farDistance;
-                                                                        farY  = farX / aspectRatio;
-                                                                      }
-                                                                    }
-                                                                    else
-                                                                    {
-                                                                      if(inputs[2]->GetInteger() == Dali::DevelCameraActor::ProjectionDirection::VERTICAL)
-                                                                      {
-                                                                        nearY = inputs[3]->GetFloat();
-                                                                        nearX = nearY * aspectRatio;
-                                                                      }
-                                                                      else
-                                                                      {
-                                                                        nearX = inputs[3]->GetFloat();
-                                                                        nearY = nearX / aspectRatio;
-                                                                      }
-                                                                      farX = nearX;
-                                                                      farY = nearY;
-                                                                    }
-
-                                                                    std::vector<Vector4> points;
-                                                                    points.push_back(Vector4(nearX, nearY, nearDistance, 1.0f));
-                                                                    points.push_back(Vector4(-nearX, nearY, nearDistance, 1.0f));
-                                                                    points.push_back(Vector4(-nearX, -nearY, nearDistance, 1.0f));
-                                                                    points.push_back(Vector4(nearX, -nearY, nearDistance, 1.0f));
-                                                                    points.push_back(Vector4(farX, farY, farDistance, 1.0f));
-                                                                    points.push_back(Vector4(-farX, farY, farDistance, 1.0f));
-                                                                    points.push_back(Vector4(-farX, -farY, farDistance, 1.0f));
-                                                                    points.push_back(Vector4(farX, -farY, farDistance, 1.0f));
-
-                                                                    Matrix shadowCameraWorldMatrix = inputs[8]->GetMatrix();
-                                                                    Vector4 worldCenter;
-                                                                    for(auto&& point : points)
-                                                                    {
-                                                                      point = worldMatrix * point;
-                                                                      worldCenter += point;
-                                                                    }
-                                                                    worldCenter /= 8.0f;
-                                                                    shadowCameraWorldMatrix.SetTranslation(Vector3(worldCenter));
-                                                                    Matrix shadowCameraViewMatrix = shadowCameraWorldMatrix;
-                                                                    shadowCameraViewMatrix.Invert();
-
-                                                                    Vector3 areaMin = Vector3::ONE * MAXFLOAT, areaMax = Vector3::ONE * -MAXFLOAT;
-                                                                    for(auto&& point : points)
-                                                                    {
-                                                                      Vector4 pointV = shadowCameraViewMatrix * point;
-                                                                      areaMin.x      = std::min(areaMin.x, pointV.x);
-                                                                      areaMin.y      = std::min(areaMin.y, pointV.y);
-                                                                      areaMin.z      = std::min(areaMin.z, pointV.z);
-                                                                      areaMax.x      = std::max(areaMax.x, pointV.x);
-                                                                      areaMax.y      = std::max(areaMax.y, pointV.y);
-                                                                      areaMax.z      = std::max(areaMax.z, pointV.z);
-                                                                    }
-
-                                                                    Vector2 center        = Vector2(areaMax + areaMin) * 0.5;
-                                                                    float   delta         = std::max(std::abs(areaMax.x - areaMin.x), std::abs(areaMax.y - areaMin.y));
-                                                                    float   delta_2       = delta * 0.5f;
-                                                                    Vector2 squareAreaMin = center - Vector2::ONE * delta_2;
-                                                                    Vector2 squareAreaMax = center + Vector2::ONE * delta_2;
-                                                                    float   deltaZ        = areaMax.z - areaMin.z;
-
-                                                                    float right  = -squareAreaMin.x;
-                                                                    float left   = -squareAreaMax.x;
-                                                                    float top    = squareAreaMin.y;
-                                                                    float bottom = squareAreaMax.y;
-                                                                    float near   = areaMin.z;
-                                                                    float far    = areaMax.z;
-
-                                                                    float* projMatrix = output.AsFloat();
-
-                                                                    projMatrix[0] = -2.0f / delta;
-                                                                    projMatrix[1] = 0.0f;
-                                                                    projMatrix[2] = 0.0f;
-                                                                    projMatrix[3] = 0.0f;
-
-                                                                    projMatrix[4] = 0.0f;
-                                                                    projMatrix[5] = -2.0f / delta;
-                                                                    projMatrix[6] = 0.0f;
-                                                                    projMatrix[7] = 0.0f;
-
-                                                                    projMatrix[8]  = 0.0f;
-                                                                    projMatrix[9]  = 0.0f;
-                                                                    projMatrix[10] = 2.0f / deltaZ;
-                                                                    projMatrix[11] = 0.0f;
-
-                                                                    projMatrix[12] = -(right + left) / delta;
-                                                                    projMatrix[13] = -(top + bottom) / delta;
-                                                                    projMatrix[14] = -(near + far) / deltaZ;
-                                                                    projMatrix[15] = 1.0f;
-
-                                                                    output = output * shadowCameraViewMatrix;
-                                                                  });
+  auto       tempViewProjectionMatrixIndex = shadowLightCamera.RegisterProperty("tempViewProjectionMatrix", Matrix::IDENTITY);
+  Constraint projectionMatrixConstraint    = Constraint::New<Matrix>(shadowLightCamera, tempViewProjectionMatrixIndex, [](Matrix& output, const PropertyInputContainer& inputs) {
+    Matrix worldMatrix  = inputs[0]->GetMatrix();
+    float  tangentFov_2 = tanf(inputs[4]->GetFloat());
+    float  nearDistance = inputs[5]->GetFloat();
+    float  farDistance  = inputs[6]->GetFloat();
+    float  aspectRatio  = inputs[7]->GetFloat();
+    float  nearY        = 0.0f;
+    float  nearX        = 0.0f;
+    float  farY         = 0.0f;
+    float  farX         = 0.0f;
+    if(inputs[1]->GetInteger() == Dali::Camera::ProjectionMode::PERSPECTIVE_PROJECTION)
+    {
+      if(inputs[2]->GetInteger() == Dali::DevelCameraActor::ProjectionDirection::VERTICAL)
+      {
+        nearY = tangentFov_2 * nearDistance;
+        nearX = nearY * aspectRatio;
+        farY  = tangentFov_2 * farDistance;
+        farX  = farY * aspectRatio;
+      }
+      else
+      {
+        nearX = tangentFov_2 * nearDistance;
+        nearY = nearX / aspectRatio;
+        farX  = tangentFov_2 * farDistance;
+        farY  = farX / aspectRatio;
+      }
+    }
+    else
+    {
+      if(inputs[2]->GetInteger() == Dali::DevelCameraActor::ProjectionDirection::VERTICAL)
+      {
+        nearY = inputs[3]->GetFloat();
+        nearX = nearY * aspectRatio;
+      }
+      else
+      {
+        nearX = inputs[3]->GetFloat();
+        nearY = nearX / aspectRatio;
+      }
+      farX = nearX;
+      farY = nearY;
+    }
+
+    std::vector<Vector4> points;
+    points.push_back(Vector4(nearX, nearY, nearDistance, 1.0f));
+    points.push_back(Vector4(-nearX, nearY, nearDistance, 1.0f));
+    points.push_back(Vector4(-nearX, -nearY, nearDistance, 1.0f));
+    points.push_back(Vector4(nearX, -nearY, nearDistance, 1.0f));
+    points.push_back(Vector4(farX, farY, farDistance, 1.0f));
+    points.push_back(Vector4(-farX, farY, farDistance, 1.0f));
+    points.push_back(Vector4(-farX, -farY, farDistance, 1.0f));
+    points.push_back(Vector4(farX, -farY, farDistance, 1.0f));
+
+    Matrix  shadowCameraWorldMatrix = inputs[8]->GetMatrix();
+    Vector4 worldCenter;
+    for(auto&& point : points)
+    {
+      point = worldMatrix * point;
+      worldCenter += point;
+    }
+    worldCenter /= 8.0f;
+    shadowCameraWorldMatrix.SetTranslation(Vector3(worldCenter));
+    Matrix shadowCameraViewMatrix = shadowCameraWorldMatrix;
+    shadowCameraViewMatrix.Invert();
+
+    Vector3 areaMin = Vector3::ONE * MAXFLOAT, areaMax = Vector3::ONE * -MAXFLOAT;
+    for(auto&& point : points)
+    {
+      Vector4 pointV = shadowCameraViewMatrix * point;
+      areaMin.x      = std::min(areaMin.x, pointV.x);
+      areaMin.y      = std::min(areaMin.y, pointV.y);
+      areaMin.z      = std::min(areaMin.z, pointV.z);
+      areaMax.x      = std::max(areaMax.x, pointV.x);
+      areaMax.y      = std::max(areaMax.y, pointV.y);
+      areaMax.z      = std::max(areaMax.z, pointV.z);
+    }
+
+    Vector2 center        = Vector2(areaMax + areaMin) * 0.5;
+    float   delta         = std::max(std::abs(areaMax.x - areaMin.x), std::abs(areaMax.y - areaMin.y));
+    float   delta_2       = delta * 0.5f;
+    Vector2 squareAreaMin = center - Vector2::ONE * delta_2;
+    Vector2 squareAreaMax = center + Vector2::ONE * delta_2;
+    float   deltaZ        = areaMax.z - areaMin.z;
+
+    float right  = -squareAreaMin.x;
+    float left   = -squareAreaMax.x;
+    float top    = squareAreaMin.y;
+    float bottom = squareAreaMax.y;
+    float near   = areaMin.z;
+    float far    = areaMax.z;
+
+    float* projMatrix = output.AsFloat();
+
+    projMatrix[0] = -2.0f / delta;
+    projMatrix[1] = 0.0f;
+    projMatrix[2] = 0.0f;
+    projMatrix[3] = 0.0f;
+
+    projMatrix[4] = 0.0f;
+    projMatrix[5] = -2.0f / delta;
+    projMatrix[6] = 0.0f;
+    projMatrix[7] = 0.0f;
+
+    projMatrix[8]  = 0.0f;
+    projMatrix[9]  = 0.0f;
+    projMatrix[10] = 2.0f / deltaZ;
+    projMatrix[11] = 0.0f;
+
+    projMatrix[12] = -(right + left) / delta;
+    projMatrix[13] = -(top + bottom) / delta;
+    projMatrix[14] = -(near + far) / deltaZ;
+    projMatrix[15] = 1.0f;
+
+    output = output * shadowCameraViewMatrix;
+  });
   projectionMatrixConstraint.AddSource(Source{selectedCamera, Dali::Actor::Property::WORLD_MATRIX});
   projectionMatrixConstraint.AddSource(Source{selectedCamera, Dali::CameraActor::Property::PROJECTION_MODE});
   projectionMatrixConstraint.AddSource(Source{selectedCamera, Dali::DevelCameraActor::Property::PROJECTION_DIRECTION});
@@ -622,8 +621,7 @@ void SceneView::SetShadow(Scene3D::Light light)
     return;
   }
 
-  auto foundLight = std::find_if(mLights.begin(), mLights.end(), [light](std::pair<Scene3D::Light, bool> lightEntity) -> bool
-                                 { return (lightEntity.second && lightEntity.first == light); });
+  auto foundLight = std::find_if(mLights.begin(), mLights.end(), [light](std::pair<Scene3D::Light, bool> lightEntity) -> bool { return (lightEntity.second && lightEntity.first == light); });
 
   if(foundLight == mLights.end())
   {
@@ -638,7 +636,7 @@ void SceneView::SetShadow(Scene3D::Light light)
   SetShadowLightConstraint(selectedCamera, lightCamera);
 
   // make framebuffer for depth map and set it to render task.
-  Vector3  size               = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
+  Vector3  size                = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
   uint32_t shadowMapBufferSize = std::min(static_cast<uint32_t>(std::max(size.width, size.height)), MAXIMUM_SIZE_SHADOW_MAP);
   UpdateShadowMapBuffer(shadowMapBufferSize);
 
@@ -1112,12 +1110,7 @@ void SceneView::OnSkyboxLoadComplete()
   }
 
   mSkyboxResourceReady = true;
-  if(IsResourceReady())
-  {
-    Control::SetResourceReady();
-  }
-
-  mSkyboxTexture = mSkyboxLoadTask->GetLoadedTexture();
+  mSkyboxTexture       = mSkyboxLoadTask->GetLoadedTexture();
   Shader skyboxShader;
   if(mSkyboxLoadTask->GetEnvironmentMapType() == Scene3D::EnvironmentMapType::CUBEMAP)
   {
@@ -1138,17 +1131,22 @@ void SceneView::OnSkyboxLoadComplete()
   }
 
   mSkyboxLoadTask.Reset();
+
+  if(IsResourceReady())
+  {
+    Control::SetResourceReady();
+  }
 }
 
 void SceneView::OnIblDiffuseLoadComplete()
 {
   mDiffuseTexture          = mIblDiffuseLoadTask->GetLoadedTexture();
   mIblDiffuseResourceReady = true;
+  mIblDiffuseLoadTask.Reset();
   if(mIblDiffuseResourceReady && mIblSpecularResourceReady)
   {
     OnIblLoadComplete();
   }
-  mIblDiffuseLoadTask.Reset();
 }
 
 void SceneView::OnIblSpecularLoadComplete()
@@ -1156,11 +1154,11 @@ void SceneView::OnIblSpecularLoadComplete()
   mSpecularTexture          = mIblSpecularLoadTask->GetLoadedTexture();
   mSpecularMipmapLevels     = mIblSpecularLoadTask->GetMipmapLevels();
   mIblSpecularResourceReady = true;
+  mIblSpecularLoadTask.Reset();
   if(mIblDiffuseResourceReady && mIblSpecularResourceReady)
   {
     OnIblLoadComplete();
   }
-  mIblSpecularLoadTask.Reset();
 }
 
 void SceneView::OnIblLoadComplete()
index 382ef23..fed5316 100644 (file)
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2022 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.
@@ -21,6 +21,9 @@
 // EXTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/visuals/npatch-data.h>
+
 namespace Dali
 {
 namespace Toolkit
@@ -250,7 +253,7 @@ void RegisterStretchProperties(Renderer& renderer, const char* uniformName, cons
   }
 }
 
-void ApplyTextureAndUniforms(Renderer& renderer, const std::shared_ptr<const Internal::NPatchData> data)
+void ApplyTextureAndUniforms(Renderer& renderer, const Internal::NPatchData* data)
 {
   TextureSet textureSet;
   textureSet = data->GetTextures();
index 2427063..da1f55a 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_NPATCH_HELPER_H
 
 /*
- * Copyright (c) 2021 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.
  */
 
 // EXTERNAL INCLUDES
+#include <dali/devel-api/rendering/renderer-devel.h>
 #include <dali/public-api/math/uint-16-pair.h>
 #include <dali/public-api/rendering/geometry.h>
-#include <dali/devel-api/rendering/renderer-devel.h>
-#include <memory> ///< for std::shared_ptr
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/utility/npatch-utilities.h>
 #include <dali-toolkit/public-api/dali-toolkit-common.h>
-#include <dali-toolkit/internal/visuals/npatch-data.h>
 
 namespace Dali
 {
 namespace Toolkit
 {
-namespace NPatchHelper
+namespace Internal
 {
-/**
- * The list that includes stretch pixel ranges
- */
-using StretchRanges = Dali::Vector<Uint16Pair>;
+class NPatchData;
+}
 
+namespace NPatchHelper
+{
 /**
  * @brief Creates a Npatch Geometry object
  *
@@ -70,7 +69,6 @@ DALI_TOOLKIT_API Geometry CreateGridGeometry(Uint16Pair gridSize);
  */
 DALI_TOOLKIT_API Geometry CreateBorderGeometry(Uint16Pair gridSize);
 
-
 /**
  * @brief Registers a properties for Stretch Ranges
  *
@@ -87,9 +85,9 @@ void RegisterStretchProperties(Renderer& renderer, const char* uniformName, cons
  * @param[in,out] renderer The renderer for broken image
  * @param[in] data The pointer of npatch-data
  */
-void ApplyTextureAndUniforms(Renderer& renderer, const std::shared_ptr<const Internal::NPatchData> data);
+void ApplyTextureAndUniforms(Renderer& renderer, const Internal::NPatchData* data);
 
-} // namespace NPatchUtility
+} // namespace NPatchHelper
 
 } // namespace Toolkit
 
index abe5581..370a678 100644 (file)
@@ -362,6 +362,8 @@ void RollingAnimatedImageCache::LoadComplete(bool loadSuccess, TextureInformatio
 
   MakeFrameReady(loadSuccess, textureInformation.textureSet, textureInformation.interval, textureInformation.preMultiplied);
 
+  // TODO : We need to remove some below logics, since user can remove Visual during ResourceReady callback.
+
   if(loadSuccess)
   {
     // The frames of a single animated image can not be loaded parallelly.
index b9a8f87..53ba256 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
+
   DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnAnimationFinished: action state = %d [%p]\n", mPlayState, this);
 
   if(mPlayState != DevelImageVisual::PlayState::STOPPED)
index 5c0c474..28c3ebd 100644 (file)
@@ -257,6 +257,8 @@ void NPatchData::NotifyObserver(TextureUploadObserver* observer, const bool& loa
 
 void NPatchData::LoadComplete(bool loadSuccess, TextureInformation textureInformation)
 {
+  NPatchDataPtr self = this; // Keep reference until this API finished
+
   if(loadSuccess)
   {
     if(mLoadingState != LoadingState::LOAD_COMPLETE)
index 3df4b29..99c4d08 100644 (file)
@@ -19,6 +19,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#include <dali/public-api/object/ref-object.h>
 #include <dali/public-api/rendering/texture-set.h>
 #include <string>
 
@@ -33,7 +34,10 @@ namespace Toolkit
 {
 namespace Internal
 {
-class NPatchData : public ConnectionTracker, public Dali::Toolkit::TextureUploadObserver
+class NPatchData;
+typedef IntrusivePtr<NPatchData> NPatchDataPtr;
+
+class NPatchData : public ConnectionTracker, public Dali::Toolkit::TextureUploadObserver, public Dali::RefObject
 {
 public:
   typedef int32_t           NPatchDataId;                ///< The NPatchDataId type. This is used as a handle to refer to a particular Npatch Data.
@@ -279,19 +283,20 @@ 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
+
+  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..16b49be 100644 (file)
@@ -66,9 +66,9 @@ NPatchData::NPatchDataId NPatchLoader::GenerateUniqueNPatchDataId()
 
 NPatchData::NPatchDataId NPatchLoader::Load(TextureManager& textureManager, TextureUploadObserver* textureObserver, const VisualUrl& url, const Rect<int>& border, bool& preMultiplyOnLoad, bool synchronousLoading)
 {
-  std::shared_ptr<NPatchData> data = GetNPatchData(url, border, preMultiplyOnLoad);
+  NPatchDataPtr data = GetNPatchData(url, border, preMultiplyOnLoad);
 
-  DALI_ASSERT_ALWAYS(data.get() && "NPatchData creation failed!");
+  DALI_ASSERT_ALWAYS(data.Get() && "NPatchData creation failed!");
 
   if(data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE)
   {
@@ -97,7 +97,7 @@ NPatchData::NPatchDataId NPatchLoader::Load(TextureManager& textureManager, Text
     auto preMultiplyOnLoading = preMultiplyOnLoad ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
                                                   : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
-    Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer(url, Dali::ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, synchronousLoading, data.get(), true, preMultiplyOnLoading);
+    Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer(url, Dali::ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, synchronousLoading, data.Get(), true, preMultiplyOnLoading);
 
     if(pixelBuffer)
     {
@@ -127,7 +127,7 @@ int32_t NPatchLoader::GetCacheIndexFromId(const NPatchData::NPatchDataId id)
   return INVALID_CACHE_INDEX;
 }
 
-bool NPatchLoader::GetNPatchData(const NPatchData::NPatchDataId id, std::shared_ptr<const NPatchData>& data)
+bool NPatchLoader::GetNPatchData(const NPatchData::NPatchDataId id, NPatchDataPtr& data)
 {
   int32_t cacheIndex = GetCacheIndexFromId(id);
   if(cacheIndex != INVALID_CACHE_INDEX)
@@ -195,7 +195,7 @@ void NPatchLoader::Process(bool postProcessor)
   }
 }
 
-std::shared_ptr<NPatchData> NPatchLoader::GetNPatchData(const VisualUrl& url, const Rect<int>& border, bool& preMultiplyOnLoad)
+NPatchDataPtr NPatchLoader::GetNPatchData(const VisualUrl& url, const Rect<int>& border, bool& preMultiplyOnLoad)
 {
   std::size_t                              hash  = CalculateHash(url.GetUrl());
   std::vector<NPatchInfo>::size_type       index = UNINITIALIZED_ID;
@@ -247,7 +247,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(new NPatchData());
     info.mData->SetId(GenerateUniqueNPatchDataId());
     info.mData->SetHash(hash);
     info.mData->SetUrl(url);
@@ -260,7 +260,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(new NPatchData());
 
     info.mData->SetId(GenerateUniqueNPatchDataId());
     info.mData->SetHash(hash);
index a55ab6f..5890326 100644 (file)
@@ -21,7 +21,6 @@
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali/integration-api/processor-interface.h>
 #include <dali/public-api/rendering/texture-set.h>
-#include <memory> // for std::shared_ptr
 #include <string>
 #include <utility> // for std::pair
 
@@ -79,7 +78,7 @@ public:
    * @param [out] data const pointer to the NPatchData
    * @return true if data matching to id was really found
    */
-  bool GetNPatchData(const NPatchData::NPatchDataId id, std::shared_ptr<const NPatchData>& data);
+  bool GetNPatchData(const NPatchData::NPatchDataId id, NPatchDataPtr& data);
 
   /**
    * @brief Request remove a texture matching id.
@@ -119,7 +118,7 @@ private:
    */
   struct NPatchInfo
   {
-    NPatchInfo(std::shared_ptr<NPatchData> data)
+    NPatchInfo(NPatchDataPtr data)
     : mData(data),
       mReferenceCount(1u)
     {
@@ -145,8 +144,8 @@ private:
     NPatchInfo(const NPatchInfo& info) = delete;            // Do not use copy constructor
     NPatchInfo& operator=(const NPatchInfo& info) = delete; // Do not use copy assign
 
-    std::shared_ptr<NPatchData> mData;
-    std::int16_t                mReferenceCount; ///< The number of N-patch visuals that use this data.
+    NPatchDataPtr mData;
+    std::int16_t  mReferenceCount; ///< The number of N-patch visuals that use this data.
   };
 
   /**
@@ -159,7 +158,7 @@ private:
    *                                   image has no alpha channel
    * @return NPatchData pointer that Load function will used.
    */
-  std::shared_ptr<NPatchData> GetNPatchData(const VisualUrl& url, const Rect<int>& border, bool& preMultiplyOnLoad);
+  NPatchDataPtr GetNPatchData(const VisualUrl& url, const Rect<int>& border, bool& preMultiplyOnLoad);
 
 protected:
   /**
index 606e040..e469297 100644 (file)
@@ -80,7 +80,7 @@ void NPatchVisual::LoadImages()
     bool preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader ? true : false;
     mId                    = mLoader.Load(textureManager, this, mImageUrl, mBorder, preMultiplyOnLoad, synchronousLoading);
 
-    std::shared_ptr<const NPatchData> data;
+    NPatchDataPtr data;
     if(mLoader.GetNPatchData(mId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE)
     {
       EnablePreMultipliedAlpha(data->IsPreMultiplied());
@@ -126,7 +126,7 @@ void NPatchVisual::GetNaturalSize(Vector2& naturalSize)
   naturalSize.y = 0u;
 
   // load now if not already loaded
-  std::shared_ptr<const NPatchData> data;
+  NPatchDataPtr data;
   if(mLoader.GetNPatchData(mId, data) && data->GetLoadingState() != NPatchData::LoadingState::LOADING)
   {
     naturalSize.x = data->GetCroppedWidth();
@@ -223,7 +223,7 @@ void NPatchVisual::DoSetOnScene(Actor& actor)
   // at this case, we try to SetResouce to mPlaceActor twice. so, we should avoid that case.
   mPlacementActor = actor;
 
-  std::shared_ptr<const NPatchData> data;
+  NPatchDataPtr data;
   if(mImpl->mRenderer && mLoader.GetNPatchData(mId, data) && data->GetLoadingState() != NPatchData::LoadingState::LOADING)
   {
     // If mAuxiliaryUrl need to be loaded, we should wait it until LoadComplete called.
@@ -338,9 +338,9 @@ NPatchVisual::~NPatchVisual()
 void NPatchVisual::OnInitialize()
 {
   // Get basic geometry and shader
-  Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY);
-  auto imageVisualShaderFeatureBuilder = ImageVisualShaderFeatureBuilder();
-  Shader   shader   = mImageVisualShaderFactory.GetShader(
+  Geometry geometry                        = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY);
+  auto     imageVisualShaderFeatureBuilder = ImageVisualShaderFeatureBuilder();
+  Shader   shader                          = mImageVisualShaderFactory.GetShader(
     mFactoryCache,
     imageVisualShaderFeatureBuilder);
 
@@ -353,8 +353,8 @@ void NPatchVisual::OnInitialize()
 
 Geometry NPatchVisual::CreateGeometry()
 {
-  Geometry                          geometry;
-  std::shared_ptr<const NPatchData> data;
+  Geometry      geometry;
+  NPatchDataPtr data;
   if(mLoader.GetNPatchData(mId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE)
   {
     if(data->GetStretchPixelsX().Size() == 1 && data->GetStretchPixelsY().Size() == 1)
@@ -408,8 +408,8 @@ Geometry NPatchVisual::CreateGeometry()
 
 Shader NPatchVisual::CreateShader()
 {
-  Shader                            shader;
-  std::shared_ptr<const NPatchData> data;
+  Shader        shader;
+  NPatchDataPtr data;
   // 0 is either no data (load failed?) or no stretch regions on image
   // for both cases we use the default shader
   NPatchUtility::StretchRanges::SizeType xStretchCount = 0;
@@ -488,13 +488,13 @@ Shader NPatchVisual::CreateShader()
 
 void NPatchVisual::ApplyTextureAndUniforms()
 {
-  std::shared_ptr<const NPatchData> data;
-  TextureSet                        textureSet;
+  NPatchDataPtr data;
+  TextureSet    textureSet;
 
   if(mLoader.GetNPatchData(mId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE)
   {
     textureSet = data->GetTextures();
-    NPatchHelper::ApplyTextureAndUniforms(mImpl->mRenderer, data);
+    NPatchHelper::ApplyTextureAndUniforms(mImpl->mRenderer, data.Get());
 
     if(mAuxiliaryResourceStatus == Toolkit::Visual::ResourceStatus::READY)
     {
@@ -551,7 +551,7 @@ Geometry NPatchVisual::GetNinePatchGeometry(VisualFactoryCache::GeometryType sub
 
 void NPatchVisual::SetResource()
 {
-  std::shared_ptr<const NPatchData> data;
+  NPatchDataPtr data;
   if(mImpl->mRenderer && mLoader.GetNPatchData(mId, data))
   {
     Geometry geometry = CreateGeometry();
@@ -628,7 +628,7 @@ void NPatchVisual::LoadComplete(bool loadSuccess, TextureInformation textureInfo
   // If auxiliaryUrl didn't required OR auxiliaryUrl load done.
   if(!mAuxiliaryUrl.IsValid() || mAuxiliaryResourceStatus != Toolkit::Visual::ResourceStatus::PREPARING)
   {
-    std::shared_ptr<const NPatchData> data;
+    NPatchDataPtr data;
     // and.. If Url loading done.
     if(mImpl->mRenderer && mLoader.GetNPatchData(mId, data) && data->GetLoadingState() != NPatchData::LoadingState::LOADING)
     {
index c6e471c..fd7c3e2 100644 (file)
@@ -337,6 +337,18 @@ void SvgVisual::AddRasterizationTask(const Vector2& size)
 
 void SvgVisual::ApplyRasterizedImage(SvgTaskPtr task)
 {
+  SvgVisualPtr self = this; // Keep reference until this API finished
+
+  // 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();
@@ -428,16 +440,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()
index 9437bdc..69fbbad 100644 (file)
@@ -272,8 +272,8 @@ VisualUrl::Type VisualFactoryCache::GetBrokenImageVisualType(int index)
 
 Geometry VisualFactoryCache::GetNPatchGeometry(int index)
 {
-  Geometry                          geometry;
-  std::shared_ptr<const NPatchData> data;
+  Geometry      geometry;
+  NPatchDataPtr data;
   if(mNPatchLoader.GetNPatchData(mBrokenImageInfoContainer[index].npatchId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE)
   {
     if(data->GetStretchPixelsX().Size() == 1 && data->GetStretchPixelsY().Size() == 1)
@@ -306,8 +306,8 @@ Geometry VisualFactoryCache::GetNPatchGeometry(int index)
 
 Shader VisualFactoryCache::GetNPatchShader(int index)
 {
-  Shader                            shader;
-  std::shared_ptr<const NPatchData> data;
+  Shader        shader;
+  NPatchDataPtr data;
   // 0 is either no data (load failed?) or no stretch regions on image
   // for both cases we use the default shader
   NPatchUtility::StretchRanges::SizeType xStretchCount = 0;
@@ -344,13 +344,13 @@ Shader VisualFactoryCache::GetNPatchShader(int index)
 
 void VisualFactoryCache::ApplyTextureAndUniforms(Renderer& renderer, int index)
 {
-  std::shared_ptr<const NPatchData> data;
-  TextureSet                        textureSet;
+  NPatchDataPtr data;
+  TextureSet    textureSet;
   if(mNPatchLoader.GetNPatchData(mBrokenImageInfoContainer[index].npatchId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE)
   {
     textureSet                               = data->GetTextures();
     mBrokenImageInfoContainer[index].texture = textureSet.GetTexture(0);
-    NPatchHelper::ApplyTextureAndUniforms(renderer, data);
+    NPatchHelper::ApplyTextureAndUniforms(renderer, data.Get());
     renderer.SetTextures(textureSet);
   }
 }
@@ -374,8 +374,8 @@ void VisualFactoryCache::UpdateBrokenImageRenderer(Renderer& renderer, const Vec
         mBrokenImageInfoContainer[index].visualType = visualUrl.GetType();
         if(mBrokenImageInfoContainer[index].visualType == VisualUrl::Type::N_PATCH)
         {
-          std::shared_ptr<const NPatchData> data;
-          Rect<int>                         border;
+          NPatchDataPtr data;
+          Rect<int>     border;
           mBrokenImageInfoContainer[index].npatchId = mNPatchLoader.Load(mTextureManager, NULL, mBrokenImageInfoContainer[index].url, border, mPreMultiplyOnLoad, true);
           if(mNPatchLoader.GetNPatchData(mBrokenImageInfoContainer[index].npatchId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE)
           {