Add DesiredWidth/Height and samplingMode in animated image visual 95/284695/6
authorseungho <sbsh.baek@samsung.com>
Tue, 28 Dec 2021 08:28:07 +0000 (17:28 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Sat, 26 Nov 2022 07:52:46 +0000 (16:52 +0900)
Let AnimatedImageVisual also use DesiredSize / FittingMode / SamplingMode feature.

Change-Id: Icd2205738a6d9c7af0f2aa06c7887ac9ea85b576

21 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals-internal.cpp
automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp
dali-toolkit/internal/image-loader/async-image-loader-impl.cpp
dali-toolkit/internal/image-loader/async-image-loader-impl.h
dali-toolkit/internal/image-loader/loading-task.cpp
dali-toolkit/internal/image-loader/loading-task.h
dali-toolkit/internal/texture-manager/texture-async-loading-helper.cpp
dali-toolkit/internal/texture-manager/texture-async-loading-helper.h
dali-toolkit/internal/texture-manager/texture-manager-impl.cpp
dali-toolkit/internal/texture-manager/texture-manager-impl.h
dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp
dali-toolkit/internal/visuals/animated-image/animated-image-visual.h
dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h
dali-toolkit/internal/visuals/animated-image/image-cache.cpp
dali-toolkit/internal/visuals/animated-image/image-cache.h
dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h
dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h
dali-toolkit/internal/visuals/visual-factory-impl.cpp

index 4134db6..77b2d14 100644 (file)
@@ -39,8 +39,9 @@ using namespace Toolkit;
 namespace
 {
 const char* TEST_VECTOR_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/insta_camera.json";
+const char* TEST_GIF_FILE_NAME          = TEST_RESOURCE_DIR "/anim.gif";
 
-}
+} // namespace
 
 int UtcDaliVisualAction(void)
 {
@@ -185,6 +186,43 @@ int UtcDaliAnimatedVectorImageVisualCreateInstancePropertyMap(void)
   END_TEST;
 }
 
+int UtcDaliAnimatedImageVisualCreateInstancePropertyMap(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliAnimatedImageVisualCreateInstancePropertyMap");
+
+  Property::Map propertyMap;
+  propertyMap.Add(Toolkit::Visual::Property::TYPE, Visual::ANIMATED_IMAGE)
+    .Add(ImageVisual::Property::URL, TEST_GIF_FILE_NAME)
+    .Add(ImageVisual::Property::DESIRED_WIDTH, 10)
+    .Add(ImageVisual::Property::DESIRED_HEIGHT, 12);
+
+  // request AnimatedVectorImageVisual with a property map
+  VisualFactory                    factory    = VisualFactory::Get();
+  Visual::Base                     visual     = factory.CreateVisual(propertyMap);
+  Toolkit::Internal::Visual::Base& visualImpl = GetImplementation(visual);
+
+  Property::Map resultMap;
+  visualImpl.CreateInstancePropertyMap(resultMap);
+
+  // check the property values from the returned map from a visual
+  DALI_TEST_EQUALS(resultMap.Count(), 3u, TEST_LOCATION);
+
+  Property::Value* value = resultMap.Find(Toolkit::Visual::Property::TYPE, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == Visual::ANIMATED_IMAGE);
+
+  value = resultMap.Find(Toolkit::ImageVisual::Property::DESIRED_WIDTH, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == 10);
+
+  value = resultMap.Find(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == 12);
+
+  END_TEST;
+}
+
 int UtcDaliAnimatedVectorImageVisualSetProperties(void)
 {
   ToolkitTestApplication application;
index 9870308..3c23a06 100644 (file)
@@ -80,6 +80,10 @@ int UtcDaliAnimatedImageVisualGetPropertyMap01(void)
       .Add(ImageVisual::Property::PIXEL_AREA, Vector4())
       .Add(ImageVisual::Property::WRAP_MODE_U, WrapMode::REPEAT)
       .Add(ImageVisual::Property::WRAP_MODE_V, WrapMode::DEFAULT)
+      .Add(ImageVisual::Property::FITTING_MODE, FittingMode::FIT_WIDTH)
+      .Add(ImageVisual::Property::SAMPLING_MODE, SamplingMode::NEAREST)
+      .Add(ImageVisual::Property::DESIRED_WIDTH, 154)
+      .Add(ImageVisual::Property::DESIRED_HEIGHT, 79)
       .Add(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME)
       .Add(ImageVisual::Property::MASK_CONTENT_SCALE, 1.6f)
       .Add(ImageVisual::Property::CROP_TO_MASK, true)
@@ -101,6 +105,30 @@ int UtcDaliAnimatedImageVisualGetPropertyMap01(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_CHECK(value->Get<std::string>() == TEST_GIF_FILE_NAME);
 
+  value = resultMap.Find(Toolkit::ImageVisual::Property::WRAP_MODE_U, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == WrapMode::REPEAT);
+
+  value = resultMap.Find(Toolkit::ImageVisual::Property::WRAP_MODE_V, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == WrapMode::DEFAULT);
+
+  value = resultMap.Find(Toolkit::ImageVisual::Property::FITTING_MODE, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == FittingMode::FIT_WIDTH);
+
+  value = resultMap.Find(Toolkit::ImageVisual::Property::SAMPLING_MODE, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == SamplingMode::NEAREST);
+
+  value = resultMap.Find(Toolkit::ImageVisual::Property::DESIRED_WIDTH, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == 154);
+
+  value = resultMap.Find(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == 79);
+
   value = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::VECTOR4);
   DALI_TEST_CHECK(value);
   DALI_TEST_EQUALS(value->Get<Vector4>(), Vector4(22.2f, 22.2f, 22.2f, 22.2f), TEST_LOCATION);
@@ -138,9 +166,10 @@ int UtcDaliAnimatedImageVisualGetPropertyMap01(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_CHECK(value->Get<int>() == DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
 
+  // Natural size getted as desired size
   Vector2 naturalSize;
   animatedImageVisual.GetNaturalSize(naturalSize);
-  DALI_TEST_EQUALS(naturalSize, Vector2(100, 100), TEST_LOCATION);
+  DALI_TEST_EQUALS(naturalSize, Vector2(154, 79), TEST_LOCATION);
 
   // request AnimatedImageVisual with an URL
   Visual::Base animatedImageVisual2 = factory.CreateVisual(TEST_GIF_FILE_NAME, ImageDimensions());
@@ -155,6 +184,10 @@ int UtcDaliAnimatedImageVisualGetPropertyMap01(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_CHECK(value->Get<std::string>() == TEST_GIF_FILE_NAME);
 
+  // Natural size getted as image size
+  animatedImageVisual2.GetNaturalSize(naturalSize);
+  DALI_TEST_EQUALS(naturalSize, Vector2(50, 50), TEST_LOCATION);
+
   END_TEST;
 }
 
@@ -179,6 +212,10 @@ int UtcDaliAnimatedImageVisualGetPropertyMap02(void)
       .Add("pixelArea", Vector4())
       .Add("wrapModeU", WrapMode::REPEAT)
       .Add("wrapModeV", WrapMode::DEFAULT)
+      .Add("fittingMode", FittingMode::FIT_WIDTH)
+      .Add("samplingMode", SamplingMode::NEAREST)
+      .Add("desiredWidth", 154)
+      .Add("desiredHeight", 79)
       .Add("alphaMaskUrl", TEST_MASK_IMAGE_FILE_NAME)
       .Add("maskContentScale", 1.6f)
       .Add("cropToMask", true)
@@ -222,6 +259,30 @@ int UtcDaliAnimatedImageVisualGetPropertyMap02(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_EQUALS(value->Get<int>(), 11, TEST_LOCATION);
 
+  value = resultMap.Find(Toolkit::ImageVisual::Property::WRAP_MODE_U, "wrapModeU");
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == WrapMode::REPEAT);
+
+  value = resultMap.Find(Toolkit::ImageVisual::Property::WRAP_MODE_V, "wrapModeV");
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == WrapMode::DEFAULT);
+
+  value = resultMap.Find(Toolkit::ImageVisual::Property::FITTING_MODE, "fittingMode");
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == FittingMode::FIT_WIDTH);
+
+  value = resultMap.Find(Toolkit::ImageVisual::Property::SAMPLING_MODE, "samplingMode");
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == SamplingMode::NEAREST);
+
+  value = resultMap.Find(Toolkit::ImageVisual::Property::DESIRED_WIDTH, "desiredWidth");
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == 154);
+
+  value = resultMap.Find(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, "desiredHeight");
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<int>() == 79);
+
   value = resultMap.Find(Toolkit::DevelVisual::Property::CORNER_RADIUS, "cornerRadius");
   DALI_TEST_CHECK(value);
   DALI_TEST_EQUALS(value->Get<Vector4>(), Vector4(50.0f, 25.0f, 12.5f, 33.0f), TEST_LOCATION);
