[Tizen] CPU Alpha Masking for Animated Image Visual 36/267936/13
authorseungho <sbsh.baek@samsung.com>
Mon, 13 Dec 2021 12:57:14 +0000 (21:57 +0900)
committerseungho <sbsh.baek@samsung.com>
Tue, 28 Dec 2021 10:09:01 +0000 (19:09 +0900)
Change-Id: Ia8b705570b0b9e9ad792c4c4f7863261ce66a5f4
Signed-off-by: seungho <sbsh.baek@samsung.com>
12 files changed:
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/texture-manager-impl.cpp
dali-toolkit/internal/visuals/texture-manager-impl.h

index cc90d5d..e830602 100644 (file)
@@ -174,7 +174,7 @@ void AnimatedImageVisual::CreateImageCache()
 
   if(mAnimatedImageLoading)
   {
-    mImageCache = new RollingAnimatedImageCache(textureManager, mAnimatedImageLoading, *this, mCacheSize, mBatchSize, IsSynchronousLoadingRequired());
+    mImageCache = new RollingAnimatedImageCache(textureManager, mAnimatedImageLoading, mMaskingData, *this, mCacheSize, mBatchSize, IsSynchronousLoadingRequired());
   }
   else if(mImageUrls)
   {
@@ -185,11 +185,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, *this, cacheSize, batchSize, mFrameDelay);
+      mImageCache = new RollingImageCache(textureManager, *mImageUrls, mMaskingData, *this, cacheSize, batchSize, mFrameDelay);
     }
     else
     {
-      mImageCache = new FixedImageCache(textureManager, *mImageUrls, *this, batchSize, mFrameDelay);
+      mImageCache = new FixedImageCache(textureManager, *mImageUrls, mMaskingData, *this, batchSize, mFrameDelay);
     }
   }
 
@@ -218,6 +218,7 @@ AnimatedImageVisual::AnimatedImageVisual(VisualFactoryCache& factoryCache, Image
   mCurrentLoopIndex(FIRST_LOOP),
   mLoadPolicy(Toolkit::ImageVisual::LoadPolicy::ATTACHED),
   mReleasePolicy(Toolkit::ImageVisual::ReleasePolicy::DETACHED),
+  mMaskingData(),
   mFrameCount(0),
   mImageSize(),
   mActionStatus(DevelAnimatedImageVisual::Action::PLAY),
@@ -260,6 +261,18 @@ void AnimatedImageVisual::GetNaturalSize(Vector2& naturalSize)
     {
       mImageSize = Dali::GetClosestImageSize((*mImageUrls)[0].mUrl);
     }
+
+    if(mMaskingData && mMaskingData->mAlphaMaskUrl.IsValid() &&
+       mMaskingData->mCropToMask)
+    {
+      ImageDimensions dimensions = Dali::GetClosestImageSize(mMaskingData->mAlphaMaskUrl.GetUrl());
+      if(dimensions != ImageDimensions(0, 0))
+      {
+        naturalSize.x = dimensions.GetWidth();
+        naturalSize.y = dimensions.GetHeight();
+      }
+      return;
+    }
   }
 
   naturalSize.width  = mImageSize.GetWidth();
@@ -303,6 +316,13 @@ void AnimatedImageVisual::DoCreatePropertyMap(Property::Map& map) const
 
   map.Insert(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mStopBehavior);
 
+  if(mMaskingData)
+  {
+    map.Insert(Toolkit::ImageVisual::Property::ALPHA_MASK_URL, mMaskingData->mAlphaMaskUrl.GetUrl());
+    map.Insert(Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE, mMaskingData->mContentScaleFactor);
+    map.Insert(Toolkit::ImageVisual::Property::CROP_TO_MASK, mMaskingData->mCropToMask);
+  }
+
   map.Insert(Toolkit::ImageVisual::Property::LOAD_POLICY, mLoadPolicy);
   map.Insert(Toolkit::ImageVisual::Property::RELEASE_POLICY, mReleasePolicy);
 }
