Move MultiplyColorByAlpha() from main thread to resource thread 20/204320/12
authorSunghyun kim <scholb.kim@samsung.com>
Tue, 23 Apr 2019 05:40:05 +0000 (14:40 +0900)
committerSunghyun kim <scholb.kim@samsung.com>
Tue, 4 Jun 2019 09:59:21 +0000 (18:59 +0900)
Change-Id: I61f8e9b1bb1711de98707aa21ec5325b62bd5b10

dali-toolkit/devel-api/image-loader/async-image-loader-devel.cpp
dali-toolkit/devel-api/image-loader/async-image-loader-devel.h
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/image-atlas-impl.cpp
dali-toolkit/internal/image-loader/image-load-thread.cpp
dali-toolkit/internal/image-loader/image-load-thread.h
dali-toolkit/internal/visuals/texture-manager-impl.cpp
dali-toolkit/internal/visuals/texture-manager-impl.h
dali-toolkit/public-api/image-loader/async-image-loader.cpp

index 690f078..451ace3 100644 (file)
@@ -24,6 +24,17 @@ namespace Toolkit
 namespace DevelAsyncImageLoader
 {
 
+uint32_t Load( AsyncImageLoader asyncImageLoader,
+               const std::string& url,
+               ImageDimensions dimensions,
+               FittingMode::Type fittingMode,
+               SamplingMode::Type samplingMode,
+               bool orientationCorrection,
+               DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad )
+{
+  return GetImplementation( asyncImageLoader ).Load( Toolkit::Internal::VisualUrl(url), dimensions, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad);
+}
+
 PixelBufferLoadedSignalType& PixelBufferLoadedSignal( AsyncImageLoader asyncImageLoader )
 {
   return GetImplementation( asyncImageLoader ).PixelBufferLoadedSignal();
index 7cb64c5..1208f0d 100644 (file)
@@ -31,6 +31,36 @@ namespace DevelAsyncImageLoader
 typedef Signal< void ( uint32_t, Devel::PixelBuffer ) > PixelBufferLoadedSignalType;
 
 /**
+ * @brief Whether to multiply alpha into color channels on load
+ */
+enum class PreMultiplyOnLoad
+{
+  OFF = 0, ///< Don't modify the image
+  ON           ///< Multiply alpha into color channels on load
+};
+
+/**
+ * @brief Starts an image loading task.
+ * @REMARK_INTERNET
+ * @REMARK_STORAGE
+ * @param[in] asyncImageLoader The ayncImageLoader
+ * @param[in] url The URL of the image file to load
+ * @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] orientationCorrection Reorient the image to respect any orientation metadata in its header
+ * @param[in] preMultiplyOnLoad ON if the image color should be multiplied by it's alpha. Set to OFF if there is no alpha
+ * @return The loading task id
+ */
+DALI_TOOLKIT_API uint32_t Load(  AsyncImageLoader asyncImageLoader,
+                const std::string& url,
+                ImageDimensions dimensions,
+                FittingMode::Type fittingMode,
+                SamplingMode::Type samplingMode,
+                bool orientationCorrection,
+                DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad );
+
+/**
  * Connect to this signal if you want to load a PixelBuffer instead of a PixelData.
  * @note Connecting to this signal prevents the emission of the ImageLoadedSignal.
  */
index 966da79..1b764cb 100644 (file)
@@ -53,15 +53,15 @@ uint32_t AsyncImageLoader::Load( const VisualUrl& url,
                                  ImageDimensions dimensions,
                                  FittingMode::Type fittingMode,
                                  SamplingMode::Type samplingMode,
-                                 bool orientationCorrection )
+                                 bool orientationCorrection,
+                                 DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad)
 {
   if( !mIsLoadThreadStarted )
   {
     mLoadThread.Start();
     mIsLoadThreadStarted = true;
   }
-
-  mLoadThread.AddTask( new LoadingTask( ++mLoadTaskId, url, dimensions, fittingMode, samplingMode, orientationCorrection ) );
+  mLoadThread.AddTask( new LoadingTask( ++mLoadTaskId, url, dimensions, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad ) );
 
   return mLoadTaskId;
 }
index ce40f5a..7810a8f 100644 (file)
@@ -50,13 +50,14 @@ public:
   static IntrusivePtr<AsyncImageLoader> New();
 
   /**
-   * @copydoc Toolkit::AsyncImageLoader::Load( const std::string&, ImageDimensions, FittingMode::Type, SamplingMode::Type, bool )
+   * @copydoc Toolkit::AsyncImageLoader::Load( const std::string&, ImageDimensions, FittingMode::Type, SamplingMode::Type, bool , DevelAsyncImageLoader::PreMultiplyOnLoad )
    */
   uint32_t Load( const VisualUrl& url,
                  ImageDimensions dimensions,
                  FittingMode::Type fittingMode,
                  SamplingMode::Type samplingMode,
-                 bool orientationCorrection );
+                 bool orientationCorrection,
+                 DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad );
 
   /**
    * @copydoc Toolkit::AsyncImageLoader::ImageLoadedSignal
index b69adbd..d167499 100644 (file)
@@ -163,7 +163,7 @@ bool ImageAtlas::Upload( Vector4& textureRect,
   unsigned int packPositionY = 0;
   if( mPacker.Pack( dimensions.GetWidth(), dimensions.GetHeight(), packPositionX, packPositionY ) )
   {
-    unsigned short loadId = mAsyncLoader.Load( url, size, fittingMode, SamplingMode::BOX_THEN_LINEAR, orientationCorrection );
+    unsigned short loadId = mAsyncLoader.Load( url, size, fittingMode, SamplingMode::BOX_THEN_LINEAR, orientationCorrection);
     mLoadingTaskInfoContainer.PushBack( new LoadingTaskInfo( loadId, packPositionX, packPositionY, dimensions.GetWidth(), dimensions.GetHeight(), atlasUploadObserver ) );
     // apply the half pixel correction
     textureRect.x = ( static_cast<float>( packPositionX ) +0.5f ) / mWidth; // left
index 74d3e39..320911d 100644 (file)
@@ -33,14 +33,15 @@ namespace Internal
 {
 
 LoadingTask::LoadingTask( uint32_t id, const VisualUrl& url, ImageDimensions dimensions,
-                          FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection )
+                          FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad )
 : pixelBuffer(),
   url( url ),
   id( id ),
   dimensions( dimensions ),
   fittingMode( fittingMode ),
   samplingMode( samplingMode ),
-  orientationCorrection( orientationCorrection )
+  orientationCorrection( orientationCorrection ),
+  preMultiplyOnLoad( preMultiplyOnLoad )
 {
 }
 
@@ -54,6 +55,14 @@ void LoadingTask::Load()
   {
     pixelBuffer = Dali::DownloadImageSynchronously ( url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection );
   }
+
+  if( pixelBuffer && Pixel::HasAlpha( pixelBuffer.GetPixelFormat() ) )
+  {
+    if( preMultiplyOnLoad == DevelAsyncImageLoader::PreMultiplyOnLoad::ON )
+    {
+      pixelBuffer.MultiplyColorByAlpha();
+    }
+  }
 }
 
 
index 4791a75..35fe216 100644 (file)
@@ -28,6 +28,7 @@
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali/integration-api/adaptors/log-factory-interface.h>
 #include <dali-toolkit/internal/visuals/visual-url.h>
+#include <dali-toolkit/devel-api/image-loader/async-image-loader-devel.h>
 
 namespace Dali
 {
@@ -51,10 +52,12 @@ struct LoadingTask
    * @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] orientationCorrection Reorient the image to respect any orientation metadata in its header.
+   * @param [in] preMultiplyOnLoad ON if the image's color should be multiplied by it's alpha.
    */
   LoadingTask( uint32_t id, const VisualUrl& url, ImageDimensions dimensions,
                FittingMode::Type fittingMode, SamplingMode::Type samplingMode,
-               bool orientationCorrection );
+               bool orientationCorrection,
+               DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad );
 
   /**
    * Load the image
@@ -78,7 +81,7 @@ public:
   FittingMode::Type  fittingMode;   ///< fitting options
   SamplingMode::Type samplingMode;  ///< sampling options
   bool               orientationCorrection:1; ///< if orientation correction is needed
-
+  DevelAsyncImageLoader::PreMultiplyOnLoad            preMultiplyOnLoad; //< if the image's color should be multiplied by it's alpha
 };
 
 
index 3a32ddc..2be3aaa 100644 (file)
@@ -690,10 +690,12 @@ void TextureManager::LoadTexture( TextureInfo& textureInfo, TextureUploadObserve
   {
     auto& loadersContainer = textureInfo.url.IsLocalResource() ? mAsyncLocalLoaders : mAsyncRemoteLoaders;
     auto loadingHelperIt = loadersContainer.GetNext();
+    auto premultiplyOnLoad = textureInfo.preMultiplyOnLoad? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF;
     DALI_ASSERT_ALWAYS(loadingHelperIt != loadersContainer.End());
     loadingHelperIt->Load(textureInfo.textureId, textureInfo.url,
                           textureInfo.desiredSize, textureInfo.fittingMode,
-                          textureInfo.samplingMode, textureInfo.orientationCorrection );
+                          textureInfo.samplingMode, textureInfo.orientationCorrection,
+                          premultiplyOnLoad );
   }
   ObserveTexture( textureInfo, observer );
 }
@@ -873,13 +875,8 @@ void TextureManager::UploadTexture( Devel::PixelBuffer& pixelBuffer, TextureInfo
   {
     DALI_LOG_INFO( gTextureManagerLogFilter, Debug::General, "  TextureManager::UploadTexture() New Texture for textureId:%d\n", textureInfo.textureId );
 
-    // If the texture doesn't have an alpha channel, can't pre-multiply it.
-    // Ensure that we don't change the load parameter (it's used for hashing), and instead set
-    // the status for use in the observer.
-    auto preMultiply = textureInfo.preMultiplyOnLoad ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD :
-      TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
-    PreMultiply( pixelBuffer, preMultiply );
-    textureInfo.preMultiplied = (preMultiply == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD );
+    // Check if this pixelBuffer is premultiplied
+    textureInfo.preMultiplied = pixelBuffer.IsAlphaPreMultiplied();
 
     Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(),
                                     pixelBuffer.GetWidth(), pixelBuffer.GetHeight() );
@@ -1120,10 +1117,11 @@ void TextureManager::AsyncLoadingHelper::Load(TextureId          textureId,
                                               ImageDimensions    desiredSize,
                                               FittingMode::Type  fittingMode,
                                               SamplingMode::Type samplingMode,
-                                              bool               orientationCorrection)
+                                              bool               orientationCorrection,
+                                              DevelAsyncImageLoader::PreMultiplyOnLoad  preMultiplyOnLoad)
 {
   mLoadingInfoContainer.push_back(AsyncLoadingInfo(textureId));
-  auto id = mLoader.Load(url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection);
+  auto id = DevelAsyncImageLoader::Load(mLoader, url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad);
   mLoadingInfoContainer.back().loadId = id;
 }
 
index c64b781..2cb06bd 100755 (executable)
@@ -713,13 +713,15 @@ private:
      * @param[in] samplingMode          The SamplingMode to use
      * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image,
      *                                  e.g., from portrait to landscape
+     * @param[in] preMultiplyOnLoad     if the image's color should be multiplied by it's alpha.
      */
     void Load(TextureId textureId,
               const VisualUrl& url,
               ImageDimensions desiredSize,
               FittingMode::Type fittingMode,
               SamplingMode::Type samplingMode,
-              bool orientationCorrection);
+              bool orientationCorrection,
+              DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
 
   public:
     AsyncLoadingHelper(const AsyncLoadingHelper&) = delete;
