Move ApplyMask to Image-Load-Thread 30/210730/13
authorSeungho, Baek <sbsh.baek@samsung.com>
Wed, 24 Jul 2019 06:27:14 +0000 (15:27 +0900)
committerSeungho, Baek <sbsh.baek@samsung.com>
Fri, 16 Aug 2019 00:23:57 +0000 (09:23 +0900)
Change-Id: I27f9dfae7d6df26ba63721803720fe851a80baf4
Signed-off-by: Seungho, Baek <sbsh.baek@samsung.com>
automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp
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-load-thread.cpp
dali-toolkit/internal/image-loader/image-load-thread.h
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/texture-manager-impl.cpp
dali-toolkit/internal/visuals/texture-manager-impl.h

index a15ecf6..27a939b 100644 (file)
@@ -1298,7 +1298,7 @@ int UtcDaliImageVisualAlphaMask(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 2 ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 3 ), true, TEST_LOCATION );
 
   application.SendNotification();
   application.Render();
@@ -1354,7 +1354,7 @@ int UtcDaliImageVisualRemoteAlphaMask(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 2 ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 3 ), true, TEST_LOCATION );
 
   application.SendNotification();
   application.Render();
@@ -1410,7 +1410,7 @@ int UtcDaliImageVisualAlphaMaskCrop(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 2 ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 3 ), true, TEST_LOCATION );
 
   application.SendNotification();
   application.Render();
index 451ace3..3bd3368 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -35,6 +35,15 @@ uint32_t Load( AsyncImageLoader asyncImageLoader,
   return GetImplementation( asyncImageLoader ).Load( Toolkit::Internal::VisualUrl(url), dimensions, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad);
 }
 