@@ -418,6 +438,18 @@ void AnimatedImageVisual::DoSetProperties(const Property::Map& propertyMap)
       {
         DoSetProperty(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, keyValue.second);
       }
+      else if(keyValue.first == ALPHA_MASK_URL)
+      {
+        DoSetProperty(Toolkit::ImageVisual::Property::ALPHA_MASK_URL, keyValue.second);
+      }
+      else if(keyValue.first == MASK_CONTENT_SCALE_NAME)
+      {
+        DoSetProperty(Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE, keyValue.second);
+      }
+      else if(keyValue.first == CROP_TO_MASK_NAME)
+      {
+        DoSetProperty(Toolkit::ImageVisual::Property::CROP_TO_MASK, keyValue.second);
+      }
       else if(keyValue.first == LOAD_POLICY_NAME)
       {
         DoSetProperty(Toolkit::ImageVisual::Property::LOAD_POLICY, keyValue.second);
@@ -559,6 +591,39 @@ void AnimatedImageVisual::DoSetProperty(Property::Index        index,
       break;
     }
 
+    case Toolkit::ImageVisual::Property::ALPHA_MASK_URL:
+    {
+      std::string alphaUrl = "";
+      if(value.Get(alphaUrl))
+      {
+        AllocateMaskData();
+        mMaskingData->mAlphaMaskUrl = alphaUrl;
+      }
+      break;
+    }
+
+    case Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE:
+    {
+      float scale = 1.0f;
+      if(value.Get(scale))
+      {
+        AllocateMaskData();
+        mMaskingData->mContentScaleFactor = scale;
+      }
+      break;
+    }
+
+    case Toolkit::ImageVisual::Property::CROP_TO_MASK:
+    {
+      bool crop = false;
+      if(value.Get(crop))
+      {
+        AllocateMaskData();
+        mMaskingData->mCropToMask = crop;
+      }
+      break;
+    }
+
     case Toolkit::ImageVisual::Property::RELEASE_POLICY:
     {
       int releasePolicy = 0;
@@ -870,6 +935,14 @@ Shader AnimatedImageVisual::GenerateShader() const
   return shader;
 }
 
+void AnimatedImageVisual::AllocateMaskData()
+{
+  if(!mMaskingData)
+  {
+    mMaskingData.reset(new TextureManager::MaskingData());
+  }
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index 6679ef2..210b588 100644 (file)
@@ -247,6 +247,12 @@ private:
    */
   TextureSet SetLoadingFailed();
 
+  /**
+   * @brief Allocate mask data.
+   * This is allocated only once.
+   */
+  void AllocateMaskData();
+
   // Undefined
   AnimatedImageVisual(const AnimatedImageVisual& animatedImageVisual);
 
@@ -274,9 +280,10 @@ private:
   int16_t              mLoopCount;
   int16_t              mCurrentLoopIndex;
 
-  // Variables for image visual policy.
+  // Variables for image visual properties.
   Dali::Toolkit::ImageVisual::LoadPolicy::Type    mLoadPolicy;
   Dali::Toolkit::ImageVisual::ReleasePolicy::Type mReleasePolicy;
+  TextureManager::MaskingDataPointer              mMaskingData;
 
   // Shared variables
   uint32_t        mFrameCount; // Number of frames
index c90e86e..004cff3 100644 (file)
@@ -36,9 +36,13 @@ static constexpr bool ENABLE_ORIENTATION_CORRECTION(true);
 static constexpr uint32_t FIRST_FRAME_INDEX = 0u;
 } // namespace
 
-FixedImageCache::FixedImageCache(
-  TextureManager& textureManager, UrlList& urlList, ImageCache::FrameReadyObserver& observer, uint32_t batchSize, uint32_t interval)
-: ImageCache(textureManager, observer, batchSize, interval),
+FixedImageCache::FixedImageCache(TextureManager&                     textureManager,
+                                 UrlList&                            urlList,
+                                 TextureManager::MaskingDataPointer& maskingData,
+                                 ImageCache::FrameReadyObserver&     observer,
+                                 uint32_t                            batchSize,
+                                 uint32_t                            interval)
+: ImageCache(textureManager, maskingData, observer, batchSize, interval),
   mImageUrls(urlList),
   mFront(FIRST_FRAME_INDEX)
 {
@@ -126,7 +130,6 @@ void FixedImageCache::LoadBatch()
     bool                               synchronousLoading = false;
     bool                               atlasingStatus     = false;
     bool                               loadingStatus      = false;
-    TextureManager::MaskingDataPointer maskInfo           = nullptr;
     AtlasUploadObserver*               atlasObserver      = nullptr;
     ImageAtlasManagerPtr               imageAtlasManager  = nullptr;
     Vector4                            textureRect;
@@ -134,7 +137,7 @@ void FixedImageCache::LoadBatch()
     auto                               preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
     TextureSet textureSet = mTextureManager.LoadTexture(
-      url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, maskInfo, synchronousLoading, mImageUrls[frameIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
+      url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, mImageUrls[frameIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
 
     // If textureSet is returned but loadingState is false than load state is LOAD_FINISHED. (Notification is not comming yet.)
     // If textureSet is null and the request is synchronous, load state is LOAD_FAILED.
@@ -198,10 +201,16 @@ void FixedImageCache::ClearCache()
     {
       mTextureManager.Remove(mImageUrls[i].mTextureId, this);
       mImageUrls[i].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+
+      if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
+      {
+        mTextureManager.Remove(mMaskingData->mAlphaMaskId, this);
+      }
     }
   }
   mReadyFlags.clear();
   mLoadStates.assign(mImageUrls.size(), TextureManager::LoadState::NOT_STARTED);
+  mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
 }
 
 void FixedImageCache::UploadComplete(
index 93a32b6..3d80db0 100644 (file)
@@ -33,19 +33,21 @@ public:
   /**
    * Constructor.
    * @param[in] textureManager The texture manager
-   * @param[in] urlList List of urls to cache
-   * @param[in] observer FrameReady observer
-   * @param[in] batchSize The size of a batch to load
-   * @param[in] interval Time interval between each frame
+   * @param[in] urlList        List of urls to cache
+   * @param[in] maskingData    Masking data to be applied.
+   * @param[in] observer       FrameReady observer
+   * @param[in] batchSize      The size of a batch to load
+   * @param[in] interval       Time interval between each frame
    *
    * This will start loading textures immediately, according to the
    * batch and cache sizes. The cache is as large as the number of urls.
    */
-  FixedImageCache(TextureManager&                 textureManager,
-                  UrlList&                        urlList,
-                  ImageCache::FrameReadyObserver& observer,
-                  uint32_t                        batchSize,
-                  uint32_t                        interval);
+  FixedImageCache(TextureManager&                     textureManager,
+                  UrlList&                            urlList,
+                  TextureManager::MaskingDataPointer& maskingData,
+                  ImageCache::FrameReadyObserver&     observer,
+                  uint32_t                            batchSize,
+                  uint32_t                            interval);
 
   ~FixedImageCache() override;
 
index dcd0d40..8f001f7 100644 (file)
@@ -22,12 +22,14 @@ namespace Toolkit
 {
 namespace Internal
 {
-ImageCache::ImageCache(TextureManager&                 textureManager,
-                       ImageCache::FrameReadyObserver& observer,
-                       uint32_t                        batchSize,
-                       uint32_t                        interval)
+ImageCache::ImageCache(TextureManager&                     textureManager,
+                       TextureManager::MaskingDataPointer& maskingData,
+                       ImageCache::FrameReadyObserver&     observer,
+                       uint32_t                            batchSize,
+                       uint32_t                            interval)
 : mTextureManager(textureManager),
   mObserver(observer),
+  mMaskingData(maskingData),
   mBatchSize(batchSize),
   mInterval(interval),
   mRequestingLoad(false),
index 432ad8c..dba45fa 100644 (file)
@@ -59,18 +59,19 @@ public:
   /**
    * @brief Constructor.
    * @param[in] textureManager The texture manager
-   * @param[in] urlList List of urls to cache
-   * @param[in] observer FrameReady observer
-   * @param[in] batchSize The size of a batch to load
-   * @param[in] interval Time interval between each frame
+   * @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 between each frame
    *
    * This will start loading textures immediately, according to the
    * batch and cache sizes. The cache is as large as the number of urls.
    */
-  ImageCache(TextureManager&                 textureManager,
-             ImageCache::FrameReadyObserver& observer,
-             uint32_t                        batchSize,
-             uint32_t                        interval);
+  ImageCache(TextureManager&                     textureManager,
+             TextureManager::MaskingDataPointer& maskingData,
+             ImageCache::FrameReadyObserver&     observer,
+             uint32_t                            batchSize,
+             uint32_t                            interval);
 
   virtual ~ImageCache();
 
@@ -139,13 +140,16 @@ private:
    */
   void TextureManagerDestroyed() final;
 
+  void AllocateMaskData();
+
 protected:
-  TextureManager&     mTextureManager;
-  FrameReadyObserver& mObserver;
-  uint32_t            mBatchSize;
-  uint32_t            mInterval;
-  bool                mRequestingLoad : 1;
-  bool                mTextureManagerAlive : 1;
+  TextureManager&                     mTextureManager;
+  FrameReadyObserver&                 mObserver;
+  TextureManager::MaskingDataPointer& mMaskingData;
+  uint32_t                            mBatchSize;
+  uint32_t                            mInterval;
+  bool                                mRequestingLoad : 1;
+  bool                                mTextureManagerAlive : 1;
 };
 
 } //namespace Internal
index f8f8310..a950ac7 100644 (file)
@@ -59,9 +59,14 @@ static constexpr uint32_t SINGLE_IMAGE_COUNT = 1u;
 static constexpr uint32_t FIRST_FRAME_INDEX  = 0u;
 } // namespace
 
-RollingAnimatedImageCache::RollingAnimatedImageCache(
-  TextureManager& textureManager, AnimatedImageLoading& animatedImageLoading, ImageCache::FrameReadyObserver& observer, uint16_t cacheSize, uint16_t batchSize, bool isSynchronousLoading)
-: ImageCache(textureManager, observer, batchSize, 0u),
+RollingAnimatedImageCache::RollingAnimatedImageCache(TextureManager&                     textureManager,
+                                                     AnimatedImageLoading&               animatedImageLoading,
+                                                     TextureManager::MaskingDataPointer& maskingData,
+                                                     ImageCache::FrameReadyObserver&     observer,
+                                                     uint16_t                            cacheSize,
+                                                     uint16_t                            batchSize,
+                                                     bool                                isSynchronousLoading)
+: ImageCache(textureManager, maskingData, observer, batchSize, 0u),
   mAnimatedImageLoading(animatedImageLoading),
   mFrameCount(SINGLE_IMAGE_COUNT),
   mFrameIndex(FIRST_FRAME_INDEX),
@@ -85,10 +90,8 @@ TextureSet RollingAnimatedImageCache::Frame(uint32_t frameIndex)
   bool popExist = false;
   while(!mQueue.IsEmpty() && mQueue.Front().mFrameNumber != frameIndex)
   {
-    ImageFrame imageFrame = mQueue.PopFront();
-    mTextureManager.Remove(mImageUrls[imageFrame.mFrameNumber].mTextureId, this);
-    mImageUrls[imageFrame.mFrameNumber].mTextureId = TextureManager::INVALID_TEXTURE_ID;
-    popExist                                       = true;
+    PopFrontCache();
+    popExist = true;
   }
 
   TextureSet textureSet;
@@ -191,6 +194,7 @@ TextureSet RollingAnimatedImageCache::RequestFrameLoading(uint32_t frameIndex, b
                                                                    frameIndex,
                                                                    loadingStatus,
                                                                    mImageUrls[frameIndex].mTextureId,
+                                                                   mMaskingData,
                                                                    SamplingMode::BOX_THEN_LINEAR,
                                                                    Dali::WrapMode::Type::DEFAULT,
                                                                    Dali::WrapMode::Type::DEFAULT,
@@ -267,13 +271,27 @@ TextureManager::TextureId RollingAnimatedImageCache::GetCachedTextureId(int inde
   return mImageUrls[mQueue[index].mFrameNumber].mTextureId;
 }
 
+void RollingAnimatedImageCache::PopFrontCache()
+{
+  ImageFrame imageFrame = mQueue.PopFront();
+  mTextureManager.Remove(mImageUrls[imageFrame.mFrameNumber].mTextureId, this);
+  mImageUrls[imageFrame.mFrameNumber].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+
+  if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
+  {
+    mTextureManager.Remove(mMaskingData->mAlphaMaskId, this);
+    if(mQueue.IsEmpty())
+    {
+      mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
+    }
+  }
+}
+
 void RollingAnimatedImageCache::ClearCache()
 {
   while(mTextureManagerAlive && !mQueue.IsEmpty())
   {
-    ImageFrame imageFrame = mQueue.PopFront();
-    mTextureManager.Remove(mImageUrls[imageFrame.mFrameNumber].mTextureId, this);
-    mImageUrls[imageFrame.mFrameNumber].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+    PopFrontCache();
   }
 
   mLoadWaitingQueue.clear();
index 6a06717..a35ba7c 100644 (file)
@@ -41,22 +41,24 @@ class RollingAnimatedImageCache : public ImageCache, public TextureUploadObserve
 public:
   /**
    * @brief Constructor.
-   * @param[in] textureManager The texture manager
-   * @param[in] animatedImageLoader The loaded animated image
-   * @param[in] observer FrameReady observer
-   * @param[in] cacheSize The size of the cache
-   * @param[in] batchSize The size of a batch to load
+   * @param[in] textureManager       The texture manager
+   * @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
+   * @param[in] batchSize            The size of a batch to load
    * @param[in] isSynchronousLoading The flag to define whether to load first frame synchronously
    *
    * This will start loading textures immediately, according to the
    * batch and cache sizes.
    */
-  RollingAnimatedImageCache(TextureManager&                 textureManager,
-                            AnimatedImageLoading&           animatedImageLoader,
-                            ImageCache::FrameReadyObserver& observer,
-                            uint16_t                        cacheSize,
-                            uint16_t                        batchSize,
-                            bool                            isSynchronousLoading);
+  RollingAnimatedImageCache(TextureManager&                     textureManager,
+                            AnimatedImageLoading&               animatedImageLoading,
+                            TextureManager::MaskingDataPointer& maskingData,
+                            ImageCache::FrameReadyObserver&     observer,
+                            uint16_t                            cacheSize,
+                            uint16_t                            batchSize,
+                            bool                                isSynchronousLoading);
 
   /**
    * @brief Destructor
@@ -143,6 +145,11 @@ private:
    */
   TextureManager::TextureId GetCachedTextureId(int index) const;
 
+  /**
+   * @brief Pop front entity of Cache.
+   */
+  void PopFrontCache();
+
 protected:
 
   /**
index c776605..df41982 100644 (file)
@@ -56,9 +56,14 @@ namespace Toolkit
 {
 namespace Internal
 {
-RollingImageCache::RollingImageCache(
-  TextureManager& textureManager, UrlList& urlList, ImageCache::FrameReadyObserver& observer, uint16_t cacheSize, uint16_t batchSize, uint32_t interval)
-: ImageCache(textureManager, observer, batchSize, interval),
+RollingImageCache::RollingImageCache(TextureManager&                     textureManager,
+                                     UrlList&                            urlList,
+                                     TextureManager::MaskingDataPointer& maskingData,
+                                     ImageCache::FrameReadyObserver&     observer,
+                                     uint16_t                            cacheSize,
+                                     uint16_t                            batchSize,
+                                     uint32_t                            interval)
+: ImageCache(textureManager, maskingData, observer, batchSize, interval),
   mImageUrls(urlList),
   mQueue(cacheSize)
 {
@@ -76,9 +81,7 @@ TextureSet RollingImageCache::Frame(uint32_t frameIndex)
   bool popExist = false;
   while(!mQueue.IsEmpty() && mQueue.Front().mUrlIndex != frameIndex)
   {
-    ImageFrame imageFrame = mQueue.PopFront();
-    mTextureManager.Remove(mImageUrls[imageFrame.mUrlIndex].mTextureId, this);
-    mImageUrls[imageFrame.mUrlIndex].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+    PopFrontCache();
     popExist                                    = true;
   }
   if(popExist || mQueue.IsEmpty())
@@ -159,7 +162,6 @@ void RollingImageCache::LoadBatch(uint32_t frameIndex)
     bool                               synchronousLoading = false;
     bool                               atlasingStatus     = false;
     bool                               loadingStatus      = false;
-    TextureManager::MaskingDataPointer maskInfo           = nullptr;
     AtlasUploadObserver*               atlasObserver      = nullptr;
     ImageAtlasManagerPtr               imageAtlasManager  = nullptr;
     Vector4                            textureRect;
@@ -167,7 +169,7 @@ void RollingImageCache::LoadBatch(uint32_t frameIndex)
     auto                               preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
     TextureSet textureSet = mTextureManager.LoadTexture(
-      url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, maskInfo, synchronousLoading, mImageUrls[imageFrame.mUrlIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
+      url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, mImageUrls[imageFrame.mUrlIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
 
     // If textureSet is returned but loadingState is false than load state is LOAD_FINISHED. (Notification is not comming yet.)
     // If textureSet is null and the request is synchronous, load state is LOAD_FAILED.
@@ -232,13 +234,27 @@ void RollingImageCache::CheckFrontFrame(bool wasReady)
   }
 }
 
+void RollingImageCache::PopFrontCache()
+{
+  ImageFrame imageFrame = mQueue.PopFront();
+  mTextureManager.Remove(mImageUrls[imageFrame.mUrlIndex].mTextureId, this);
+  mImageUrls[imageFrame.mUrlIndex].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+
+  if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
+  {
+    mTextureManager.Remove(mMaskingData->mAlphaMaskId, this);
+    if(mQueue.IsEmpty())
+    {
+      mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
+    }
+  }
+}
+
 void RollingImageCache::ClearCache()
 {
   while(mTextureManagerAlive && !mQueue.IsEmpty())
   {
-    ImageFrame imageFrame = mQueue.PopFront();
-    mTextureManager.Remove(mImageUrls[imageFrame.mUrlIndex].mTextureId, this);
-    mImageUrls[imageFrame.mUrlIndex].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+    PopFrontCache();
   }
   mLoadStates.assign(mImageUrls.size(), TextureManager::LoadState::NOT_STARTED);
 }
index 6f168df..0f0d883 100644 (file)
@@ -39,21 +39,23 @@ public:
   /**
    * Constructor.
    * @param[in] textureManager The texture manager
-   * @param[in] urlList List of urls to cache
-   * @param[in] observer FrameReady observer
-   * @param[in] cacheSize The size of the cache
-   * @param[in] batchSize The size of a batch to load
-   * @param[in] interval Time interval between each frame
+   * @param[in] urlList        List of urls to cache
+   * @param[in] maskingData    Masking data to be applied.
+   * @param[in] observer       FrameReady observer
+   * @param[in] cacheSize      The size of the cache
+   * @param[in] batchSize      The size of a batch to load
+   * @param[in] interval       Time interval between each frame
    *
    * This will start loading textures immediately, according to the
    * batch and cache sizes.
    */
-  RollingImageCache(TextureManager&                 textureManager,
-                    UrlList&                        urlList,
-                    ImageCache::FrameReadyObserver& observer,
-                    uint16_t                        cacheSize,
-                    uint16_t                        batchSize,
-                    uint32_t                        interval);
+  RollingImageCache(TextureManager&                     textureManager,
+                    UrlList&                            urlList,
+                    TextureManager::MaskingDataPointer& maskingData,
+                    ImageCache::FrameReadyObserver&     observer,
+                    uint16_t                            cacheSize,
+                    uint16_t                            batchSize,
+                    uint32_t                            interval);
 
   /**
    * Destructor
@@ -139,6 +141,11 @@ private:
    */
   void CheckFrontFrame(bool wasReady);
 
+  /**
+   * @brief Pop front entity of Cache.
+   */
+  void PopFrontCache();
+
 protected:
 
   /**
index b1f18eb..e694c57 100644 (file)
@@ -146,6 +146,7 @@ TextureSet TextureManager::LoadAnimatedImageTexture(Dali::AnimatedImageLoading a
                                                     uint32_t                   frameIndex,
                                                     bool&                      loadingStatus,
                                                     TextureManager::TextureId& textureId,
+                                                    MaskingDataPointer&        maskInfo,
                                                     Dali::SamplingMode::Type   samplingMode,
                                                     Dali::WrapMode::Type       wrapModeU,
                                                     Dali::WrapMode::Type       wrapModeV,
@@ -168,6 +169,15 @@ TextureSet TextureManager::LoadAnimatedImageTexture(Dali::AnimatedImageLoading a
     }
     else
     {
+      if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
+      {
+        Devel::PixelBuffer maskPixelBuffer = LoadImageFromFile(maskInfo->mAlphaMaskUrl.GetUrl(), ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, true);
+        if(maskPixelBuffer)
+        {
+          pixelBuffer.ApplyMask(maskPixelBuffer, maskInfo->mContentScaleFactor, maskInfo->mCropToMask);
+        }
+      }
+
       PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
       if(!textureSet)
       {
@@ -180,9 +190,36 @@ TextureSet TextureManager::LoadAnimatedImageTexture(Dali::AnimatedImageLoading a
   }
   else
   {
-    loadingStatus = true;
-    auto preMultiply                    = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
-    textureId                           = RequestLoadInternal(animatedImageLoading.GetUrl(), INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, TextureManager::NO_ATLAS, false, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiply, animatedImageLoading, frameIndex, useCache);
+    TextureId alphaMaskId        = INVALID_TEXTURE_ID;
+    float     contentScaleFactor = 1.0f;
+    bool      cropToMask         = false;
+    if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
+    {
+      maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl);
+      alphaMaskId            = maskInfo->mAlphaMaskId;
+      contentScaleFactor     = maskInfo->mContentScaleFactor;
+      cropToMask             = maskInfo->mCropToMask;
+    }
+
+    loadingStatus    = true;
+    auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+    textureId        = RequestLoadInternal(animatedImageLoading.GetUrl(),
+                                    alphaMaskId,
+                                    contentScaleFactor,
+                                    ImageDimensions(),
+                                    FittingMode::SCALE_TO_FILL,
+                                    SamplingMode::BOX_THEN_LINEAR,
+                                    TextureManager::NO_ATLAS,
+                                    cropToMask,
+                                    StorageType::UPLOAD_TO_TEXTURE,
+                                    textureObserver,
+                                    true,
+                                    TextureManager::ReloadPolicy::CACHED,
+                                    preMultiply,
+                                    animatedImageLoading,
+                                    frameIndex,
+                                    useCache);
+
     TextureManager::LoadState loadState = GetTextureStateInternal(textureId);
     if(loadState == TextureManager::LoadState::UPLOADED)
     {
@@ -244,8 +281,25 @@ Devel::PixelBuffer TextureManager::LoadPixelBuffer(
   return pixelBuffer;
 }
 
-TextureSet TextureManager::LoadTexture(
-  const VisualUrl& url, Dali::ImageDimensions desiredSize, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode, MaskingDataPointer& maskInfo, bool synchronousLoading, TextureManager::TextureId& textureId, Vector4& textureRect, Dali::ImageDimensions& textureRectSize, bool& atlasingStatus, bool& loadingStatus, Dali::WrapMode::Type wrapModeU, Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver, AtlasUploadObserver* atlasObserver, ImageAtlasManagerPtr imageAtlasManager, bool orientationCorrection, TextureManager::ReloadPolicy reloadPolicy, TextureManager::MultiplyOnLoad& preMultiplyOnLoad)
+TextureSet TextureManager::LoadTexture(const VisualUrl&                url,
+                                       Dali::ImageDimensions           desiredSize,
+                                       Dali::FittingMode::Type         fittingMode,
+                                       Dali::SamplingMode::Type        samplingMode,
+                                       MaskingDataPointer&             maskInfo,
+                                       bool                            synchronousLoading,
+                                       TextureManager::TextureId&      textureId,
+                                       Vector4&                        textureRect,
+                                       Dali::ImageDimensions&          textureRectSize,
+                                       bool&                           atlasingStatus,
+                                       bool&                           loadingStatus,
+                                       Dali::WrapMode::Type            wrapModeU,
+                                       Dali::WrapMode::Type            wrapModeV,
+                                       TextureUploadObserver*          textureObserver,
+                                       AtlasUploadObserver*            atlasObserver,
+                                       ImageAtlasManagerPtr            imageAtlasManager,
+                                       bool                            orientationCorrection,
+                                       TextureManager::ReloadPolicy    reloadPolicy,
+                                       TextureManager::MultiplyOnLoad& preMultiplyOnLoad)
 {
   TextureSet textureSet;
 
index 4fddf49..0da2ba2 100644 (file)
@@ -59,7 +59,7 @@ class TextureManager : public ConnectionTracker
 {
 public:
   typedef int32_t  TextureId;               ///< The TextureId type. This is used as a handle to refer to a particular Texture.
-  static const int INVALID_TEXTURE_ID = -1; ///< Used to represent a null TextureId or error
+  static constexpr int32_t INVALID_TEXTURE_ID = -1; ///< Used to represent a null TextureId or error
 
   /**
    * Whether the texture should be atlased or uploaded into it's own GPU texture
@@ -169,6 +169,7 @@ public:
    * @param[in]  frameIndex            The frame index to load.
    * @param[out] loadingStatus         The loading status of the texture
    * @param[out] textureId             The textureId of the frame
+   * @param[in, out] maskInfo          Mask info structure
    * @param[in]  samplingMode          The SamplingMode to use
    * @param[in]  wrapModeU             Horizontal Wrap mode
    * @param[in]  wrapModeV             Vertical Wrap mode
@@ -184,6 +185,7 @@ public:
                                       uint32_t                   frameIndex,
                                       bool&                      loadingStatus,
                                       TextureManager::TextureId& textureId,
+                                      MaskingDataPointer&        maskInfo,
                                       Dali::SamplingMode::Type   samplingMode,
                                       Dali::WrapMode::Type       wrapModeU,
                                       Dali::WrapMode::Type       wrapModeV,