@@ -359,6 +420,11 @@ int UtcDaliAnimatedImageVisualGetPropertyMap03(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_CHECK(value->Get<bool>() == DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
 
+  // Natural size getted as masked image size
+  Vector2 naturalSize;
+  animatedImageVisual.GetNaturalSize(naturalSize);
+  DALI_TEST_EQUALS(naturalSize, Vector2(100, 100), TEST_LOCATION);
+
   END_TEST;
 }
 
@@ -1792,7 +1858,7 @@ int UtcDaliAnimatedImageVisualWrapMode(void)
   // Test wrap mode in animated image visual.
   const int     width  = 950;
   const int     height = 1080;
-  const Vector4 pixelArea(0.0f, 0.0f, 950/ 40, 1.0f);
+  const Vector4 pixelArea(0.0f, 0.0f, 950 / 40, 1.0f);
 
   Property::Map propertyMap;
   propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE);
@@ -1848,3 +1914,72 @@ int UtcDaliAnimatedImageVisualWrapMode(void)
 
   END_TEST;
 }
+
+int UtcDaliAnimatedImageVisualDesiredSize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliAnimatedImageVisualDesiredSize");
+
+  TestGlAbstraction& gl           = application.GetGlAbstraction();
+  TraceCallStack&    textureTrace = gl.GetTextureTrace();
+
+  // Set desiredWidth < 37 and desiredHeight < 50, which is smaller than original image's size.
+  int desiredWidth  = 15;
+  int desiredHeight = 20;
+
+  Visual::Base visual = VisualFactory::Get().CreateVisual(TEST_GIF_FILE_NAME, ImageDimensions(desiredWidth, desiredHeight));
+  DALI_TEST_CHECK(visual);
+
+  DummyControl      actor     = DummyControl::New(true);
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 2 - first frame and second frame.
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+  textureTrace.Enable(true);
+  textureTrace.EnableLogging(true);
+
+  application.SendNotification();
+  application.Render();
+
+  {
+    std::stringstream out;
+    out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight;
+    DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str()));
+  }
+
+  // Unparent to make next trigger
+  actor.Unparent();
+
+  application.SendNotification();
+  application.Render();
+
+  // Set visual size
+  actor.SetProperty(Actor::Property::SIZE, Vector2(300.0f, 300.0f));
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 2 - first frame and second frame.
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+  textureTrace.Reset();
+
+  application.SendNotification();
+  application.Render();
+
+  {
+    std::stringstream out;
+    out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight;
+    DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str())); // The size should not be changed
+  }
+
+  END_TEST;
+}
\ No newline at end of file
index 7ce566e..0a0338f 100644 (file)
@@ -19,8 +19,8 @@
 #include "async-image-loader-impl.h"
 
 // EXTERNAL INCLUDES
-#include <dali/public-api/adaptor-framework/async-task-manager.h>
 #include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/public-api/adaptor-framework/async-task-manager.h>
 
 namespace Dali
 {
@@ -49,7 +49,19 @@ uint32_t AsyncImageLoader::LoadAnimatedImage(Dali::AnimatedImageLoading
                                              uint32_t                                 frameIndex,
                                              DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad)
 {
-  LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, animatedImageLoading, frameIndex, preMultiplyOnLoad,MakeCallback(this, &AsyncImageLoader::ProcessLoadedImage));
+  LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, animatedImageLoading, frameIndex, preMultiplyOnLoad, MakeCallback(this, &AsyncImageLoader::ProcessLoadedImage));
+  Dali::AsyncTaskManager::Get().AddTask(loadingTask);
+  return mLoadTaskId;
+}
+
+uint32_t AsyncImageLoader::LoadAnimatedImage(Dali::AnimatedImageLoading               animatedImageLoading,
+                                             uint32_t                                 frameIndex,
+                                             Dali::ImageDimensions                    desiredSize,
+                                             Dali::FittingMode::Type                  fittingMode,
+                                             Dali::SamplingMode::Type                 samplingMode,
+                                             DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad)
+{
+  LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, animatedImageLoading, frameIndex, desiredSize, fittingMode, samplingMode, preMultiplyOnLoad, MakeCallback(this, &AsyncImageLoader::ProcessLoadedImage));
   Dali::AsyncTaskManager::Get().AddTask(loadingTask);
   return mLoadTaskId;
 }
@@ -64,7 +76,7 @@ uint32_t AsyncImageLoader::Load(const VisualUrl&                         url,
 {
   LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, url, dimensions, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad, loadPlanes, MakeCallback(this, &AsyncImageLoader::ProcessLoadedImage));
   AsyncTaskManager::Get().AddTask(loadingTask);
-  mLoadingTasks.push_back(AsyncImageLoadingInfo(loadingTask,mLoadTaskId));
+  mLoadingTasks.push_back(AsyncImageLoadingInfo(loadingTask, mLoadTaskId));
   return mLoadTaskId;
 }
 
@@ -77,7 +89,7 @@ uint32_t AsyncImageLoader::LoadEncodedImageBuffer(const EncodedImageBuffer&
 {
   LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, encodedImageBuffer, dimensions, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad, MakeCallback(this, &AsyncImageLoader::ProcessLoadedImage));
   Dali::AsyncTaskManager::Get().AddTask(loadingTask);
-  mLoadingTasks.push_back(AsyncImageLoadingInfo(loadingTask,mLoadTaskId));
+  mLoadingTasks.push_back(AsyncImageLoadingInfo(loadingTask, mLoadTaskId));
   return mLoadTaskId;
 }
 
