Fixed Cache for AnimatedVectorImageVisual 10/300510/7
authorseungho baek <sbsh.baek@samsung.com>
Thu, 26 Oct 2023 09:17:02 +0000 (18:17 +0900)
committersunghyun kim <scholb.kim@samsung.com>
Fri, 29 Dec 2023 02:11:32 +0000 (11:11 +0900)
Change-Id: I22bab282652f5377b95ce1d34db4564398be0ae8
Signed-off-by: seungho baek <sbsh.baek@samsung.com>
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
dali-toolkit/devel-api/visuals/image-visual-properties-devel.h
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/internal/visuals/visual-string-constants.h

index 4aec20d..4c5fe55 100644 (file)
@@ -211,6 +211,12 @@ public:
     mDynamicPropertyCallback = std::unique_ptr<CallbackBase>(callback);
   }
 
+  void KeepRasterizedBuffer()
+  {
+    Dali::Mutex::ScopedLock lock(mMutex);
+    mEnableFixedCache = true;
+  }
+
   Dali::VectorAnimationRenderer::UploadCompletedSignalType& UploadCompletedSignal()
   {
     return mUploadCompletedSignal;
@@ -256,6 +262,7 @@ public:
   bool     mLoadFailed{false};
   bool     mResourceReady{false};
   bool     mNeedTrigger{true};
+  bool     mEnableFixedCache{false};
 
   Dali::VectorAnimationRenderer::UploadCompletedSignalType mUploadCompletedSignal;
   std::unique_ptr<EventThreadCallback>                     mEventThreadCallback;
@@ -391,6 +398,12 @@ void VectorAnimationRenderer::AddPropertyValueCallback(const std::string& keyPat
   Internal::Adaptor::GetImplementation(*this).AddPropertyValueCallback(keyPath, property, callback, id);
 }
 
+void VectorAnimationRenderer::KeepRasterizedBuffer()
+{
+  Internal::Adaptor::GetImplementation(*this).KeepRasterizedBuffer();
+}
+
+
 VectorAnimationRenderer::UploadCompletedSignalType& VectorAnimationRenderer::UploadCompletedSignal()
 {
   return Internal::Adaptor::GetImplementation(*this).UploadCompletedSignal();
index 2aa3d4e..775c5fa 100644 (file)
@@ -212,7 +212,8 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void)
     .Add("borderlineColor", borderlineColor)
     .Add("borderlineOffset", borderlineOffset)
     .Add("desiredWidth", desiredWidth)
-    .Add("desiredHeight", desiredHeight);
+    .Add("desiredHeight", desiredHeight)
+    .Add("useFixedCache", false);
 
   Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
   DALI_TEST_CHECK(visual);
@@ -389,6 +390,10 @@ int UtcDaliAnimatedVectorImageVisualGetPropertyMap01(void)
   value = resultMap.Find(DevelImageVisual::Property::MARKER_INFO, Property::MAP);
   DALI_TEST_CHECK(value);
 
+  value = resultMap.Find(DevelImageVisual::Property::USE_FIXED_CACHE, Property::BOOLEAN);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<bool>() == false); // Check default value
+
   value = resultMap.Find(DevelImageVisual::Property::REDRAW_IN_SCALING_DOWN, Property::BOOLEAN);
   DALI_TEST_CHECK(value);
   DALI_TEST_CHECK(value->Get<bool>() == true); // Check default value
@@ -1094,6 +1099,100 @@ int UtcDaliAnimatedVectorImageVisualMarkerInfoFromInvalid(void)
   END_TEST;
 }
 
