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 06065b7..0a0338f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 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.
 #include "async-image-loader-impl.h"
 
 // EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/bitmap-loader.h>
-#include <dali/integration-api/adaptors/adaptor.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/public-api/adaptor-framework/async-task-manager.h>
 
 namespace Dali
 {
-
 namespace Toolkit
 {
-
 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()
@@ -50,22 +45,63 @@ IntrusivePtr<AsyncImageLoader> AsyncImageLoader::New()
   return internal;
 }
 
-uint32_t AsyncImageLoader::Load( const std::string& url,
-                                 ImageDimensions dimensions,
-                                 FittingMode::Type fittingMode,
-                                 SamplingMode::Type samplingMode,
-                                 bool orientationCorrection )
+uint32_t AsyncImageLoader::LoadAnimatedImage(Dali::AnimatedImageLoading               animatedImageLoading,
+                                             uint32_t                                 frameIndex,
+                                             DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad)
 {
-  if( !mIsLoadThreadStarted )
-  {
-    mLoadThread.Start();
-    mIsLoadThreadStarted = true;
-  }
+  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;
+}
 
-  BitmapLoader loader = BitmapLoader::New( url, dimensions, fittingMode, samplingMode, orientationCorrection );
+uint32_t AsyncImageLoader::Load(const VisualUrl&                         url,
+                                ImageDimensions                          dimensions,
+                                FittingMode::Type                        fittingMode,
+                                SamplingMode::Type                       samplingMode,
+                                bool                                     orientationCorrection,
+                                DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad,
+                                bool                                     loadPlanes)
+{
+  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;
+}
 
-  mLoadThread.AddTask( new LoadingTask( ++mLoadTaskId, loader ) );
+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;
+}
 
+uint32_t AsyncImageLoader::ApplyMask(Devel::PixelBuffer                       pixelBuffer,
+                                     Devel::PixelBuffer                       maskPixelBuffer,
+                                     float                                    contentScale,
+                                     bool                                     cropToMask,
+                                     DevelAsyncImageLoader::PreMultiplyOnLoad 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;
 }
 
@@ -74,22 +110,80 @@ Toolkit::AsyncImageLoader::ImageLoadedSignalType& AsyncImageLoader::ImageLoadedS
   return mLoadedSignal;
 }
 
-bool AsyncImageLoader::Cancel( uint32_t loadingTaskId )
+Toolkit::DevelAsyncImageLoader::PixelBufferLoadedSignalType& AsyncImageLoader::PixelBufferLoadedSignal()
 {
-  return mLoadThread.CancelTask( loadingTaskId );
+  return mPixelBufferLoadedSignal;
+}
+
+bool AsyncImageLoader::Cancel(uint32_t 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(LoadingTaskPtr task)
+{
+  if(mPixelBufferLoadedSignal.GetConnectionCount() > 0)
+  {
+    mPixelBufferLoadedSignal.Emit(task->id, task->pixelBuffers);
+  }
+  else if(mLoadedSignal.GetConnectionCount() > 0)
+  {
+    PixelData pixelData;
+    if(!task->pixelBuffers.empty())
+    {
+      pixelData = Devel::PixelBuffer::Convert(task->pixelBuffers[0]);
+    }
+    mLoadedSignal.Emit(task->id, pixelData);
+  }
+
+  mCompletedTaskIds.push_back(task->id);
 }
 
-void AsyncImageLoader::ProcessLoadedImage()
+void AsyncImageLoader::RemoveCompletedTask()
 {
-  while( LoadingTask *next =  mLoadThread.NextCompletedTask() )
+  std::uint32_t loadingTaskId;
+  auto          end              = mLoadingTasks.end();
+  auto          endCompletedIter = mCompletedTaskIds.end();
+  for(std::vector<AsyncImageLoadingInfo>::iterator iter = mLoadingTasks.begin(); iter != end; ++iter)
   {
-    mLoadedSignal.Emit( next->id, next->loader.GetPixelData() );
-    delete next;
+    loadingTaskId = (*iter).loadId;
+    for(auto iterCompleted = mCompletedTaskIds.begin(); iterCompleted != endCompletedIter; ++iterCompleted)
+    {
+      if((*iterCompleted) == loadingTaskId)
+      {
+        mLoadingTasks.erase(iter);
+      }
+    }
   }
 }