@@ -89,7 +101,7 @@ uint32_t AsyncImageLoader::ApplyMask(Devel::PixelBuffer                       pi
 {
   LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, pixelBuffer, maskPixelBuffer, contentScale, cropToMask, preMultiplyOnLoad, MakeCallback(this, &AsyncImageLoader::ProcessLoadedImage));
   Dali::AsyncTaskManager::Get().AddTask(loadingTask);
-  mLoadingTasks.push_back(AsyncImageLoadingInfo(loadingTask,mLoadTaskId));
+  mLoadingTasks.push_back(AsyncImageLoadingInfo(loadingTask, mLoadTaskId));
   return mLoadTaskId;
 }
 
@@ -160,8 +172,8 @@ void AsyncImageLoader::ProcessLoadedImage(LoadingTaskPtr task)
 void AsyncImageLoader::RemoveCompletedTask()
 {
   std::uint32_t loadingTaskId;
-  auto end = mLoadingTasks.end();
-  auto endCompletedIter = mCompletedTaskIds.end();
+  auto          end              = mLoadingTasks.end();
+  auto          endCompletedIter = mCompletedTaskIds.end();
   for(std::vector<AsyncImageLoadingInfo>::iterator iter = mLoadingTasks.begin(); iter != end; ++iter)
   {
     loadingTaskId = (*iter).loadId;
index a75fa32..c23b102 100644 (file)
@@ -36,7 +36,7 @@ using LoadingTaskPtr = IntrusivePtr<LoadingTask>;
 
 struct AsyncImageLoadingInfo
 {
-  AsyncImageLoadingInfo(LoadingTaskPtr loadingTask,std::uint32_t loadId)
+  AsyncImageLoadingInfo(LoadingTaskPtr loadingTask, std::uint32_t loadId)
   : loadingTask(loadingTask),
     loadId(loadId)
   {
@@ -67,6 +67,24 @@ public:
                              DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
 
   /**
+   * @brief Starts an animated image loading task.
+   * @param[in] asyncImageLoader The ayncImageLoader
+   * @param[in] animatedImageLoading The AnimatedImageLoading to load animated image
+   * @param[in] frameIndex The frame index of a frame to be loaded frame
+   * @param[in] dimensions The width and height to fit the loaded image to
+   * @param[in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter
+   * @param[in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size
+   * @param[in] preMultiplyOnLoad ON if the image color should be multiplied by it's alpha. Set to OFF if there is no alpha or if the image need to be applied alpha mask.
+   * @return The loading task id
+   */
+  uint32_t LoadAnimatedImage(Dali::AnimatedImageLoading               animatedImageLoading,
+                             uint32_t                                 frameIndex,
+                             Dali::ImageDimensions                    desiredSize,
+                             Dali::FittingMode::Type                  fittingMode,
+                             Dali::SamplingMode::Type                 samplingMode,
+                             DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
+
+  /**
    * @brief Starts an image loading task.
    * @param[in] url The URL of the image file to load
    * @param[in] dimensions The width and height to fit the loaded image to
index 29f3bdb..11f83a8 100644 (file)
@@ -38,8 +38,30 @@ LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLo
   id(id),
   textureId(TextureManagerType::INVALID_TEXTURE_ID),
   dimensions(),
-  fittingMode(),
-  samplingMode(),
+  fittingMode(FittingMode::SCALE_TO_FILL),
+  samplingMode(SamplingMode::BOX_THEN_LINEAR),
+  preMultiplyOnLoad(preMultiplyOnLoad),
+  maskPixelBuffer(),
+  contentScale(1.0f),
+  animatedImageLoading(animatedImageLoading),
+  frameIndex(frameIndex),
+  orientationCorrection(),
+  isMaskTask(false),
+  cropToMask(false),
+  loadPlanes(false),
+  isReady(true)
+{
+}
+
+LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLoading, uint32_t frameIndex, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, CallbackBase* callback)
+: AsyncTask(callback),
+  url(),
+  encodedImageBuffer(),
+  id(id),
+  textureId(TextureManagerType::INVALID_TEXTURE_ID),
+  dimensions(dimensions),
+  fittingMode(fittingMode),
+  samplingMode(samplingMode),
   preMultiplyOnLoad(preMultiplyOnLoad),
   maskPixelBuffer(),
   contentScale(1.0f),
@@ -149,7 +171,7 @@ void LoadingTask::Load()
   Devel::PixelBuffer pixelBuffer;
   if(animatedImageLoading)
   {
-    pixelBuffer = animatedImageLoading.LoadFrame(frameIndex);
+    pixelBuffer = animatedImageLoading.LoadFrame(frameIndex, dimensions, fittingMode, samplingMode);
   }
   else if(encodedImageBuffer)
   {
index 09208b4..6072856 100644 (file)
 
 // EXTERNAL INCLUDES
 #include <dali-toolkit/devel-api/image-loader/async-image-loader-devel.h>
+#include <dali-toolkit/internal/texture-manager/texture-manager-type.h>
 #include <dali-toolkit/internal/visuals/visual-url.h>
-#include <dali/public-api/adaptor-framework/async-task-manager.h>
 #include <dali/devel-api/adaptor-framework/event-thread-callback.h>
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali/devel-api/threading/conditional-wait.h>
 #include <dali/devel-api/threading/mutex.h>
 #include <dali/devel-api/threading/thread.h>
 #include <dali/integration-api/adaptor-framework/log-factory-interface.h>
+#include <dali/public-api/adaptor-framework/async-task-manager.h>
 #include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/images/image-operations.h>
 #include <dali/public-api/object/ref-object.h>
-#include <dali-toolkit/internal/texture-manager/texture-manager-type.h>
 
 namespace Dali
 {
@@ -39,7 +39,6 @@ namespace Toolkit
 {
 namespace Internal
 {
-
 class LoadingTask;
 using LoadingTaskPtr = IntrusivePtr<LoadingTask>;
 
@@ -66,6 +65,26 @@ public:
   /**
    * Constructor.
    * @param [in] id of the task
+   * @param [in] animatedImageLoading The AnimatedImageLoading to load animated image
+   * @param [in] frameIndex The frame index of a frame to be loaded frame
+   * @param [in] dimensions The width and height to fit the loaded image to
+   * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter
+   * @param [in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size
+   * @param [in] preMultiplyOnLoad ON if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha or if the image need to be applied alpha mask.
+   * @param [in] callback The callback that is called when the operation is completed.
+   */
+  LoadingTask(uint32_t                                 id,
+              Dali::AnimatedImageLoading               animatedImageLoading,
+              uint32_t                                 frameIndex,
+              Dali::ImageDimensions                    dimensions,
+              Dali::FittingMode::Type                  fittingMode,
+              Dali::SamplingMode::Type                 samplingMode,
+              DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad,
+              CallbackBase*                            callback);
+
+  /**
+   * Constructor.
+   * @param [in] id of the task
    * @param [in] url The URL of the image file to load.
    * @param [in] size The width and height to fit the loaded image to, 0.0 means whole image
    * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
@@ -188,7 +207,7 @@ public:
   bool isMaskTask : 1;            ///< whether this task is for mask or not
   bool cropToMask : 1;            ///< Whether to crop the content to the mask size
   bool loadPlanes : 1;            ///< Whether to load image planes
-  bool isReady    : 1;            ///< Whether this task ready to run
+  bool isReady : 1;               ///< Whether this task ready to run
 };
 
 } // namespace Internal
index 87d3fa6..9927ea2 100644 (file)
@@ -44,9 +44,12 @@ TextureAsyncLoadingHelper::TextureAsyncLoadingHelper(TextureManager& textureMana
 void TextureAsyncLoadingHelper::LoadAnimatedImage(const TextureManager::TextureId&                textureId,
                                                   Dali::AnimatedImageLoading                      animatedImageLoading,
                                                   const std::uint32_t&                            frameIndex,
+                                                  const Dali::ImageDimensions&                    desiredSize,
+                                                  const Dali::FittingMode::Type&                  fittingMode,
+                                                  const Dali::SamplingMode::Type&                 samplingMode,
                                                   const DevelAsyncImageLoader::PreMultiplyOnLoad& preMultiplyOnLoad)
 {
-  LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, animatedImageLoading, frameIndex, preMultiplyOnLoad, MakeCallback(this, &TextureAsyncLoadingHelper::AsyncLoadComplete));
+  LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, animatedImageLoading, frameIndex, desiredSize, fittingMode, samplingMode, preMultiplyOnLoad, MakeCallback(this, &TextureAsyncLoadingHelper::AsyncLoadComplete));
   loadingTask->SetTextureId(textureId);
   Dali::AsyncTaskManager::Get().AddTask(loadingTask);
 }
@@ -81,7 +84,6 @@ void TextureAsyncLoadingHelper::ApplyMask(const TextureManager::TextureId&
                                           const bool&                                     cropToMask,
                                           const DevelAsyncImageLoader::PreMultiplyOnLoad& preMultiplyOnLoad)
 {
-
   LoadingTaskPtr loadingTask = new LoadingTask(++mLoadTaskId, pixelBuffer, maskPixelBuffer, contentScale, cropToMask, preMultiplyOnLoad, MakeCallback(this, &TextureAsyncLoadingHelper::AsyncLoadComplete));
   loadingTask->SetTextureId(textureId);
   Dali::AsyncTaskManager::Get().AddTask(loadingTask);
index d993737..15e1d4e 100644 (file)
@@ -31,7 +31,6 @@ namespace Toolkit
 {
 namespace Internal
 {
-
 /**
  * @brief Helper class to keep the relation between AsyncImageLoader and corresponding LoadingInfo container
  */
@@ -49,11 +48,18 @@ public:
    * @param[in] textureId             TextureId to reference the texture that will be loaded
    * @param[in] animatedImageLoading  The AnimatedImageLoading to load animated image
    * @param[in] frameIndex            The frame index of a frame to be loaded frame
+   * @param[in] desiredSize           The size the image is likely to appear at.
+   *                                  This can be set to 0,0 for automatic
+   * @param[in] fittingMode           The FittingMode to use
+   * @param[in] samplingMode          The SamplingMode to use
    * @param[in] preMultiplyOnLoad     if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha or if the image need to be applied alpha mask.
    */
   void LoadAnimatedImage(const TextureManager::TextureId&                textureId,
                          Dali::AnimatedImageLoading                      animatedImageLoading,
                          const std::uint32_t&                            frameIndex,
+                         const Dali::ImageDimensions&                    desiredSize,
+                         const Dali::FittingMode::Type&                  fittingMode,
+                         const Dali::SamplingMode::Type&                 samplingMode,
                          const DevelAsyncImageLoader::PreMultiplyOnLoad& preMultiplyOnLoad);
 
   /**
index 8930d2d..0984e2f 100644 (file)
@@ -33,7 +33,7 @@
 
 namespace
 {
-constexpr auto INITIAL_HASH_NUMBER                     = size_t{0u};
+constexpr auto INITIAL_HASH_NUMBER = size_t{0u};
 
 constexpr auto TEXTURE_INDEX      = 0u; ///< The Index for texture
 constexpr auto MASK_TEXTURE_INDEX = 1u; ///< The Index for mask texture
@@ -135,6 +135,8 @@ TextureSet TextureManager::LoadAnimatedImageTexture(
   const uint32_t&                 frameIndex,
   TextureManager::TextureId&      textureId,
   MaskingDataPointer&             maskInfo,
+  const Dali::ImageDimensions&    desiredSize,
+  const Dali::FittingMode::Type&  fittingMode,
   const Dali::SamplingMode::Type& samplingMode,
   const bool&                     synchronousLoading,
   TextureUploadObserver*          textureObserver,
@@ -147,7 +149,7 @@ TextureSet TextureManager::LoadAnimatedImageTexture(
     Devel::PixelBuffer pixelBuffer;
     if(animatedImageLoading)
     {
-      pixelBuffer = animatedImageLoading.LoadFrame(frameIndex);
+      pixelBuffer = animatedImageLoading.LoadFrame(frameIndex, desiredSize, fittingMode, samplingMode);
     }
     if(!pixelBuffer)
     {
@@ -158,7 +160,7 @@ TextureSet TextureManager::LoadAnimatedImageTexture(
       Texture maskTexture;
       if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
       {
-        Devel::PixelBuffer maskPixelBuffer = LoadImageFromFile(maskInfo->mAlphaMaskUrl.GetUrl(), ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, true);
+        Devel::PixelBuffer maskPixelBuffer = LoadImageFromFile(maskInfo->mAlphaMaskUrl.GetUrl(), desiredSize, fittingMode, samplingMode, true);
         if(maskPixelBuffer)
         {
           if(!maskInfo->mPreappliedMasking)
@@ -213,7 +215,7 @@ TextureSet TextureManager::LoadAnimatedImageTexture(
       }
     }
 
-    textureId = RequestLoadInternal(url, alphaMaskId, contentScaleFactor, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, UseAtlas::NO_ATLAS, cropToMask, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad, animatedImageLoading, frameIndex, false);
+    textureId = RequestLoadInternal(url, alphaMaskId, contentScaleFactor, desiredSize, fittingMode, samplingMode, UseAtlas::NO_ATLAS, cropToMask, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad, animatedImageLoading, frameIndex, false);
 
     TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
     if(loadState == TextureManager::LoadState::UPLOADED)
@@ -875,10 +877,10 @@ void TextureManager::LoadTexture(TextureManager::TextureInfo& textureInfo, Textu
   textureInfo.loadState = LoadState::LOADING;
   if(!textureInfo.loadSynchronously)
   {
-    auto  premultiplyOnLoad = (textureInfo.preMultiplyOnLoad && textureInfo.maskTextureId == INVALID_TEXTURE_ID) ? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF;
+    auto premultiplyOnLoad = (textureInfo.preMultiplyOnLoad && textureInfo.maskTextureId == INVALID_TEXTURE_ID) ? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF;
     if(textureInfo.animatedImageLoading)
     {
-      mAsyncLoader->LoadAnimatedImage(textureInfo.textureId, textureInfo.animatedImageLoading, textureInfo.frameIndex, premultiplyOnLoad);
+      mAsyncLoader->LoadAnimatedImage(textureInfo.textureId, textureInfo.animatedImageLoading, textureInfo.frameIndex, textureInfo.desiredSize, textureInfo.fittingMode, textureInfo.samplingMode, premultiplyOnLoad);
     }
     else
     {
@@ -1194,7 +1196,7 @@ void TextureManager::ApplyMask(TextureManager::TextureInfo& textureInfo, const T
 
     DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::ApplyMask(): url:%s sync:%s\n", textureInfo.url.GetUrl().c_str(), textureInfo.loadSynchronously ? "T" : "F");
 
-    textureInfo.loadState   = LoadState::MASK_APPLYING;
+    textureInfo.loadState  = LoadState::MASK_APPLYING;
     auto premultiplyOnLoad = textureInfo.preMultiplyOnLoad ? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF;
     mAsyncLoader->ApplyMask(textureInfo.textureId, pixelBuffer, maskPixelBuffer, textureInfo.scaleFactor, textureInfo.cropToMask, premultiplyOnLoad);
   }
index 791553c..54db840 100644 (file)
@@ -21,9 +21,9 @@
 #include <dali/devel-api/adaptor-framework/animated-image-loading.h>
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
+#include <dali/public-api/adaptor-framework/round-robin-container-view.h>
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/rendering/geometry.h>
-#include <dali/public-api/adaptor-framework/round-robin-container-view.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
@@ -119,6 +119,8 @@ public:
    * @param[in]  frameIndex            The frame index to load.
    * @param[out] textureId             The textureId of the frame
    * @param[in, out] maskInfo          Mask info structure
+   * @param[in]  desiredSize           The size the image is likely to appear at. This can be set to 0, 0 for automatic
+   * @param[in]  fittingMode           The FittingMode to use
    * @param[in]  samplingMode          The SamplingMode to use
    * @param[in]  synchronousLoading    true if the frame should be loaded synchronously
    * @param[in]  textureObserver       The client object should inherit from this and provide the "LoadCompleted" virtual.
@@ -133,6 +135,8 @@ public:
                                       const uint32_t&                 frameIndex,
                                       TextureManager::TextureId&      textureId,
                                       MaskingDataPointer&             maskInfo,
+                                      const Dali::ImageDimensions&    desiredSize,
+                                      const Dali::FittingMode::Type&  fittingMode,
                                       const Dali::SamplingMode::Type& samplingMode,
                                       const bool&                     synchronousLoading,
                                       TextureUploadObserver*          textureObserver,
@@ -612,7 +616,6 @@ private:
    */
   void EmitLoadComplete(TextureUploadObserver* observer, TextureManager::TextureInfo& textureInfo, const bool& success);
 
-
   /**
    * @brief Remove observer in textureInfo
    *
@@ -648,14 +651,14 @@ private:
    */
   void ObserverDestroyed(TextureUploadObserver* observer);
 
-private:                                    // Member Variables:
-  TextureCacheManager mTextureCacheManager; ///< Manager the life-cycle and caching of Textures
-  std::unique_ptr<TextureAsyncLoadingHelper> mAsyncLoader;  ///< The Asynchronous image loader used to provide all local async loads
-  Dali::Vector<LifecycleObserver*>        mLifecycleObservers;      ///< Lifecycle observers of texture manager
-  Dali::Vector<QueueElement>              mLoadQueue;               ///< Queue of textures to load after NotifyObservers
-  Dali::Vector<QueueElement>              mRemoveQueue;             ///< Queue of textures to remove after NotifyObservers
-  TextureManager::TextureId               mLoadingQueueTextureId;   ///< TextureId when it is loading. it causes Load Textures to be queued.
-  bool                                    mLoadYuvPlanes;           ///< A global flag to specify if the image should be loaded as yuv planes
+private:                                                             // Member Variables:
+  TextureCacheManager                        mTextureCacheManager;   ///< Manager the life-cycle and caching of Textures
+  std::unique_ptr<TextureAsyncLoadingHelper> mAsyncLoader;           ///< The Asynchronous image loader used to provide all local async loads
+  Dali::Vector<LifecycleObserver*>           mLifecycleObservers;    ///< Lifecycle observers of texture manager
+  Dali::Vector<QueueElement>                 mLoadQueue;             ///< Queue of textures to load after NotifyObservers
+  Dali::Vector<QueueElement>                 mRemoveQueue;           ///< Queue of textures to remove after NotifyObservers
+  TextureManager::TextureId                  mLoadingQueueTextureId; ///< TextureId when it is loading. it causes Load Textures to be queued.
+  bool                                       mLoadYuvPlanes;         ///< A global flag to specify if the image should be loaded as yuv planes
 };
 
 } // namespace Internal
index db00ff5..3e8387f 100644 (file)
@@ -49,6 +49,26 @@ namespace
 {
 const int CUSTOM_PROPERTY_COUNT(5); // ltr, wrap, pixel area, crop to mask, mask texture ratio
 
+// fitting modes
+DALI_ENUM_TO_STRING_TABLE_BEGIN(FITTING_MODE)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, SHRINK_TO_FIT)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, SCALE_TO_FILL)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, FIT_WIDTH)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, FIT_HEIGHT)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, DEFAULT)
+DALI_ENUM_TO_STRING_TABLE_END(FITTING_MODE)
+
+// sampling modes
+DALI_ENUM_TO_STRING_TABLE_BEGIN(SAMPLING_MODE)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, BOX)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, NEAREST)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, LINEAR)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, BOX_THEN_NEAREST)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, BOX_THEN_LINEAR)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, NO_FILTER)
+  DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::SamplingMode, DONT_CARE)
+DALI_ENUM_TO_STRING_TABLE_END(SAMPLING_MODE)
+
 // stop behavior
 DALI_ENUM_TO_STRING_TABLE_BEGIN(STOP_BEHAVIOR)
   DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::Toolkit::DevelImageVisual::StopBehavior, CURRENT_FRAME)