+int UtcDaliAnimatedVectorImageVisualUsedFixedCache(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliAnimatedVectorImageVisualUsedFixedCache");
+
+  Property::Map propertyMap;
+  propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
+    .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME)
+    .Add(DevelImageVisual::Property::USE_FIXED_CACHE, true)
+    .Add(ImageVisual::Property::SYNCHRONOUS_LOADING, false);
+
+  Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
+  DALI_TEST_CHECK(visual);
+
+  DummyControl      actor     = DummyControl::New(true);
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+  //actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 1 - render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  Vector2 controlSize(200.f, 200.f);
+  actor.SetProperty(Actor::Property::SIZE, controlSize);
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 1 - load
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  // renderer is added to actor
+  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+  Renderer renderer = actor.GetRendererAt(0u);
+  DALI_TEST_CHECK(renderer);
+
+  Property::Map    map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+  Property::Value* value = map.Find(DevelImageVisual::Property::USE_FIXED_CACHE);
+  DALI_TEST_CHECK(value->Get<bool>() == true);
+
+  END_TEST;
+}
+
+int UtcDaliAnimatedVectorImageVisualUsedFixedCacheFailed(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliAnimatedVectorImageVisualUsedFixedCacheFailed");
+
+  Property::Map propertyMap;
+  propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
+    .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_INVALID_FILE_NAME)
+    .Add(DevelImageVisual::Property::USE_FIXED_CACHE, true)
+    .Add(ImageVisual::Property::SYNCHRONOUS_LOADING, false);
+
+  Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
+  DALI_TEST_CHECK(visual);
+
+  DummyControl      actor     = DummyControl::New(true);
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+  Vector2 controlSize(200.f, 200.f);
+  actor.SetProperty(Actor::Property::SIZE, controlSize);
+
+  application.GetScene().Add(actor);
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 1 - load, and failed.
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  // renderer is added to actor
+  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+  Renderer renderer = actor.GetRendererAt(0u);
+  DALI_TEST_CHECK(renderer);
+
+  propertyMap.Clear();
+  propertyMap.Add(DevelImageVisual::Property::USE_FIXED_CACHE, true)
+    .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME)
+    .Add(ImageVisual::Property::DESIRED_WIDTH, 100)
+    .Add(ImageVisual::Property::DESIRED_HEIGHT, 100);
+  DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, propertyMap);
+
+  Property::Map    map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+  Property::Value* value = map.Find(DevelImageVisual::Property::USE_FIXED_CACHE);
+  DALI_TEST_CHECK(value->Get<bool>() == true);
+
+  END_TEST;
+}
+
 int UtcDaliAnimatedVectorImageVisualAnimationFinishedSignal(void)
 {
   ToolkitTestApplication application;
index 1677767..473ec7c 100644 (file)
@@ -190,6 +190,16 @@ enum Type
    * @note This property is read-only.
    */
   MARKER_INFO = ORIENTATION_CORRECTION + 15,
+
+  /**
+   * @brief Whether to AnimatedVectorImageVisual fixed cache or not.
+   * @details Name "useFixedCache", type Property::BOOLEAN.
+   * If this property is true, AnimatedVectorImageVisual uses fixed cache for loading and keeps loaded frame
+   * until the visual is removed. It reduces CPU cost when the animated image will be looping.
+   * But it can spend a lot of memory if the resource has high resolution image or many frame count.
+   * @note It is used in the AnimatedImageVisual. The default is false
+   */
+  USE_FIXED_CACHE = ORIENTATION_CORRECTION + 16
 };
 
 } //namespace Property
index 699c281..72997d1 100644 (file)
@@ -100,7 +100,8 @@ AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factory
   mLoadFailed(false),
   mRendererAdded(false),
   mCoreShutdown(false),
-  mRedrawInScalingDown(true)
+  mRedrawInScalingDown(true),
+  mUseFixedCache(false)
 {
   // the rasterized image is with pre-multiplied alpha format
   mImpl->mFlags |= Visual::Base::Impl::IS_PREMULTIPLIED_ALPHA;
@@ -217,6 +218,7 @@ void AnimatedVectorImageVisual::DoCreatePropertyMap(Property::Map& map) const
   map.Insert(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, IsSynchronousLoadingRequired());
   map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth());
   map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight());
+  map.Insert(Toolkit::DevelImageVisual::Property::USE_FIXED_CACHE, mUseFixedCache);
 }
 
 void AnimatedVectorImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const
@@ -277,6 +279,10 @@ void AnimatedVectorImageVisual::DoSetProperties(const Property::Map& propertyMap
       {
         DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, keyValue.second);
       }
+      else if(keyValue.first == USE_FIXED_CACHE)
+      {
+        DoSetProperty(Toolkit::DevelImageVisual::Property::USE_FIXED_CACHE, keyValue.second);
+      }
     }
   }
 
@@ -382,6 +388,20 @@ void AnimatedVectorImageVisual::DoSetProperty(Property::Index index, const Prope
       }
       break;
     }
