Merge "(Vector) Support EncodedImageBuffer can use for vector image" into devel/master
authorEunki Hong <eunkiki.hong@samsung.com>
Wed, 8 Nov 2023 04:56:41 +0000 (04:56 +0000)
committerGerrit Code Review <gerrit@review>
Wed, 8 Nov 2023 04:56:41 +0000 (04:56 +0000)
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
dali-toolkit/devel-api/visuals/image-visual-properties-devel.h
dali-toolkit/internal/image-loader/fast-track-loading-task.cpp
dali-toolkit/internal/image-loader/loading-task.cpp
dali-toolkit/internal/texture-manager/texture-manager-impl.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
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/svg/svg-task.cpp

index bb45bda..4aec20d 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.
@@ -19,6 +19,7 @@
 #include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
 #include <dali/devel-api/threading/mutex.h>
 #include <dali/public-api/object/base-object.h>
+#include <dali/public-api/object/property-array.h>
 #include <toolkit-application.h>
 #include <toolkit-event-thread-callback.h>
 #include <toolkit-vector-animation-renderer.h>
@@ -374,6 +375,12 @@ bool VectorAnimationRenderer::GetMarkerInfo(const std::string& marker, uint32_t&
   return Internal::Adaptor::GetImplementation(*this).GetMarkerInfo(marker, startFrame, endFrame);
 }
 
+void VectorAnimationRenderer::GetMarkerInfo(Property::Map& map) const
+{
+  map.Add(VECTOR_ANIMATION_MARKER_NAME_1, Property::Array({VECTOR_ANIMATION_MARKER_START_FRAME_1, VECTOR_ANIMATION_MARKER_END_FRAME_1}));
+  map.Add(VECTOR_ANIMATION_MARKER_NAME_2, Property::Array({VECTOR_ANIMATION_MARKER_START_FRAME_2, VECTOR_ANIMATION_MARKER_END_FRAME_2}));
+}
+
 void VectorAnimationRenderer::InvalidateBuffer()
 {
   return Internal::Adaptor::GetImplementation(*this).InvalidateBuffer();
index 732d6b1..907b8af 100644 (file)
@@ -386,6 +386,9 @@ int UtcDaliAnimatedVectorImageVisualGetPropertyMap01(void)
   value = resultMap.Find(DevelImageVisual::Property::CONTENT_INFO, Property::MAP);
   DALI_TEST_CHECK(value);
 
+  value = resultMap.Find(DevelImageVisual::Property::MARKER_INFO, Property::MAP);
+  DALI_TEST_CHECK(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
@@ -967,6 +970,85 @@ int UtcDaliAnimatedVectorImageVisualPlayRangeMarker(void)
   END_TEST;
 }
 
+int UtcDaliAnimatedVectorImageVisualMarkerInfo(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliAnimatedVectorImageVisualMarkerInfo");
+
+  Property::Map propertyMap;
+  propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
+    .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME)
+    .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(20.f, 30.f);
+  actor.SetProperty(Actor::Property::SIZE, controlSize);
+
+  application.GetScene().Add(actor);
+
+  Property::Map attributes;
+  DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes);
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), 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::MARKER_INFO);
+
+  DALI_TEST_CHECK(value);
+
+  Property::Map* result = value->GetMap();
+  DALI_TEST_CHECK(result);
+
+  std::string resultMarkerName;
+  int         resultStartFrame, resultEndFrame;
+  DALI_TEST_EQUALS(2u, result->Count(), TEST_LOCATION);
+
+  for(uint32_t i = 0u; i < result->Count(); ++i)
+  {
+    if(result->GetKeyAt(i).stringKey == VECTOR_ANIMATION_MARKER_NAME_1)
+    {
+      Property::Array* frameArray = result->GetValue(i).GetArray();
+      DALI_TEST_CHECK(frameArray);
+      frameArray->GetElementAt(0).Get(resultStartFrame);
+      frameArray->GetElementAt(1).Get(resultEndFrame);
+
+      DALI_TEST_EQUALS(VECTOR_ANIMATION_MARKER_START_FRAME_1, resultStartFrame, TEST_LOCATION);
+      DALI_TEST_EQUALS(VECTOR_ANIMATION_MARKER_END_FRAME_1, resultEndFrame, TEST_LOCATION);
+    }
+    else if(result->GetKeyAt(i).stringKey == VECTOR_ANIMATION_MARKER_NAME_2)
+    {
+      Property::Array* frameArray = result->GetValue(i).GetArray();
+      DALI_TEST_CHECK(frameArray);
+      frameArray->GetElementAt(0).Get(resultStartFrame);
+      frameArray->GetElementAt(1).Get(resultEndFrame);
+
+      DALI_TEST_EQUALS(VECTOR_ANIMATION_MARKER_START_FRAME_2, resultStartFrame, TEST_LOCATION);
+      DALI_TEST_EQUALS(VECTOR_ANIMATION_MARKER_END_FRAME_2, resultEndFrame, TEST_LOCATION);
+    }
+    else
+    {
+      DALI_TEST_CHECK(false);
+    }
+  }
+
+  END_TEST;
+}
+
 int UtcDaliAnimatedVectorImageVisualAnimationFinishedSignal(void)
 {
   ToolkitTestApplication application;
index 0a82fb4..5ca6052 100644 (file)
@@ -3881,6 +3881,34 @@ void OnResourceReadySignal10(Control control)
   }
 }
 