@@ -124,7 +144,7 @@ Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, "
 
 AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties)
 {
-  AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory));
+  AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory, ImageDimensions()));
   visual->InitializeAnimatedImage(imageUrl);
   visual->SetProperties(properties);
 
@@ -135,7 +155,7 @@ AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache
 
 AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const Property::Array& imageUrls, const Property::Map& properties)
 {
-  AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory));
+  AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory, ImageDimensions()));
   visual->mImageUrls = new ImageCache::UrlList();
   visual->mImageUrls->reserve(imageUrls.Count());
 
@@ -154,9 +174,9 @@ AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache
   return visual;
 }
 
-AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl)
+AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size)
 {
-  AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory));
+  AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory, size));
   visual->InitializeAnimatedImage(imageUrl);
 
   visual->Initialize();
@@ -178,7 +198,7 @@ void AnimatedImageVisual::CreateImageCache()
 
   if(mAnimatedImageLoading)
   {
-    mImageCache = new RollingAnimatedImageCache(textureManager, mAnimatedImageLoading, mMaskingData, *this, mCacheSize, mBatchSize,  mWrapModeU, mWrapModeV, IsSynchronousLoadingRequired(), mFactoryCache.GetPreMultiplyOnLoad());
+    mImageCache = new RollingAnimatedImageCache(textureManager, mDesiredSize, mFittingMode, mSamplingMode, mAnimatedImageLoading, mMaskingData, *this, mCacheSize, mBatchSize, mWrapModeU, mWrapModeV, IsSynchronousLoadingRequired(), mFactoryCache.GetPreMultiplyOnLoad());
   }
   else if(mImageUrls)
   {
@@ -189,11 +209,11 @@ void AnimatedImageVisual::CreateImageCache()
     uint16_t cacheSize = std::max(std::min(std::max(batchSize, mCacheSize), numUrls), MINIMUM_CACHESIZE);
     if(cacheSize < numUrls)
     {
-      mImageCache = new RollingImageCache(textureManager, *mImageUrls, mMaskingData, *this, cacheSize, batchSize, mFrameDelay);
+      mImageCache = new RollingImageCache(textureManager, mDesiredSize, mFittingMode, mSamplingMode, *mImageUrls, mMaskingData, *this, cacheSize, batchSize, mFrameDelay);
     }
     else
     {
-      mImageCache = new FixedImageCache(textureManager, *mImageUrls, mMaskingData, *this, batchSize, mFrameDelay);
+      mImageCache = new FixedImageCache(textureManager, mDesiredSize, mFittingMode, mSamplingMode, *mImageUrls, mMaskingData, *this, batchSize, mFrameDelay);
     }
   }
 