+uint32_t ApplyMask( AsyncImageLoader asyncImageLoader,
+                    Devel::PixelBuffer pixelBuffer,
+                    Devel::PixelBuffer maskPixelBuffer,
+                    float contentScale,
+                    bool cropToMask )
+{
+  return GetImplementation( asyncImageLoader ).ApplyMask( pixelBuffer, maskPixelBuffer, contentScale, cropToMask );
+}
+
 PixelBufferLoadedSignalType& PixelBufferLoadedSignal( AsyncImageLoader asyncImageLoader )
 {
   return GetImplementation( asyncImageLoader ).PixelBufferLoadedSignal();
index 1208f0d..fb2ade1 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_DEVEL_API_IMAGE_LOADER_ASYNC_IMAGE_LOADER_DEVEL_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -28,7 +28,7 @@ namespace Toolkit
 namespace DevelAsyncImageLoader
 {
 
-typedef Signal< void ( uint32_t, Devel::PixelBuffer ) > PixelBufferLoadedSignalType;
+typedef Signal< void ( uint32_t, Devel::PixelBuffer, bool ) > PixelBufferLoadedSignalType;
 
 /**
  * @brief Whether to multiply alpha into color channels on load
@@ -52,13 +52,30 @@ enum class PreMultiplyOnLoad
  * @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 );
+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 );
+
+/**
+ * @brief Starts an mask applying task.
+ * @REMARK_INTERNET
+ * @REMARK_STORAGE
+ * @param[in] asyncImageLoader The ayncImageLoader
+ * @param[in] pixelBuffer Pointer to raw pixel data to be masked
+ * @param[in] maskPixelBuffer Pointer to raw masking data
+ * @param[in] contentScale The factor to scale the content
+ * @param[in] cropToMask Whether to crop the content to the mask size
+ * @return The masking task id
+ */
+DALI_TOOLKIT_API uint32_t ApplyMask( AsyncImageLoader asyncImageLoader,
+                                     Devel::PixelBuffer pixelBuffer,
+                                     Devel::PixelBuffer maskPixelBuffer,
+                                     float contentScale,
+                                     bool cropToMask );
 
 /**
  * Connect to this signal if you want to load a PixelBuffer instead of a PixelData.
index 1b764cb..dd98ae3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -66,6 +66,21 @@ uint32_t AsyncImageLoader::Load( const VisualUrl& url,
   return mLoadTaskId;
 }
 
+uint32_t AsyncImageLoader::ApplyMask( Devel::PixelBuffer pixelBuffer,
+                                      Devel::PixelBuffer maskPixelBuffer,
+                                      float contentScale,
+                                      bool cropToMask )
+{
+  if( !mIsLoadThreadStarted )
+  {
+    mLoadThread.Start();
+    mIsLoadThreadStarted = true;
+  }
+  mLoadThread.AddTask( new LoadingTask( ++mLoadTaskId, pixelBuffer, maskPixelBuffer, contentScale, cropToMask ) );
+
+  return mLoadTaskId;
+}
+
 Toolkit::AsyncImageLoader::ImageLoadedSignalType& AsyncImageLoader::ImageLoadedSignal()
 {
   return mLoadedSignal;
@@ -92,7 +107,7 @@ void AsyncImageLoader::ProcessLoadedImage()
   {
     if( mPixelBufferLoadedSignal.GetConnectionCount() > 0 )
     {
-      mPixelBufferLoadedSignal.Emit( next->id, next->pixelBuffer );
+      mPixelBufferLoadedSignal.Emit( next->id, next->pixelBuffer, next->isMaskTask );
     }
     else if( mLoadedSignal.GetConnectionCount() > 0 )
     {
index 7810a8f..69a7617 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_ASYNC_IMAGE_LOADER_IMPL_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -60,6 +60,19 @@ public:
                  DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad );
 
   /**
+   * @brief Starts an mask applying task.
+   * @param[in] pixelBuffer of the to be masked image
+   * @param[in] maskPixelBuffer of the mask image
+   * @param[in] contentScale The factor to scale the content
+   * @param[in] cropToMask Whether to crop the content to the mask size
+   * @return The loading task id
+   */
+  uint32_t ApplyMask( Devel::PixelBuffer pixelBuffer,
+                      Devel::PixelBuffer maskPixelBuffer,
+                      float contentScale,
+                      bool cropToMask );
+
+  /**
    * @copydoc Toolkit::AsyncImageLoader::ImageLoadedSignal
    */
   Toolkit::AsyncImageLoader::ImageLoadedSignalType& ImageLoadedSignal();
index 320911d..f687af6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -41,7 +41,27 @@ LoadingTask::LoadingTask( uint32_t id, const VisualUrl& url, ImageDimensions dim
   fittingMode( fittingMode ),
   samplingMode( samplingMode ),
   orientationCorrection( orientationCorrection ),
-  preMultiplyOnLoad( preMultiplyOnLoad )
+  preMultiplyOnLoad( preMultiplyOnLoad ),
+  isMaskTask( false ),
+  maskPixelBuffer(),
+  contentScale( 1.0f ),
+  cropToMask( false )
+{
+}
+
+LoadingTask::LoadingTask( uint32_t id, Devel::PixelBuffer pixelBuffer, Devel::PixelBuffer maskPixelBuffer, float contentScale, bool cropToMask )
+: pixelBuffer( pixelBuffer ),
+  url( "" ),
+  id( id ),
+  dimensions(),
+  fittingMode(),
+  samplingMode(),
+  orientationCorrection(),
+  preMultiplyOnLoad(),
+  isMaskTask( true ),
+  maskPixelBuffer( maskPixelBuffer ),
+  contentScale( contentScale ),
+  cropToMask( cropToMask )
 {
 }
 
@@ -65,6 +85,10 @@ void LoadingTask::Load()
   }
 }
 
+void LoadingTask::ApplyMask()
+{
+  pixelBuffer.ApplyMask( maskPixelBuffer, contentScale, cropToMask );
+}
 
 ImageLoadThread::ImageLoadThread( EventThreadCallback* trigger )
 : mTrigger( trigger ),
@@ -89,7 +113,15 @@ void ImageLoadThread::Run()
 
   while( LoadingTask* task = NextTaskToProcess() )
   {
-    task->Load();
+    if( !task->isMaskTask )
+    {
+      task->Load();
+    }
+    else
+    {
+      task->ApplyMask();
+    }
+
     AddCompletedTask( task );
   }
 }
index 35fe216..cd6bd32 100644 (file)
@@ -54,16 +54,38 @@ struct LoadingTask
    * @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,