index b01134d..a1d21e7 100644 (file)
@@ -64,12 +64,12 @@ AsyncImageLoader AsyncImageLoader::New()
 
 uint32_t AsyncImageLoader::Load( const std::string& url )
 {
-  return GetImplementation( *this ).Load( Toolkit::Internal::VisualUrl(url), ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true );
+  return GetImplementation( *this ).Load( Toolkit::Internal::VisualUrl(url), ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true, DevelAsyncImageLoader::PreMultiplyOnLoad::OFF );
 }
 
 uint32_t AsyncImageLoader::Load( const std::string& url, ImageDimensions dimensions )
 {
-  return GetImplementation( *this ).Load( Toolkit::Internal::VisualUrl(url), dimensions, FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true );
+  return GetImplementation( *this ).Load( Toolkit::Internal::VisualUrl(url), dimensions, FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true , DevelAsyncImageLoader::PreMultiplyOnLoad::OFF );
 }
 
 uint32_t AsyncImageLoader::Load( const std::string& url,
@@ -78,7 +78,7 @@ uint32_t AsyncImageLoader::Load( const std::string& url,
                                  SamplingMode::Type samplingMode,
                                  bool orientationCorrection )
 {
-  return GetImplementation(*this).Load( Toolkit::Internal::VisualUrl(url), dimensions, fittingMode, samplingMode, orientationCorrection );
+  return GetImplementation(*this).Load( Toolkit::Internal::VisualUrl(url), dimensions, fittingMode, samplingMode, orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad::OFF );
 }
 
 bool AsyncImageLoader::Cancel( uint32_t loadingTaskId )