@@ -203,7 +223,7 @@ void AnimatedImageVisual::CreateImageCache()
   }
 }
 
-AnimatedImageVisual::AnimatedImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory)
+AnimatedImageVisual::AnimatedImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, ImageDimensions desiredSize)
 : Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::ANIMATED_IMAGE),
   mFrameDelayTimer(),
   mPlacementActor(),
@@ -223,11 +243,14 @@ AnimatedImageVisual::AnimatedImageVisual(VisualFactoryCache& factoryCache, Image
   mLoadPolicy(Toolkit::ImageVisual::LoadPolicy::ATTACHED),
   mReleasePolicy(Toolkit::ImageVisual::ReleasePolicy::DETACHED),
   mMaskingData(),
+  mDesiredSize(desiredSize),
   mFrameCount(0),
   mImageSize(),
   mActionStatus(DevelAnimatedImageVisual::Action::PLAY),
   mWrapModeU(WrapMode::DEFAULT),
   mWrapModeV(WrapMode::DEFAULT),
+  mFittingMode(FittingMode::SCALE_TO_FILL),
+  mSamplingMode(SamplingMode::BOX_THEN_LINEAR),
   mStopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME),
   mStartFirstFrame(false),
   mIsJumpTo(false)
@@ -249,6 +272,14 @@ AnimatedImageVisual::~AnimatedImageVisual()
 
 void AnimatedImageVisual::GetNaturalSize(Vector2& naturalSize)
 {
+  if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0)
+  {
+    naturalSize.x = mDesiredSize.GetWidth();
+    naturalSize.y = mDesiredSize.GetHeight();
+    return;
+  }
+
+  naturalSize = Vector2::ZERO;
   if(mImageSize.GetWidth() == 0 && mImageSize.GetHeight() == 0)
   {
     if(mMaskingData && mMaskingData->mAlphaMaskUrl.IsValid() &&
@@ -325,11 +356,21 @@ void AnimatedImageVisual::DoCreatePropertyMap(Property::Map& map) const
 
   map.Insert(Toolkit::ImageVisual::Property::LOAD_POLICY, mLoadPolicy);
   map.Insert(Toolkit::ImageVisual::Property::RELEASE_POLICY, mReleasePolicy);
+  map.Insert(Toolkit::ImageVisual::Property::FITTING_MODE, mFittingMode);
+  map.Insert(Toolkit::ImageVisual::Property::SAMPLING_MODE, mSamplingMode);
+  map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth());
+  map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight());
 }
 
 void AnimatedImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const
 {
-  // Do nothing
+  map.Clear();
+  map.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::ANIMATED_IMAGE);
+  if(mImageUrl.IsValid())
+  {
+    map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth());
+    map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight());
+  }
 }
 
 void AnimatedImageVisual::OnDoAction(const Dali::Property::Index actionId, const Dali::Property::Value& attributes)