+  LoadingTask( uint32_t id,
+               const VisualUrl& url,
+               ImageDimensions dimensions,
+               FittingMode::Type fittingMode,
+               SamplingMode::Type samplingMode,
                bool orientationCorrection,
-               DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad );
+               DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
+
+  /**
+   * Constructor.
+   * @param [in] id of the task
+   * @param [in] pixelBuffer of the to be masked image
+   * @param [in] maskPixelBuffer of the mask image
+   * @param [in] contentScale The factor to scale the content
+   * @param [in] cropToMask Whether to crop the content to the mask size
+   */
+  LoadingTask( uint32_t id,
+              Devel::PixelBuffer pixelBuffer,
+              Devel::PixelBuffer maskPixelBuffer,
+              float contentScale,
+              bool cropToMask );
 
   /**
    * Load the image
    */
   void Load();
 
+  /**
+   * Apply mask
+   */
+  void ApplyMask();
+
 private:
 
   // Undefined
@@ -75,6 +97,7 @@ private:
 public:
 
   Devel::PixelBuffer pixelBuffer;   ///< pixelBuffer handle after successful load
+                                    ///< or pixelBuffer to be masked image in the mask task
   VisualUrl          url;           ///< url of the image to load
   uint32_t           id;            ///< The unique id associated with this task.
   ImageDimensions    dimensions;    ///< dimensions to load
@@ -82,6 +105,11 @@ public:
   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
+
+  bool isMaskTask;                  ///< whether this task is for mask or not
+  Devel::PixelBuffer maskPixelBuffer; ///< pixelBuffer of mask image
+  float contentScale;               ///< The factor to scale the content
+  bool cropToMask;                  ///< Whether to crop the content to the mask size
 };
 
 
index 77d06b7..8607fa8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
index 2be3aaa..e55fd90 100644 (file)
@@ -85,6 +85,8 @@ Debug::Filter* gTextureManagerLogFilter = Debug::Filter::New( Debug::NoLogging,
     loadState == TextureManager::LOADING ? "LOADING" :                   \
     loadState == TextureManager::LOAD_FINISHED ? "LOAD_FINISHED" :       \
     loadState == TextureManager::WAITING_FOR_MASK ? "WAITING_FOR_MASK" : \
+    loadState == TextureManager::MASK_APPLYING ? "MASK_APPLYING" :         \
+    loadState == TextureManager::MASK_APPLIED ? "MASK_APPLIED" :         \
     loadState == TextureManager::UPLOADED ? "UPLOADED" :                 \
     loadState == TextureManager::CANCELLED ? "CANCELLED" :               \
     loadState == TextureManager::LOAD_FAILED ? "LOAD_FAILED" : "Unknown"
@@ -263,6 +265,9 @@ TextureSet TextureManager::LoadTexture(
       // If we are loading the texture, or waiting for the ready signal handler to complete, inform
       // caller that they need to wait.
       loadingStatus = ( loadState == TextureManager::LOADING ||
+                        loadState == TextureManager::WAITING_FOR_MASK ||
+                        loadState == TextureManager::MASK_APPLYING ||
+                        loadState == TextureManager::MASK_APPLIED ||
                         loadState == TextureManager::NOT_STARTED ||
                         mQueueLoadFlag );
 
@@ -393,7 +398,11 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
                  GET_LOAD_STATE_STRING(textureInfo.loadState ) );
 
   // Force reloading of texture by setting loadState unless already loading or cancelled.
-  if ( TextureManager::ReloadPolicy::FORCED == reloadPolicy && TextureManager::LOADING != textureInfo.loadState &&
+  if ( TextureManager::ReloadPolicy::FORCED == reloadPolicy &&
+       TextureManager::LOADING != textureInfo.loadState &&
+       TextureManager::WAITING_FOR_MASK != textureInfo.loadState &&
+       TextureManager::MASK_APPLYING != textureInfo.loadState &&
+       TextureManager::MASK_APPLIED != textureInfo.loadState &&
        TextureManager::CANCELLED != textureInfo.loadState )
   {
     DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Verbose, "TextureManager::RequestLoad( url=%s observer=%p ) ForcedReload cacheIndex:%d, textureId=%d\n",
@@ -412,6 +421,9 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
       break;
     }
     case TextureManager::LOADING:
+    case TextureManager::WAITING_FOR_MASK:
+    case TextureManager::MASK_APPLYING:
+    case TextureManager::MASK_APPLIED:
     {
       ObserveTexture( textureInfo, observer );
       break;
@@ -433,7 +445,6 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
       break;
     }
     case TextureManager::LOAD_FINISHED:
-    case TextureManager::WAITING_FOR_MASK:
       // Loading has already completed. Do nothing.
       break;
   }
@@ -648,7 +659,6 @@ void TextureManager::LoadOrQueueTexture( TextureInfo& textureInfo, TextureUpload
       }
       break;
     }