+void OnResourceReadySignal11(Control control)
+{
+  gResourceReadySignalCounter++;
+
+  if(!gImageView2)
+  {
+    auto scene = gImageView1.GetParent();
+
+    // Try to load animated image visual here which is already cached, and then ignore forcely.
+
+    Property::Map map1;
+    map1[Toolkit::ImageVisual::Property::URL] = TEST_GIF_FILE_NAME;
+
+    gImageView2 = ImageView::New();
+    gImageView2.SetProperty(Toolkit::ImageView::Property::IMAGE, map1);
+
+    gImageView3 = ImageView::New();
+    gImageView3.SetProperty(Toolkit::ImageView::Property::IMAGE, map1);
+
+    scene.Add(gImageView2);
+    gImageView2.Unparent();
+
+    scene.Add(gImageView3);
+    gImageView3.Unparent();
+    gImageView3.Reset(); // Destroy visual
+  }
+}
+
 } // namespace
 
 int UtcDaliImageViewSetImageOnResourceReadySignal01(void)
@@ -4725,6 +4753,82 @@ int UtcDaliImageViewSetImageOnResourceReadySignal10(void)
   END_TEST;
 }
 
+int UtcDaliImageViewSetImageOnResourceReadySignal11(void)
+{
+  tet_infoline("Test ResourceReady Add AnimatedImageVisual and then Remove immediately.");
+
+  ToolkitTestApplication application;
+
+  gResourceReadySignalCounter = 0;
+
+  // Clear image view for clear test
+
+  if(gImageView1)
+  {
+    gImageView1.Reset();
+  }
+  if(gImageView2)
+  {
+    gImageView2.Reset();
+  }
+  if(gImageView3)
+  {
+    gImageView3.Reset();
+  }
+
+  try
+  {
+    gImageView1 = ImageView::New();
+    gImageView1.SetProperty(Toolkit::ImageView::Property::IMAGE, TEST_GIF_FILE_NAME);
+    gImageView1.ResourceReadySignal().Connect(&OnResourceReadySignal11);
+    application.GetScene().Add(gImageView1); // It will call resourceReady signal 1 time.
+
+    tet_printf("ResourceReady called %d times\n", gResourceReadySignalCounter);
+
+    DALI_TEST_EQUALS(gResourceReadySignalCounter, 0, TEST_LOCATION);
+
+    application.SendNotification();
+    application.Render();
+
+    // Load gImageView1
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+    tet_printf("ResourceReady called %d times\n", gResourceReadySignalCounter);
+
+    DALI_TEST_EQUALS(gResourceReadySignalCounter, 1, TEST_LOCATION);
+
+    DALI_TEST_CHECK(true);
+  }
+  catch(...)
+  {
+    // Exception should not happened
+    DALI_TEST_CHECK(false);
+  }
+
+  // Clear cache.
+  application.SendNotification();
+  application.Render();
+
+  gResourceReadySignalCounter = 0;
+
+  // Clear image view for clear test
+
+  if(gImageView1)
+  {
+    gImageView1.Reset();
+  }
+  if(gImageView2)
+  {
+    gImageView2.Reset();
+  }
+  if(gImageView3)
+  {
+    gImageView3.Reset();
+  }
+
+  END_TEST;
+}
+
 int UtcDaliImageViewUseSameUrlWithAnimatedImageVisual(void)
 {
   tet_infoline("Test multiple views with same image in animated image visual");
index 35dc49d..1677767 100644 (file)
@@ -133,7 +133,7 @@ enum Type
 
   /**
    * @brief The content information the AnimatedVectorImageVisual will use.
-   * @details Name "contentInfo", Type Property::MAP.
+   * @details Type Property::MAP.
    * The map contains the layer name as a key and Property::Array as a value.
    * And the array contains 2 integer values which are the frame numbers, the start frame number and the end frame number of the layer.
    * @note This property is read-only.
@@ -180,7 +180,16 @@ enum Type
    * Disable broken image for these visuals.
    * default is true.
    */
-  ENABLE_BROKEN_IMAGE = ORIENTATION_CORRECTION + 14
+  ENABLE_BROKEN_IMAGE = ORIENTATION_CORRECTION + 14,
+
+  /**
+   * @brief The marker information the AnimatedVectorImageVisual will use.
+   * @details Type Property::MAP.
+   * The map contains the marker name as a key and Property::Array as a value.
+   * And the array contains 2 integer values which are the frame numbers, the start frame number and the end frame number of the marker.
+   * @note This property is read-only.
+   */
+  MARKER_INFO = ORIENTATION_CORRECTION + 15,
 };
 
 } //namespace Property