@@ -466,6 +507,22 @@ void AnimatedImageVisual::DoSetProperties(const Property::Map& propertyMap)
       {
         DoSetProperty(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, keyValue.second);
       }
+      else if(keyValue.first == IMAGE_FITTING_MODE)
+      {
+        DoSetProperty(Toolkit::ImageVisual::Property::FITTING_MODE, keyValue.second);
+      }
+      else if(keyValue.first == IMAGE_SAMPLING_MODE)
+      {
+        DoSetProperty(Toolkit::ImageVisual::Property::SAMPLING_MODE, keyValue.second);
+      }
+      else if(keyValue.first == IMAGE_DESIRED_WIDTH)
+      {
+        DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_WIDTH, keyValue.second);
+      }
+      else if(keyValue.first == IMAGE_DESIRED_HEIGHT)
+      {
+        DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, keyValue.second);
+      }
     }
   }
   // Load image immediately if LOAD_POLICY requires it
@@ -654,6 +711,50 @@ void AnimatedImageVisual::DoSetProperty(Property::Index        index,
       mLoadPolicy = Toolkit::ImageVisual::LoadPolicy::Type(loadPolicy);
       break;
     }
+
+    case Toolkit::ImageVisual::Property::FITTING_MODE:
+    {
+      int fittingMode = 0;
+      Scripting::GetEnumerationProperty(value, FITTING_MODE_TABLE, FITTING_MODE_TABLE_COUNT, fittingMode);
+      mFittingMode = Dali::FittingMode::Type(fittingMode);
+      break;
+    }
+
+    case Toolkit::ImageVisual::Property::SAMPLING_MODE:
+    {
+      int samplingMode = 0;
+      Scripting::GetEnumerationProperty(value, SAMPLING_MODE_TABLE, SAMPLING_MODE_TABLE_COUNT, samplingMode);
+      mSamplingMode = Dali::SamplingMode::Type(samplingMode);
+      break;
+    }
+
+    case Toolkit::ImageVisual::Property::DESIRED_WIDTH:
+    {
+      float desiredWidth = 0.0f;
+      if(value.Get(desiredWidth))
+      {
+        mDesiredSize.SetWidth(desiredWidth);
+      }
+      else
+      {
+        DALI_LOG_ERROR("AnimatedImageVisual: desiredWidth property has incorrect type\n");
+      }
+      break;
+    }
+
+    case Toolkit::ImageVisual::Property::DESIRED_HEIGHT:
+    {
+      float desiredHeight = 0.0f;
+      if(value.Get(desiredHeight))
+      {
+        mDesiredSize.SetHeight(desiredHeight);
+      }
+      else
+      {
+        DALI_LOG_ERROR("AnimatedImageVisual: desiredHeight property has incorrect type\n");
+      }
+      break;
+    }
   }
 }
 
index 8fc0f59..243b989 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_ANIMATED_IMAGE_VISUAL_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -111,8 +111,9 @@ public:
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
    * @param[in] shaderFactory The ImageVisualShaderFactory object
    * @param[in] imageUrl The URL to animated image resource to use