+
+    case Toolkit::DevelImageVisual::Property::USE_FIXED_CACHE:
+    {
+      bool useFixedCache = false;
+      if(value.Get(useFixedCache))
+      {
+        mUseFixedCache = useFixedCache;
+        if(mVectorAnimationTask)
+        {
+          mVectorAnimationTask->KeepRasterizedBuffer(mUseFixedCache);
+        }
+      }
+      break;
+    }
   }
 }
 
@@ -403,6 +423,7 @@ void AnimatedVectorImageVisual::OnInitialize(void)
     encodedImageBuffer = textureManager.GetEncodedImageBuffer(mImageUrl.GetUrl());
   }
 
+  mVectorAnimationTask->KeepRasterizedBuffer(mUseFixedCache);
   mVectorAnimationTask->RequestLoad(mImageUrl, encodedImageBuffer, IsSynchronousLoadingRequired());
 
   auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
index e013d6c..ded8c45 100644 (file)
@@ -253,6 +253,7 @@ private:
   bool                               mRendererAdded;
   bool                               mCoreShutdown;
   bool                               mRedrawInScalingDown;
+  bool                               mUseFixedCache;
 };
 
 } // namespace Internal
index 6dba6b5..4cde154 100644 (file)
@@ -91,7 +91,9 @@ VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache)
   mRasterized(false),
   mKeepAnimation(false),
   mLayerInfoCached(false),
-  mMarkerInfoCached(false)
+  mMarkerInfoCached(false),
+  mUseFixedCache(false),
+  mSizeUpdated(false)
 {
   mVectorRenderer.UploadCompletedSignal().Connect(this, &VectorAnimationTask::OnUploadCompleted);
 }
@@ -296,6 +298,20 @@ void VectorAnimationTask::SetSize(uint32_t width, uint32_t height)
     mWidth  = width;
     mHeight = height;
 
+    // If fixedCache is enabled, Call KeepRasterizedBuffer()
+    if(mUseFixedCache)
+    {
+      if(mTotalFrame > 0 && !mLoadFailed)
+      {
+        mVectorRenderer.KeepRasterizedBuffer();
+      }
+      else
+      {
+        // If Load is not yet, update the size later.
+        mSizeUpdated = true;
+      }
+    }
+
     DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetSize: width = %d, height = %d [%p]\n", width, height, this);
   }
 }
@@ -832,6 +848,11 @@ void VectorAnimationTask::OnLoadCompleted()
 {
   if(!mLoadFailed)
   {
+    if(mUseFixedCache && mSizeUpdated)
+    {
+      mVectorRenderer.KeepRasterizedBuffer();
+      mSizeUpdated = false;
+    }
     mResourceReadySignal.Emit(ResourceStatus::LOADED);
   }
   else
index a6c24b9..54e6bb2 100644 (file)
@@ -273,6 +273,16 @@ public: // Implementation of AsyncTask
     return "VectorAnimationTask";
   }
 
+  void KeepRasterizedBuffer(bool useFixedCache)
+  {
+    mUseFixedCache = useFixedCache;
+  }
+
+  bool IsKeptRasterizedBuffer()
+  {
+    return mUseFixedCache;
+  }
+
 private:
   /**
    * @brief Loads the animation file.
@@ -410,6 +420,8 @@ private:
   bool                                 mKeepAnimation : 1;
   mutable bool                         mLayerInfoCached : 1;
   mutable bool                         mMarkerInfoCached : 1;
+  bool                                 mUseFixedCache : 1;
+  bool                                 mSizeUpdated : 1;
 };
 
 } // namespace Internal
index 0ffa198..f257837 100644 (file)
@@ -125,6 +125,7 @@ const char* const MASKING_TYPE_NAME("maskingType");
 const char* const MASK_TEXTURE_RATIO_NAME("maskTextureRatio");
 const char* const FAST_TRACK_UPLOADING_NAME("fastTrackUploading");
 const char* const ENABLE_BROKEN_IMAGE("enableBrokenImage");
+const char* const USE_FIXED_CACHE("useFixedCache");
 
 // Text visual
 const char* const TEXT_PROPERTY("text");
index ff492ec..944beaa 100644 (file)
@@ -109,6 +109,7 @@ extern const char* const MASKING_TYPE_NAME;
 extern const char* const MASK_TEXTURE_RATIO_NAME;
 extern const char* const FAST_TRACK_UPLOADING_NAME;
 extern const char* const ENABLE_BROKEN_IMAGE;
+extern const char* const USE_FIXED_CACHE;
 
 // Text visual
 extern const char* const TEXT_PROPERTY;