index fc07dfb..ebefb94 100644 (file)
@@ -150,7 +150,7 @@ void FastTrackLoadingTask::Load()
   {
     std::ostringstream oss;
     oss << "[url:" << mUrl.GetUrl() << "]";
-    DALI_TRACE_BEGIN(gTraceFilter, "DALI_IMAGE_FAST_TRACK_UPLOADING_TASK");
+    // DALI_TRACE_BEGIN(gTraceFilter, "DALI_IMAGE_FAST_TRACK_UPLOADING_TASK"); ///< TODO : Open it if we can control trace log level
     DALI_LOG_RELEASE_INFO("BEGIN: DALI_IMAGE_FAST_TRACK_UPLOADING_TASK %s", oss.str().c_str());
   }
 #endif
@@ -228,7 +228,7 @@ void FastTrackLoadingTask::Load()
       oss << "premult:" << mPremultiplied << " ";
     }
     oss << "url:" << mUrl.GetUrl() << "]";
-    DALI_TRACE_END(gTraceFilter, "DALI_IMAGE_FAST_TRACK_UPLOADING_TASK");
+    // DALI_TRACE_END(gTraceFilter, "DALI_IMAGE_FAST_TRACK_UPLOADING_TASK"); ///< TODO : Open it if we can control trace log level
     DALI_LOG_RELEASE_INFO("END: DALI_IMAGE_FAST_TRACK_UPLOADING_TASK %s", oss.str().c_str());
   }
 #endif