+   * @param[in] size The width and height of the image. The visual size will be used if these are 0.
    */
-  static AnimatedImageVisualPtr New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl);
+  static AnimatedImageVisualPtr New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size = ImageDimensions());
 
 public: // from Visual
   /**
@@ -141,8 +142,9 @@ protected:
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
    * @param[in] shaderFactory The ImageVisualShaderFactory object
+   * @param[in] desiredSize The width and height of the image. The visual size will be used if these are 0.
    */
-  AnimatedImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory);
+  AnimatedImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, ImageDimensions desiredSize);
 
   /**
    * @brief A reference counted object may only be deleted by calling Unreference().
@@ -284,6 +286,7 @@ private:
   Dali::Toolkit::ImageVisual::LoadPolicy::Type    mLoadPolicy;
   Dali::Toolkit::ImageVisual::ReleasePolicy::Type mReleasePolicy;
   TextureManager::MaskingDataPointer              mMaskingData;
+  Dali::ImageDimensions                           mDesiredSize;
 
   // Shared variables
   uint32_t        mFrameCount; // Number of frames
@@ -291,11 +294,13 @@ private:
 
   DevelAnimatedImageVisual::Action::Type mActionStatus;
 
-  Dali::WrapMode::Type                   mWrapModeU : 3;
-  Dali::WrapMode::Type                   mWrapModeV : 3;
-  DevelImageVisual::StopBehavior::Type   mStopBehavior : 2;
-  bool                                   mStartFirstFrame : 1;
-  bool                                   mIsJumpTo : 1;
+  Dali::WrapMode::Type                 mWrapModeU : 3;
+  Dali::WrapMode::Type                 mWrapModeV : 3;
+  Dali::FittingMode::Type              mFittingMode : 3;
+  Dali::SamplingMode::Type             mSamplingMode : 4;
+  DevelImageVisual::StopBehavior::Type mStopBehavior : 2;
+  bool                                 mStartFirstFrame : 1;
+  bool                                 mIsJumpTo : 1;
 };
 
 } // namespace Internal
index 7cb6ce3..c40f802 100644 (file)
@@ -36,12 +36,15 @@ constexpr uint32_t FIRST_FRAME_INDEX = 0u;
 } // namespace
 
 FixedImageCache::FixedImageCache(TextureManager&                     textureManager,
+                                 ImageDimensions                     size,
+                                 Dali::FittingMode::Type             fittingMode,
+                                 Dali::SamplingMode::Type            samplingMode,
                                  UrlList&                            urlList,
                                  TextureManager::MaskingDataPointer& maskingData,
                                  ImageCache::FrameReadyObserver&     observer,
                                  uint32_t                            batchSize,
                                  uint32_t                            interval)
-: ImageCache(textureManager, maskingData, observer, batchSize, interval),
+: ImageCache(textureManager, size, fittingMode, samplingMode, maskingData, observer, batchSize, interval),
   mImageUrls(urlList),
   mFront(FIRST_FRAME_INDEX)
 {
@@ -132,7 +135,7 @@ void FixedImageCache::LoadBatch()
     Dali::ImageDimensions textureRectSize;
     auto                  preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
-    mTextureManager.LoadTexture(url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, mImageUrls[frameIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
+    mTextureManager.LoadTexture(url, mDesiredSize, mFittingMode, mSamplingMode, mMaskingData, synchronousLoading, mImageUrls[frameIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
     mRequestingLoad = false;
   }
 }
index c798a66..90e2c8f 100644 (file)
@@ -33,6 +33,9 @@ public:
   /**
    * Constructor.
    * @param[in] textureManager The texture manager
+   * @param[in] size           The width and height to fit the loaded image to.
+   * @param[in] fittingMode    The FittingMode of the resource to load
+   * @param[in] samplingMode   The SamplingMode of the resource to load
    * @param[in] urlList        List of urls to cache
    * @param[in] maskingData    Masking data to be applied.
    * @param[in] observer       FrameReady observer
@@ -43,6 +46,9 @@ public:
    * batch and cache sizes. The cache is as large as the number of urls.
    */
   FixedImageCache(TextureManager&                     textureManager,
+                  ImageDimensions                     size,
+                  Dali::FittingMode::Type             fittingMode,
+                  Dali::SamplingMode::Type            samplingMode,
                   UrlList&                            urlList,
                   TextureManager::MaskingDataPointer& maskingData,
                   ImageCache::FrameReadyObserver&     observer,
index 59f0520..3b5131f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -23,6 +23,9 @@ namespace Toolkit
 namespace Internal
 {
 ImageCache::ImageCache(TextureManager&                     textureManager,
+                       ImageDimensions                     size,
+                       Dali::FittingMode::Type             fittingMode,
+                       Dali::SamplingMode::Type            samplingMode,
                        TextureManager::MaskingDataPointer& maskingData,
                        ImageCache::FrameReadyObserver&     observer,
                        uint32_t                            batchSize,
@@ -30,6 +33,9 @@ ImageCache::ImageCache(TextureManager&                     textureManager,
 : mTextureManager(textureManager),
   mObserver(observer),
   mMaskingData(maskingData),
+  mDesiredSize(size),
+  mFittingMode(fittingMode),
+  mSamplingMode(samplingMode),
   mBatchSize(batchSize),
   mInterval(interval),
   mLoadState(TextureManager::LoadState::NOT_STARTED),
index d3b6b0a..f65d60b 100644 (file)
@@ -59,8 +59,10 @@ public:
   /**
    * @brief Constructor.
    * @param[in] textureManager The texture manager
-   * @param[in] urlList List of urls to cache
-   * @param[in] observer FrameReady observer
+   * @param[in] size           The width and height to fit the loaded image to.
+   * @param[in] fittingMode    The FittingMode of the resource to load
+   * @param[in] samplingMode   The SamplingMode of the resource to load
+   * @param[in] observer       FrameReady observer
    * @param[in] maskingData    Masking data to be applied.
    * @param[in] batchSize The size of a batch to load
    * @param[in] interval Time interval(ms) between each frame
@@ -69,6 +71,9 @@ public:
    * batch and cache sizes. The cache is as large as the number of urls.
    */
   ImageCache(TextureManager&                     textureManager,
+             ImageDimensions                     size,
+             Dali::FittingMode::Type             fittingMode,
+             Dali::SamplingMode::Type            samplingMode,
              TextureManager::MaskingDataPointer& maskingData,
              ImageCache::FrameReadyObserver&     observer,
              uint32_t                            batchSize,
@@ -140,6 +145,9 @@ protected:
   TextureManager&                     mTextureManager;
   FrameReadyObserver&                 mObserver;
   TextureManager::MaskingDataPointer& mMaskingData;
+  Dali::ImageDimensions               mDesiredSize;
+  Dali::FittingMode::Type             mFittingMode : 3;
+  Dali::SamplingMode::Type            mSamplingMode : 4;
   uint32_t                            mBatchSize;
   uint32_t                            mInterval;
   TextureManager::LoadState           mLoadState;
index bd6c5a7..995ea60 100644 (file)
@@ -61,6 +61,9 @@ static constexpr uint32_t FIRST_FRAME_INDEX  = 0u;
 } // namespace
 
 RollingAnimatedImageCache::RollingAnimatedImageCache(TextureManager&                     textureManager,
+                                                     ImageDimensions                     size,
+                                                     Dali::FittingMode::Type             fittingMode,
+                                                     Dali::SamplingMode::Type            samplingMode,
                                                      AnimatedImageLoading&               animatedImageLoading,
                                                      TextureManager::MaskingDataPointer& maskingData,
                                                      ImageCache::FrameReadyObserver&     observer,
@@ -70,7 +73,7 @@ RollingAnimatedImageCache::RollingAnimatedImageCache(TextureManager&
                                                      const Dali::WrapMode::Type&         wrapModeV,
                                                      bool                                isSynchronousLoading,
                                                      bool                                preMultiplyOnLoad)
-: ImageCache(textureManager, maskingData, observer, batchSize, 0u),
+: ImageCache(textureManager, size, fittingMode, samplingMode, maskingData, observer, batchSize, 0u),
   mImageUrl(animatedImageLoading.GetUrl()),
   mAnimatedImageLoading(animatedImageLoading),
   mFrameCount(SINGLE_IMAGE_COUNT),
@@ -207,7 +210,9 @@ TextureSet RollingAnimatedImageCache::RequestFrameLoading(uint32_t frameIndex, b
                                                                    frameIndex,
                                                                    loadTextureId,
                                                                    mMaskingData,
-                                                                   SamplingMode::BOX_THEN_LINEAR,
+                                                                   mDesiredSize,
+                                                                   mFittingMode,
+                                                                   mSamplingMode,
                                                                    synchronousLoading,
                                                                    this,
                                                                    preMultiplyOnLoading);
@@ -263,8 +268,8 @@ TextureSet RollingAnimatedImageCache::GetFrontTextureSet() const
 {
   DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "RollingAnimatedImageCache::GetFrontTextureSet() FrameNumber:%d\n", mQueue[0].mFrameNumber);
 
-  TextureManager::TextureId textureId = GetCachedTextureId(0);
-  TextureSet textureSet = mTextureManager.GetTextureSet(textureId);
+  TextureManager::TextureId textureId  = GetCachedTextureId(0);
+  TextureSet                textureSet = mTextureManager.GetTextureSet(textureId);
   if(textureSet)
   {
     Sampler sampler = Sampler::New();
index 8fed2d7..c827e40 100644 (file)
@@ -42,7 +42,10 @@ public:
   /**
    * @brief Constructor.
    * @param[in] textureManager       The texture manager
-   * @param[in] animatedImageLoading  The loaded animated image
+   * @param[in] size                 The width and height to fit the loaded image to.
+   * @param[in] fittingMode          The FittingMode of the resource to load
+   * @param[in] samplingMode         The SamplingMode of the resource to load
+   * @param[in] animatedImageLoading The loaded animated image
    * @param[in] maskingData          Masking data to be applied.
    * @param[in] observer             FrameReady observer
    * @param[in] cacheSize            The size of the cache
@@ -56,6 +59,9 @@ public:
    * batch and cache sizes.
    */
   RollingAnimatedImageCache(TextureManager&                     textureManager,
+                            ImageDimensions                     size,
+                            Dali::FittingMode::Type             fittingMode,
+                            Dali::SamplingMode::Type            samplingMode,
                             AnimatedImageLoading&               animatedImageLoading,
                             TextureManager::MaskingDataPointer& maskingData,
                             ImageCache::FrameReadyObserver&     observer,
index f0dbb94..19f025d 100644 (file)
@@ -58,13 +58,16 @@ namespace Toolkit
 namespace Internal
 {
 RollingImageCache::RollingImageCache(TextureManager&                     textureManager,
+                                     ImageDimensions                     size,
+                                     Dali::FittingMode::Type             fittingMode,
+                                     Dali::SamplingMode::Type            samplingMode,
                                      UrlList&                            urlList,
                                      TextureManager::MaskingDataPointer& maskingData,
                                      ImageCache::FrameReadyObserver&     observer,
                                      uint16_t                            cacheSize,
                                      uint16_t                            batchSize,
                                      uint32_t                            interval)
-: ImageCache(textureManager, maskingData, observer, batchSize, interval),
+: ImageCache(textureManager, size, fittingMode, samplingMode, maskingData, observer, batchSize, interval),
   mImageUrls(urlList),
   mQueue(cacheSize)
 {
@@ -168,7 +171,7 @@ void RollingImageCache::LoadBatch(uint32_t frameIndex)
 
     TextureManager::TextureId loadTextureId = TextureManager::INVALID_TEXTURE_ID;
     TextureSet                textureSet    = mTextureManager.LoadTexture(
-      url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, loadTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
+      url, mDesiredSize, mFittingMode, mSamplingMode, mMaskingData, synchronousLoading, loadTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
     mImageUrls[imageFrame.mUrlIndex].mTextureId = loadTextureId;
 
     mRequestingLoad = false;
@@ -180,8 +183,8 @@ void RollingImageCache::LoadBatch(uint32_t frameIndex)
 
 TextureSet RollingImageCache::GetFrontTextureSet() const
 {
-  TextureManager::TextureId textureId = GetCachedTextureId(0);
-  TextureSet textureSet = mTextureManager.GetTextureSet(textureId);
+  TextureManager::TextureId textureId  = GetCachedTextureId(0);
+  TextureSet                textureSet = mTextureManager.GetTextureSet(textureId);
   if(textureSet)
   {
     Sampler sampler = Sampler::New();
index e01f17f..8fbaad6 100644 (file)
@@ -38,6 +38,9 @@ public:
   /**
    * Constructor.
    * @param[in] textureManager The texture manager
+   * @param[in] size           The width and height to fit the loaded image to.
+   * @param[in] fittingMode    The FittingMode of the resource to load
+   * @param[in] samplingMode   The SamplingMode of the resource to load
    * @param[in] urlList        List of urls to cache
    * @param[in] maskingData    Masking data to be applied.
    * @param[in] observer       FrameReady observer
@@ -49,6 +52,9 @@ public:
    * batch and cache sizes.
    */
   RollingImageCache(TextureManager&                     textureManager,
+                    ImageDimensions                     size,
+                    Dali::FittingMode::Type             fittingMode,
+                    Dali::SamplingMode::Type            samplingMode,
                     UrlList&                            urlList,
                     TextureManager::MaskingDataPointer& maskingData,
                     ImageCache::FrameReadyObserver&     observer,
@@ -141,8 +147,8 @@ private:
     bool         mReady    = false;
   };
 
-  std::vector<UrlStore>&                 mImageUrls;
-  CircularQueue<ImageFrame>              mQueue;
+  std::vector<UrlStore>&    mImageUrls;
+  CircularQueue<ImageFrame> mQueue;
 };
 
 } // namespace Internal
index 60fb25e..a975aa8 100644 (file)
@@ -338,7 +338,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual(const std::string& url, ImageD
       case VisualUrl::GIF:
       case VisualUrl::WEBP:
       {
-        visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
+        visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size);
         break;
       }
       case VisualUrl::JSON: