Add DesiredWidth/Height and samplingMode in animated image visual
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / image-loader / async-image-loader-impl.cpp
index 412eda7..0a0338f 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.
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/public-api/adaptor-framework/async-task-manager.h>
 
 namespace Dali
 {
@@ -29,15 +30,13 @@ namespace Internal
 {
 AsyncImageLoader::AsyncImageLoader()
 : mLoadedSignal(),
-  mLoadThread(new EventThreadCallback(MakeCallback(this, &AsyncImageLoader::ProcessLoadedImage))),
-  mLoadTaskId(0u),
-  mIsLoadThreadStarted(false)
+  mLoadTaskId(0u)
 {
 }
 
 AsyncImageLoader::~AsyncImageLoader()
 {
-  mLoadThread.CancelAll();
+  CancelAll();
 }
 
 IntrusivePtr<AsyncImageLoader> AsyncImageLoader::New()
@@ -46,16 +45,24 @@ IntrusivePtr<AsyncImageLoader> AsyncImageLoader::New()
   return internal;
 }
 
-uint32_t AsyncImageLoader::LoadAnimatedImage(Dali::AnimatedImageLoading animatedImageLoading,
-                                             uint32_t                   frameIndex)
+uint32_t AsyncImageLoader::LoadAnimatedImage(Dali::AnimatedImageLoading               animatedImageLoading,
+                                             uint32_t                                 frameIndex,
+                                             DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad)
 {
-  if(!mIsLoadThreadStarted)
-  {
-    mLoadThread.Start();
-    mIsLoadThreadStarted = true;
-  }
-  mLoadThread.AddTask(new LoadingTask(++mLoadTaskId, animatedImageLoading, frameIndex));
+  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,15 +71,25 @@ uint32_t AsyncImageLoader::Load(const VisualUrl&                         url,
                                 FittingMode::Type                        fittingMode,
                                 SamplingMode::Type                       samplingMode,
                                 bool                                     orientationCorrection,
-                                DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad)
+                                DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad,
+                                bool                                     loadPlanes)
 {
-  if(!mIsLoadThreadStarted)
-  {
-    mLoadThread.Start();
-    mIsLoadThreadStarted = true;
-  }
-  mLoadThread.AddTask(new LoadingTask(++mLoadTaskId, url, dimensions, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad));
+  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));
+  return mLoadTaskId;
+}
 
+uint32_t AsyncImageLoader::LoadEncodedImageBuffer(const EncodedImageBuffer&                encodedImageBuffer,
+                                                  ImageDimensions                          dimensions,
+                                                  FittingMode::Type                        fittingMode,
+                                                  SamplingMode::Type                       samplingMode,
+                                                  bool                                     orientationCorrection,
+                                                  DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad)
+{
+  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));
   return mLoadTaskId;
 }
 
@@ -82,13 +99,9 @@ uint32_t AsyncImageLoader::ApplyMask(Devel::PixelBuffer                       pi
                                      bool                                     cropToMask,
                                      DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad)
 {
-  if(!mIsLoadThreadStarted)
-  {
-    mLoadThread.Start();
-    mIsLoadThreadStarted = true;
-  }
-  mLoadThread.AddTask(new LoadingTask(++mLoadTaskId, pixelBuffer, maskPixelBuffer, contentScale, cropToMask, preMultiplyOnLoad));
-
+  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));
   return mLoadTaskId;
 }
 
@@ -104,33 +117,73 @@ Toolkit::DevelAsyncImageLoader::PixelBufferLoadedSignalType& AsyncImageLoader::P
 
 bool AsyncImageLoader::Cancel(uint32_t loadingTaskId)
 {
-  return mLoadThread.CancelTask(loadingTaskId);
+  // Remove already completed tasks
+  RemoveCompletedTask();
+
+  auto end = mLoadingTasks.end();
+  for(std::vector<AsyncImageLoadingInfo>::iterator iter = mLoadingTasks.begin(); iter != end; ++iter)
+  {
+    if((*iter).loadId == loadingTaskId)
+    {
+      Dali::AsyncTaskManager::Get().RemoveTask((*iter).loadingTask);
+      mLoadingTasks.erase(iter);
+      return true;
+    }
+  }
+
+  return false;
 }
 
 void AsyncImageLoader::CancelAll()
 {
-  mLoadThread.CancelAll();
+  // Remove already completed tasks
+  RemoveCompletedTask();
+
+  auto end = mLoadingTasks.end();
+  for(std::vector<AsyncImageLoadingInfo>::iterator iter = mLoadingTasks.begin(); iter != end; ++iter)
+  {
+    if((*iter).loadingTask && Dali::AsyncTaskManager::Get())
+    {
+      Dali::AsyncTaskManager::Get().RemoveTask(((*iter).loadingTask));
+    }
+  }
+  mLoadingTasks.clear();
 }
 
-void AsyncImageLoader::ProcessLoadedImage()
+void AsyncImageLoader::ProcessLoadedImage(LoadingTaskPtr task)
 {
-  while(LoadingTask* next = mLoadThread.NextCompletedTask())
+  if(mPixelBufferLoadedSignal.GetConnectionCount() > 0)
+  {
+    mPixelBufferLoadedSignal.Emit(task->id, task->pixelBuffers);
+  }
+  else if(mLoadedSignal.GetConnectionCount() > 0)
   {
-    if(mPixelBufferLoadedSignal.GetConnectionCount() > 0)
+    PixelData pixelData;
+    if(!task->pixelBuffers.empty())
     {
-      mPixelBufferLoadedSignal.Emit(next->id, next->pixelBuffer);
+      pixelData = Devel::PixelBuffer::Convert(task->pixelBuffers[0]);
     }
-    else if(mLoadedSignal.GetConnectionCount() > 0)
+    mLoadedSignal.Emit(task->id, pixelData);
+  }
+
+  mCompletedTaskIds.push_back(task->id);
+}
+
+void AsyncImageLoader::RemoveCompletedTask()
+{
+  std::uint32_t loadingTaskId;
+  auto          end              = mLoadingTasks.end();
+  auto          endCompletedIter = mCompletedTaskIds.end();
+  for(std::vector<AsyncImageLoadingInfo>::iterator iter = mLoadingTasks.begin(); iter != end; ++iter)
+  {
+    loadingTaskId = (*iter).loadId;
+    for(auto iterCompleted = mCompletedTaskIds.begin(); iterCompleted != endCompletedIter; ++iterCompleted)
     {
-      PixelData pixelData;
-      if(next->pixelBuffer)
+      if((*iterCompleted) == loadingTaskId)
       {
-        pixelData = Devel::PixelBuffer::Convert(next->pixelBuffer);
+        mLoadingTasks.erase(iter);
       }
-      mLoadedSignal.Emit(next->id, pixelData);
     }
-
-    delete next;
   }
 }