-    case LOADING:
     case UPLOADED:
     {
       if( mQueueLoadFlag )
@@ -665,9 +675,12 @@ void TextureManager::LoadOrQueueTexture( TextureInfo& textureInfo, TextureUpload
       }
       break;
     }
+    case LOADING:
     case CANCELLED:
     case LOAD_FINISHED:
     case WAITING_FOR_MASK:
+    case MASK_APPLYING:
+    case MASK_APPLIED:
     {
       break;
     }
@@ -737,7 +750,7 @@ void TextureManager::ObserveTexture( TextureInfo& textureInfo,
 }
 
 void TextureManager::AsyncLoadComplete( AsyncLoadingInfoContainerType& loadingContainer, uint32_t id,
-                                        Devel::PixelBuffer pixelBuffer )
+                                        Devel::PixelBuffer pixelBuffer, bool isMaskTask )
 {
   DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::AsyncLoadComplete( id:%d )\n", id );
 
@@ -758,6 +771,10 @@ void TextureManager::AsyncLoadComplete( AsyncLoadingInfoContainerType& loadingCo
 
         if( textureInfo.loadState != CANCELLED )
         {
+          if( isMaskTask )
+          {
+            textureInfo.loadState = MASK_APPLIED;
+          }
           // textureInfo can be invalidated after this call (as the mTextureInfoContainer may be modified)
           PostLoad( textureInfo, pixelBuffer );
         }
@@ -787,18 +804,25 @@ void TextureManager::PostLoad( TextureInfo& textureInfo, Devel::PixelBuffer& pix
       // wait for the mask to finish loading.
       if( textureInfo.maskTextureId != INVALID_TEXTURE_ID )
       {
-        LoadState maskLoadState = GetTextureStateInternal( textureInfo.maskTextureId );
-        if( maskLoadState == LOADING )
+        if( textureInfo.loadState == MASK_APPLIED )
         {
-          textureInfo.pixelBuffer = pixelBuffer; // Store the pixel buffer temporarily
-          textureInfo.loadState = WAITING_FOR_MASK;
-        }
-        else if( maskLoadState == LOAD_FINISHED )
-        {
-          ApplyMask( pixelBuffer, textureInfo.maskTextureId, textureInfo.scaleFactor, textureInfo.cropToMask );
           UploadTexture( pixelBuffer, textureInfo );
           NotifyObservers( textureInfo, true );
         }
+        else
+        {
+          LoadState maskLoadState = GetTextureStateInternal( textureInfo.maskTextureId );
+          textureInfo.pixelBuffer = pixelBuffer; // Store the pixel buffer temporarily
+          if( maskLoadState == LOADING )
+          {
+            textureInfo.loadState = WAITING_FOR_MASK;
+          }
+          else if( maskLoadState == LOAD_FINISHED )
+          {
+            // Send New Task to Thread
+            ApplyMask( textureInfo, textureInfo.maskTextureId );
+          }
+        }
       }
       else
       {
@@ -818,7 +842,6 @@ void TextureManager::PostLoad( TextureInfo& textureInfo, Devel::PixelBuffer& pix
   }
   else
   {
-    DALI_LOG_ERROR( "TextureManager::AsyncImageLoad(%s) failed\n", textureInfo.url.GetUrl().c_str() );
     // @todo If the load was unsuccessful, upload the broken image.
     textureInfo.loadState = LOAD_FAILED;
     CheckForWaitingTexture( textureInfo );
@@ -838,18 +861,15 @@ void TextureManager::CheckForWaitingTexture( TextureInfo& maskTextureInfo )
         mTextureInfoContainer[cacheIndex].loadState == WAITING_FOR_MASK )
     {
       TextureInfo& textureInfo( mTextureInfoContainer[cacheIndex] );
-      Devel::PixelBuffer pixelBuffer = textureInfo.pixelBuffer;
-      textureInfo.pixelBuffer.Reset();
 
       if( maskTextureInfo.loadState == LOAD_FINISHED )
       {
-        ApplyMask( pixelBuffer, maskTextureInfo.textureId, textureInfo.scaleFactor, textureInfo.cropToMask );
-        UploadTexture( pixelBuffer, textureInfo );
-        NotifyObservers( textureInfo, true );
+        // Send New Task to Thread
+        ApplyMask( textureInfo, maskTextureInfo.textureId );
       }
       else
       {
-        DALI_LOG_ERROR( "TextureManager::ApplyMask to %s failed\n", textureInfo.url.GetUrl().c_str() );
+        textureInfo.pixelBuffer.Reset();
         textureInfo.loadState = LOAD_FAILED;
         NotifyObservers( textureInfo, false );
       }
@@ -857,15 +877,23 @@ void TextureManager::CheckForWaitingTexture( TextureInfo& maskTextureInfo )
   }
 }
 
-void TextureManager::ApplyMask(
-  Devel::PixelBuffer& pixelBuffer, TextureId maskTextureId,
-  float contentScale, bool cropToMask )
+void TextureManager::ApplyMask( TextureInfo& textureInfo, TextureId maskTextureId )
 {
   int maskCacheIndex = GetCacheIndexFromId( maskTextureId );
   if( maskCacheIndex != INVALID_CACHE_INDEX )
   {
     Devel::PixelBuffer maskPixelBuffer = mTextureInfoContainer[maskCacheIndex].pixelBuffer;
-    pixelBuffer.ApplyMask( maskPixelBuffer, contentScale, cropToMask );
+    Devel::PixelBuffer pixelBuffer = textureInfo.pixelBuffer;
+    textureInfo.pixelBuffer.Reset();
+
+    DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::ApplyMask(): url:%s sync:%s\n",
+                   textureInfo.url.GetUrl().c_str(), textureInfo.loadSynchronously?"T":"F" );
+
+    textureInfo.loadState = MASK_APPLYING;
+    auto& loadersContainer = textureInfo.url.IsLocalResource() ? mAsyncLocalLoaders : mAsyncRemoteLoaders;
+    auto loadingHelperIt = loadersContainer.GetNext();
+    DALI_ASSERT_ALWAYS(loadingHelperIt != loadersContainer.End());
+    loadingHelperIt->ApplyMask( textureInfo.textureId, pixelBuffer, maskPixelBuffer, textureInfo.scaleFactor, textureInfo.cropToMask );
   }
 }
 
@@ -1121,7 +1149,18 @@ void TextureManager::AsyncLoadingHelper::Load(TextureId          textureId,
                                               DevelAsyncImageLoader::PreMultiplyOnLoad  preMultiplyOnLoad)
 {
   mLoadingInfoContainer.push_back(AsyncLoadingInfo(textureId));
-  auto id = DevelAsyncImageLoader::Load(mLoader, url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad);
+  auto id = DevelAsyncImageLoader::Load( mLoader, url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad );
+  mLoadingInfoContainer.back().loadId = id;
+}
+
+void TextureManager::AsyncLoadingHelper::ApplyMask( TextureId textureId,
+                                               Devel::PixelBuffer pixelBuffer,
+                                               Devel::PixelBuffer maskPixelBuffer,
+                                               float contentScale,
+                                               bool cropToMask )
+{
+  mLoadingInfoContainer.push_back(AsyncLoadingInfo(textureId));
+  auto id = DevelAsyncImageLoader::ApplyMask( mLoader, pixelBuffer, maskPixelBuffer, contentScale, cropToMask );
   mLoadingInfoContainer.back().loadId = id;
 }
 
@@ -1143,9 +1182,10 @@ TextureManager::AsyncLoadingHelper::AsyncLoadingHelper(
 }
 
 void TextureManager::AsyncLoadingHelper::AsyncLoadComplete(uint32_t           id,
-                                                           Devel::PixelBuffer pixelBuffer)
+                                                           Devel::PixelBuffer pixelBuffer,
+                                                           bool isMaskTask)
 {
-  mTextureManager.AsyncLoadComplete(mLoadingInfoContainer, id, pixelBuffer);
+  mTextureManager.AsyncLoadComplete(mLoadingInfoContainer, id, pixelBuffer, isMaskTask);
 }
 
 void TextureManager::SetBrokenImageUrl(const std::string& brokenImageUrl)
index 2cb06bd..d2c55fd 100755 (executable)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H
 
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -99,6 +99,8 @@ public:
     LOADING,         ///< Loading has been started, but not finished.
     LOAD_FINISHED,   ///< Loading has finished. (for CPU storage only)
     WAITING_FOR_MASK,///< Loading has finished, but waiting for mask image
+    MASK_APPLYING,   ///< Loading has finished, Mask is applying
+    MASK_APPLIED,    ///< Loading has finished, Mask is applyied by GPU
     UPLOADED,        ///< Uploaded and ready. (For GPU upload only)
     CANCELLED,       ///< Removed before loading completed
     LOAD_FAILED      ///< Async loading failed, e.g. connection problem
@@ -585,8 +587,9 @@ private:
    * @param[in] container The Async loading container
    * @param[in] id        This is the async image loaders Id
    * @param[in] pixelBuffer The loaded image data
+   * @param[in] isMaskTask whether this task is for mask or not
    */
-  void AsyncLoadComplete( AsyncLoadingInfoContainerType& container, uint32_t id, Devel::PixelBuffer pixelBuffer );
+  void AsyncLoadComplete( AsyncLoadingInfoContainerType& container, uint32_t id, Devel::PixelBuffer pixelBuffer, bool isMaskTask );
 
   /**
    * @brief Performs Post-Load steps including atlasing.
@@ -605,13 +608,10 @@ private:
 
   /**
    * Apply the mask to the pixelBuffer.
-   * @param[in] pixelBuffer The pixelBuffer to apply the mask to
+   * @param[in] textureInfo The information of texture to apply the mask to
    * @param[in] maskTextureId The texture id of the mask.
-   * @param[in] contentScale The factor to scale the content
-   * @param[in] cropToMask Whether to crop the content to the mask size
    */
-  void ApplyMask( Devel::PixelBuffer& pixelBuffer, TextureId maskTextureId,
-                  float contentScale, bool cropToMask );
+  void ApplyMask( TextureInfo& textureInfo, TextureId maskTextureId );
 
   /**
    * Upload the texture specified in pixelBuffer to the appropriate location
@@ -723,6 +723,20 @@ private:
               bool orientationCorrection,
               DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
 
+    /**
+     * @brief Apply mask
+     * @param [in] id of the texture
+     * @param [in] pixelBuffer of the to be masked image
+     * @param [in] maskPixelBuffer of the mask image
+     * @param [in] contentScale The factor to scale the content
+     * @param [in] cropToMask Whether to crop the content to the mask size
+     */
+    void ApplyMask( TextureId textureId,
+                    Devel::PixelBuffer pixelBuffer,
+                    Devel::PixelBuffer maskPixelBuffer,
+                    float contentScale,
+                    bool cropToMask );
+
   public:
     AsyncLoadingHelper(const AsyncLoadingHelper&) = delete;
     AsyncLoadingHelper& operator=(const AsyncLoadingHelper&) = delete;
@@ -742,8 +756,9 @@ private:
      * @brief Callback to be called when texture loading is complete, it passes the pixel buffer on to texture manager.
      * @param[in] id          Loader id
      * @param[in] pixelBuffer Image data
+     * @param[in] isMaskTask whether this task is for mask or not
      */
-    void AsyncLoadComplete(uint32_t id, Devel::PixelBuffer pixelBuffer);
+    void AsyncLoadComplete(uint32_t id, Devel::PixelBuffer pixelBuffer, bool isMaskTask);
 
   private:
     Toolkit::AsyncImageLoader     mLoader;