index 2c08799..e26a927 100644 (file)
@@ -163,7 +163,7 @@ void LoadingTask::Process()
   {
     std::ostringstream oss;
     oss << "[url:" << (!!(animatedImageLoading) ? animatedImageLoading.GetUrl() : url.GetUrl()) << "]";
-    DALI_TRACE_BEGIN(gTraceFilter, "DALI_IMAGE_LOADING_TASK");
+    // DALI_TRACE_BEGIN(gTraceFilter, "DALI_IMAGE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
     DALI_LOG_RELEASE_INFO("BEGIN: DALI_IMAGE_LOADING_TASK %s", oss.str().c_str());
   }
 #endif
@@ -194,7 +194,7 @@ void LoadingTask::Process()
       oss << "premult:" << pixelBuffers[0].IsAlphaPreMultiplied() << " ";
     }
     oss << "url:" << (!!(animatedImageLoading) ? animatedImageLoading.GetUrl() : url.GetUrl()) << "]";
-    DALI_TRACE_END(gTraceFilter, "DALI_IMAGE_LOADING_TASK");
+    // DALI_TRACE_END(gTraceFilter, "DALI_IMAGE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
     DALI_LOG_RELEASE_INFO("END: DALI_IMAGE_LOADING_TASK %s", oss.str().c_str());
   }
 #endif
index 0dceae2..0c3e3dd 100644 (file)
@@ -585,7 +585,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
     if(textureInfo.loadState != LoadState::UPLOADED)
     {
       textureInfo.preMultiplied = (preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD);
-      textureInfo.loadState = TextureManager::LoadState::WAITING_FOR_MASK;
+      textureInfo.loadState     = TextureManager::LoadState::WAITING_FOR_MASK;
     }
   }
 
@@ -939,6 +939,8 @@ void TextureManager::LoadOrQueueTexture(TextureManager::TextureInfo& textureInfo
 
 void TextureManager::QueueLoadTexture(const TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer)
 {
+  DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "Add observer to observer queue (textureId:%d, observer:%p)\n", textureInfo.textureId, observer);
+
   const auto& textureId = textureInfo.textureId;
   mLoadQueue.PushBack(QueueElement(textureId, observer));
 
@@ -1413,6 +1415,7 @@ void TextureManager::ObserverDestroyed(TextureUploadObserver* observer)
   {
     if(element.mObserver == observer)
     {
+      DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "Remove observer from observer queue (textureId:%d, observer:%p)\n", element.mTextureId, element.mObserver);
       element.mTextureId = INVALID_TEXTURE_ID;
       element.mObserver  = nullptr;
     }
@@ -1515,6 +1518,22 @@ void TextureManager::RemoveTextureObserver(TextureManager::TextureInfo& textureI
       observer->DestructionSignal().Disconnect(this, &TextureManager::ObserverDestroyed);
       textureInfo.observerList.Erase(iter);
     }
+    else
+    {
+      // Given textureId might exist at load queue.
+      // Remove observer from the LoadQueue
+      for(auto&& element : mLoadQueue)
+      {
+        if(element.mTextureId == textureInfo.textureId && element.mObserver == observer)
+        {
+          DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "Remove observer from observer queue (textureId:%d, observer:%p)\n", element.mTextureId, element.mObserver);
+          DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "  Disconnect DestructionSignal to observer:%p\n", observer);
+          observer->DestructionSignal().Disconnect(this, &TextureManager::ObserverDestroyed);
+          element.mObserver = nullptr;
+          break;
+        }
+      }
+    }
   }
 }
 
index 09c4418..699c281 100644 (file)
@@ -210,6 +210,10 @@ void AnimatedVectorImageVisual::DoCreatePropertyMap(Property::Map& map) const
   mVectorAnimationTask->GetLayerInfo(layerInfo);
   map.Insert(Toolkit::DevelImageVisual::Property::CONTENT_INFO, layerInfo);
 
+  Property::Map markerInfo;
+  mVectorAnimationTask->GetMarkerInfo(markerInfo);
+  map.Insert(Toolkit::DevelImageVisual::Property::MARKER_INFO, markerInfo);
+
   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());
index c1e9d56..c0d3802 100644 (file)
@@ -150,7 +150,7 @@ bool VectorAnimationTask::Load(bool synchronousLoading)
   {
     std::ostringstream oss;
     oss << "[url:" << mImageUrl.GetUrl() << "]";
-    DALI_TRACE_BEGIN(gTraceFilter, "DALI_LOTTIE_LOADING_TASK");
+    // DALI_TRACE_BEGIN(gTraceFilter, "DALI_LOTTIE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
     DALI_LOG_RELEASE_INFO("BEGIN: DALI_LOTTIE_LOADING_TASK %s", oss.str().c_str());
   }
 #endif
@@ -195,7 +195,7 @@ bool VectorAnimationTask::Load(bool synchronousLoading)
     {
       std::ostringstream oss;
       oss << "[url:" << mImageUrl.GetUrl() << "]";
-      DALI_TRACE_END(gTraceFilter, "DALI_LOTTIE_LOADING_TASK");
+      // DALI_TRACE_END(gTraceFilter, "DALI_LOTTIE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
       DALI_LOG_RELEASE_INFO("END: DALI_LOTTIE_LOADING_TASK %s", oss.str().c_str());
     }
 #endif
@@ -222,7 +222,7 @@ bool VectorAnimationTask::Load(bool synchronousLoading)
   {
     std::ostringstream oss;
     oss << "[url:" << mImageUrl.GetUrl() << "]";
-    DALI_TRACE_END(gTraceFilter, "DALI_LOTTIE_LOADING_TASK");
+    // DALI_TRACE_END(gTraceFilter, "DALI_LOTTIE_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
     DALI_LOG_RELEASE_INFO("END: DALI_LOTTIE_LOADING_TASK %s", oss.str().c_str());
   }
 #endif
@@ -487,6 +487,11 @@ void VectorAnimationTask::GetLayerInfo(Property::Map& map) const
   mVectorRenderer.GetLayerInfo(map);
 }
 
+void VectorAnimationTask::GetMarkerInfo(Property::Map& map) const
+{
+  mVectorRenderer.GetMarkerInfo(map);
+}
+
 VectorAnimationTask::ResourceReadySignalType& VectorAnimationTask::ResourceReadySignal()
 {
   return mResourceReadySignal;
index 123d685..367fc8a 100644 (file)
@@ -218,6 +218,12 @@ public:
   void GetLayerInfo(Property::Map& map) const;
 
   /**
+   * @brief Gets the all marker information.
+   * @param[out] map The marker information
+   */
+  void GetMarkerInfo(Property::Map& map) const;
+
+  /**
    * @brief Connect to this signal to be notified when the resource is ready.
    * @return The signal to connect to.
    */
index 5f8ed8c..9939dc7 100644 (file)
@@ -90,7 +90,7 @@ void SvgLoadingTask::Process()
   {
     std::ostringstream oss;
     oss << "[url:" << mImageUrl.GetUrl() << "]";
-    DALI_TRACE_BEGIN(gTraceFilter, "DALI_SVG_LOADING_TASK");
+    // DALI_TRACE_BEGIN(gTraceFilter, "DALI_SVG_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
     DALI_LOG_RELEASE_INFO("BEGIN: DALI_SVG_LOADING_TASK %s", oss.str().c_str());
   }
 #endif
@@ -144,7 +144,7 @@ void SvgLoadingTask::Process()
     std::ostringstream oss;
     oss << "[success:" << mHasSucceeded << " ";
     oss << "url:" << mImageUrl.GetUrl() << "]";
-    DALI_TRACE_END(gTraceFilter, "DALI_SVG_LOADING_TASK");
+    // DALI_TRACE_END(gTraceFilter, "DALI_SVG_LOADING_TASK"); ///< TODO : Open it if we can control trace log level
     DALI_LOG_RELEASE_INFO("END: DALI_SVG_LOADING_TASK %s", oss.str().c_str());
   }
 #endif