CPU Alpha Masking for Animated Image Visual 20/274420/10
authorseungho <sbsh.baek@samsung.com>
Thu, 28 Apr 2022 05:54:59 +0000 (14:54 +0900)
committerseungho <sbsh.baek@samsung.com>
Wed, 11 May 2022 01:46:35 +0000 (10:46 +0900)
Change-Id: I3b6abac73d248f70998bb992945b96a25c6fb7c8
Signed-off-by: seungho <sbsh.baek@samsung.com>
13 files changed:
automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp
dali-toolkit/internal/texture-manager/texture-manager-impl.cpp
dali-toolkit/internal/texture-manager/texture-manager-impl.h
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

index 1fffc97..55745fb 100644 (file)
@@ -46,8 +46,9 @@ void dali_animated_image_visual_cleanup(void)
 
 namespace
 {
 
 namespace
 {
-const char* TEST_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/application-icon-%02d.png";
-const char* TEST_GIF_FILE_NAME   = TEST_RESOURCE_DIR "/anim.gif";
+const char* TEST_IMAGE_FILE_NAME      = TEST_RESOURCE_DIR "/application-icon-%02d.png";
+const char* TEST_GIF_FILE_NAME        = TEST_RESOURCE_DIR "/anim.gif";
+const char* TEST_MASK_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/mask.png";
 } // namespace
 
 void CopyUrlsIntoArray(Property::Array& urls, int startIndex = 0)
 } // namespace
 
 void CopyUrlsIntoArray(Property::Array& urls, int startIndex = 0)
@@ -78,6 +79,9 @@ int UtcDaliAnimatedImageVisualGetPropertyMap01(void)
       .Add(ImageVisual::Property::PIXEL_AREA, Vector4())
       .Add(ImageVisual::Property::WRAP_MODE_U, WrapMode::REPEAT)
       .Add(ImageVisual::Property::WRAP_MODE_V, WrapMode::DEFAULT)
       .Add(ImageVisual::Property::PIXEL_AREA, Vector4())
       .Add(ImageVisual::Property::WRAP_MODE_U, WrapMode::REPEAT)
       .Add(ImageVisual::Property::WRAP_MODE_V, WrapMode::DEFAULT)
+      .Add(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME)
+      .Add(ImageVisual::Property::MASK_CONTENT_SCALE, 1.6f)
+      .Add(ImageVisual::Property::CROP_TO_MASK, true)
       .Add(DevelVisual::Property::CORNER_RADIUS, 22.2f)
       .Add(DevelVisual::Property::CORNER_RADIUS_POLICY, Visual::Transform::Policy::ABSOLUTE)
       .Add(DevelVisual::Property::BORDERLINE_WIDTH, 33.3f)
       .Add(DevelVisual::Property::CORNER_RADIUS, 22.2f)
       .Add(DevelVisual::Property::CORNER_RADIUS_POLICY, Visual::Transform::Policy::ABSOLUTE)
       .Add(DevelVisual::Property::BORDERLINE_WIDTH, 33.3f)
@@ -115,6 +119,23 @@ int UtcDaliAnimatedImageVisualGetPropertyMap01(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_EQUALS(value->Get<float>(), 0.3f, TEST_LOCATION);
 
   DALI_TEST_CHECK(value);
   DALI_TEST_EQUALS(value->Get<float>(), 0.3f, TEST_LOCATION);
 
+  // Check mask properties
+  value = resultMap.Find(ImageVisual::Property::ALPHA_MASK_URL, Property::STRING);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<std::string>() == TEST_MASK_IMAGE_FILE_NAME);
+
+  value = resultMap.Find(ImageVisual::Property::MASK_CONTENT_SCALE, Property::FLOAT);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<float>(), 1.6f, TEST_LOCATION);
+
+  value = resultMap.Find(ImageVisual::Property::CROP_TO_MASK, Property::BOOLEAN);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<bool>(), true, TEST_LOCATION);
+
+  Vector2 naturalSize;
+  animatedImageVisual.GetNaturalSize(naturalSize);
+  DALI_TEST_EQUALS(naturalSize, Vector2(100, 100), TEST_LOCATION);
+
   // request AnimatedImageVisual with an URL
   Visual::Base animatedImageVisual2 = factory.CreateVisual(TEST_GIF_FILE_NAME, ImageDimensions());
   resultMap.Clear();
   // request AnimatedImageVisual with an URL
   Visual::Base animatedImageVisual2 = factory.CreateVisual(TEST_GIF_FILE_NAME, ImageDimensions());
   resultMap.Clear();
@@ -152,6 +173,9 @@ int UtcDaliAnimatedImageVisualGetPropertyMap02(void)
       .Add("pixelArea", Vector4())
       .Add("wrapModeU", WrapMode::REPEAT)
       .Add("wrapModeV", WrapMode::DEFAULT)
       .Add("pixelArea", Vector4())
       .Add("wrapModeU", WrapMode::REPEAT)
       .Add("wrapModeV", WrapMode::DEFAULT)
+      .Add("alphaMaskUrl", TEST_MASK_IMAGE_FILE_NAME)
+      .Add("maskContentScale", 1.6f)
+      .Add("cropToMask", true)
       .Add("cornerRadius", Vector4(50.0f, 25.0f, 12.5f, 33.0f))
       .Add("cornerRadiusPolicy", Visual::Transform::Policy::RELATIVE)
       .Add("borderlineWidth", 20.0f)
       .Add("cornerRadius", Vector4(50.0f, 25.0f, 12.5f, 33.0f))
       .Add("cornerRadiusPolicy", Visual::Transform::Policy::RELATIVE)
       .Add("borderlineWidth", 20.0f)
@@ -211,6 +235,19 @@ int UtcDaliAnimatedImageVisualGetPropertyMap02(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_EQUALS(value->Get<float>(), -1.0f, TEST_LOCATION);
 
   DALI_TEST_CHECK(value);
   DALI_TEST_EQUALS(value->Get<float>(), -1.0f, TEST_LOCATION);
 
+  // Check mask properties
+  value = resultMap.Find(ImageVisual::Property::ALPHA_MASK_URL, "alphaMaskUrl");
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<std::string>() == TEST_MASK_IMAGE_FILE_NAME);
+
+  value = resultMap.Find(ImageVisual::Property::MASK_CONTENT_SCALE, "maskContentScale");
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<float>(), 1.6f, TEST_LOCATION);
+
+  value = resultMap.Find(ImageVisual::Property::CROP_TO_MASK, "cropToMask");
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<bool>(), true, TEST_LOCATION);
+
   END_TEST;
 }
 
   END_TEST;
 }
 
@@ -235,6 +272,9 @@ int UtcDaliAnimatedImageVisualGetPropertyMap03(void)
       .Add("pixelArea", Vector4())
       .Add("wrapModeU", WrapMode::REPEAT)
       .Add("wrapModeV", WrapMode::DEFAULT)
       .Add("pixelArea", Vector4())
       .Add("wrapModeU", WrapMode::REPEAT)
       .Add("wrapModeV", WrapMode::DEFAULT)
+      .Add("alphaMaskUrl", TEST_MASK_IMAGE_FILE_NAME)
+      .Add("maskContentScale", 1.6f)
+      .Add("cropToMask", true)
       .Add("cornerRadius", 50.5f));
 
   Property::Map resultMap;
       .Add("cornerRadius", 50.5f));
 
   Property::Map resultMap;
@@ -290,6 +330,19 @@ int UtcDaliAnimatedImageVisualGetPropertyMap03(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_EQUALS(value->Get<float>(), 0.0f, TEST_LOCATION);
 
   DALI_TEST_CHECK(value);
   DALI_TEST_EQUALS(value->Get<float>(), 0.0f, TEST_LOCATION);
 
+  // Check mask properties
+  value = resultMap.Find(ImageVisual::Property::ALPHA_MASK_URL, "alphaMaskUrl");
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<std::string>() == TEST_MASK_IMAGE_FILE_NAME);
+
+  value = resultMap.Find(ImageVisual::Property::MASK_CONTENT_SCALE, "maskContentScale");
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<float>(), 1.6f, TEST_LOCATION);
+
+  value = resultMap.Find(ImageVisual::Property::CROP_TO_MASK, "cropToMask");
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<bool>(), true, TEST_LOCATION);
+
   END_TEST;
 }
 
   END_TEST;
 }
 
@@ -472,6 +525,63 @@ int UtcDaliAnimatedImageVisualSynchronousLoading(void)
   END_TEST;
 }
 
   END_TEST;
 }
 
+
+int UtcDaliAnimatedImageVisualSynchronousLoadingWithAlphaMask(void)
+{
+  ToolkitTestApplication application;
+  TestGlAbstraction&     gl = application.GetGlAbstraction();
+
+  {
+    Property::Map propertyMap;
+    propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE);
+    propertyMap.Insert(ImageVisual::Property::URL, TEST_GIF_FILE_NAME);
+    propertyMap.Insert(ImageVisual::Property::BATCH_SIZE, 2);
+    propertyMap.Insert(ImageVisual::Property::CACHE_SIZE, 2);
+    propertyMap.Insert(ImageVisual::Property::FRAME_DELAY, 20);
+    propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true);
+    propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME);
+    propertyMap.Insert(DevelVisual::Property::CORNER_RADIUS, 0.23f);
+    propertyMap.Insert(DevelVisual::Property::CORNER_RADIUS_POLICY, Visual::Transform::Policy::ABSOLUTE);
+
+    VisualFactory factory = VisualFactory::Get();
+    Visual::Base  visual  = factory.CreateVisual(propertyMap);
+
+    Property::Map testMap;
+    visual.CreatePropertyMap(testMap);
+    DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION);
+
+    DummyControl        dummyControl = DummyControl::New(true);
+    Impl::DummyControl& dummyImpl    = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+    dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+    dummyControl.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+    application.GetScene().Add(dummyControl);
+
+    TraceCallStack& textureTrace = gl.GetTextureTrace();
+    textureTrace.Enable(true);
+
+    application.SendNotification();
+    application.Render(20);
+
+    // The first frame is loaded synchronously and load next batch with masking
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+
+    application.SendNotification();
+    application.Render();
+
+    DALI_TEST_EQUALS(Test::GetTimerCount(), 1, TEST_LOCATION);
+    DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 2, TEST_LOCATION);
+
+    dummyControl.Unparent();
+  }
+  tet_infoline("Test that removing the visual from stage deletes all textures");
+  application.SendNotification();
+  application.Render(16);
+  DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliAnimatedImageVisualJumpToAction(void)
 {
   ToolkitTestApplication application;
 int UtcDaliAnimatedImageVisualJumpToAction(void)
 {
   ToolkitTestApplication application;
@@ -737,6 +847,52 @@ int UtcDaliAnimatedImageVisualAnimatedImage01(void)
   END_TEST;
 }
 
   END_TEST;
 }
 
+int UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask01(void)
+{
+  ToolkitTestApplication application;
+  TestGlAbstraction&     gl = application.GetGlAbstraction();
+
+  {
+    Property::Map propertyMap;
+    propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE);
+    propertyMap.Insert(ImageVisual::Property::URL, TEST_GIF_FILE_NAME);
+    propertyMap.Insert(ImageVisual::Property::BATCH_SIZE, 2);
+    propertyMap.Insert(ImageVisual::Property::CACHE_SIZE, 4);
+    propertyMap.Insert(ImageVisual::Property::FRAME_DELAY, 20);
+    propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME);
+
+
+    VisualFactory factory = VisualFactory::Get();
+    Visual::Base  visual  = factory.CreateVisual(propertyMap);
+
+    DummyControl        dummyControl = DummyControl::New(true);
+    Impl::DummyControl& dummyImpl    = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+    dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+    dummyControl.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+    application.GetScene().Add(dummyControl);
+
+    application.SendNotification();
+    application.Render();
+
+    // load two frame(batch size), load mask image, and request two masking
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(5), true, TEST_LOCATION);
+
+    application.SendNotification();
+    application.Render(20);
+
+    DALI_TEST_EQUALS(gl.GetLastGenTextureId(), 2, TEST_LOCATION);
+
+    dummyControl.Unparent();
+  }
+  tet_infoline("Test that removing the visual from stage deletes all textures");
+  application.SendNotification();
+  application.Render(20);
+  DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliAnimatedImageVisualMultiImage01(void)
 {
   ToolkitTestApplication application;
 int UtcDaliAnimatedImageVisualMultiImage01(void)
 {
   ToolkitTestApplication application;
index 390bb20..880a075 100644 (file)
@@ -138,15 +138,17 @@ TextureManager::~TextureManager()
   }
 }
 
   }
 }
 
-TextureSet TextureManager::LoadAnimatedImageTexture(Dali::AnimatedImageLoading      animatedImageLoading,
-                                                    const uint32_t&                 frameIndex,
-                                                    TextureManager::TextureId&      textureId,
-                                                    const Dali::SamplingMode::Type& samplingMode,
-                                                    const Dali::WrapMode::Type&     wrapModeU,
-                                                    const Dali::WrapMode::Type&     wrapModeV,
-                                                    const bool&                     synchronousLoading,
-                                                    const bool&                     useCache,
-                                                    TextureUploadObserver*          textureObserver)
+TextureSet TextureManager::LoadAnimatedImageTexture(
+  Dali::AnimatedImageLoading      animatedImageLoading,
+  const uint32_t&                 frameIndex,
+  TextureManager::TextureId&      textureId,
+  MaskingDataPointer&             maskInfo,
+  const Dali::SamplingMode::Type& samplingMode,
+  const Dali::WrapMode::Type&     wrapModeU,
+  const Dali::WrapMode::Type&     wrapModeV,
+  const bool&                     synchronousLoading,
+  const bool&                     useCache,
+  TextureUploadObserver*          textureObserver)
 {
   TextureSet textureSet;
 
 {
   TextureSet textureSet;
 
@@ -163,6 +165,18 @@ TextureSet TextureManager::LoadAnimatedImageTexture(Dali::AnimatedImageLoading
     }
     else
     {
     }
     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);
+        }
+        else
+        {
+          DALI_LOG_ERROR("TextureManager::LoadAnimatedImageTexture: Synchronous mask image loading is failed\n");
+        }
+      }
       PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
       if(!textureSet)
       {
       PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
       if(!textureSet)
       {
@@ -175,8 +189,20 @@ TextureSet TextureManager::LoadAnimatedImageTexture(Dali::AnimatedImageLoading
   }
   else
   {
   }
   else
   {
-    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, UseAtlas::NO_ATLAS, false, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiply, animatedImageLoading, frameIndex, false, 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;
+    }
+
+    auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+    textureId        = RequestLoadInternal(animatedImageLoading.GetUrl(), alphaMaskId, contentScaleFactor, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, UseAtlas::NO_ATLAS, cropToMask, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiply, animatedImageLoading, frameIndex, false, useCache);
+
     TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
     if(loadState == TextureManager::LoadState::UPLOADED)
     {
     TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
     if(loadState == TextureManager::LoadState::UPLOADED)
     {
index ee1f065..36219cc 100644 (file)
@@ -115,6 +115,7 @@ public:
    * @param[in]  animatedImageLoading  The AnimatedImageLoading that contain the animated image information
    * @param[in]  frameIndex            The frame index to load.
    * @param[out] textureId             The textureId of the frame
    * @param[in]  animatedImageLoading  The AnimatedImageLoading that contain the animated image information
    * @param[in]  frameIndex            The frame index to load.
    * @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
    * @param[in]  samplingMode          The SamplingMode to use
    * @param[in]  wrapModeU             Horizontal Wrap mode
    * @param[in]  wrapModeV             Vertical Wrap mode
@@ -128,6 +129,7 @@ public:
   TextureSet LoadAnimatedImageTexture(Dali::AnimatedImageLoading      animatedImageLoading,
                                       const uint32_t&                 frameIndex,
                                       TextureManager::TextureId&      textureId,
   TextureSet LoadAnimatedImageTexture(Dali::AnimatedImageLoading      animatedImageLoading,
                                       const uint32_t&                 frameIndex,
                                       TextureManager::TextureId&      textureId,
+                                      MaskingDataPointer&             maskInfo,
                                       const Dali::SamplingMode::Type& samplingMode,
                                       const Dali::WrapMode::Type&     wrapModeU,
                                       const Dali::WrapMode::Type&     wrapModeV,
                                       const Dali::SamplingMode::Type& samplingMode,
                                       const Dali::WrapMode::Type&     wrapModeU,
                                       const Dali::WrapMode::Type&     wrapModeV,
index be73cca..b704d34 100644 (file)
@@ -175,7 +175,7 @@ void AnimatedImageVisual::CreateImageCache()
 
   if(mAnimatedImageLoading)
   {
 
   if(mAnimatedImageLoading)
   {
-    mImageCache = new RollingAnimatedImageCache(textureManager, mAnimatedImageLoading, *this, mCacheSize, mBatchSize, IsSynchronousLoadingRequired());
+    mImageCache = new RollingAnimatedImageCache(textureManager, mAnimatedImageLoading, mMaskingData, *this, mCacheSize, mBatchSize, IsSynchronousLoadingRequired());
   }
   else if(mImageUrls)
   {
   }
   else if(mImageUrls)
   {
@@ -186,11 +186,11 @@ void AnimatedImageVisual::CreateImageCache()
     uint16_t cacheSize = std::max(std::min(std::max(batchSize, mCacheSize), numUrls), MINIMUM_CACHESIZE);
     if(cacheSize < numUrls)
     {
     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
     {
     }
     else
     {
-      mImageCache = new FixedImageCache(textureManager, *mImageUrls, *this, batchSize, mFrameDelay);
+      mImageCache = new FixedImageCache(textureManager, *mImageUrls, mMaskingData, *this, batchSize, mFrameDelay);
     }
   }
 
     }
   }
 
@@ -219,6 +219,7 @@ AnimatedImageVisual::AnimatedImageVisual(VisualFactoryCache& factoryCache, Image
   mCurrentLoopIndex(FIRST_LOOP),
   mLoadPolicy(Toolkit::ImageVisual::LoadPolicy::ATTACHED),
   mReleasePolicy(Toolkit::ImageVisual::ReleasePolicy::DETACHED),
   mCurrentLoopIndex(FIRST_LOOP),
   mLoadPolicy(Toolkit::ImageVisual::LoadPolicy::ATTACHED),
   mReleasePolicy(Toolkit::ImageVisual::ReleasePolicy::DETACHED),
+  mMaskingData(),
   mFrameCount(0),
   mImageSize(),
   mActionStatus(DevelAnimatedImageVisual::Action::PLAY),
   mFrameCount(0),
   mImageSize(),
   mActionStatus(DevelAnimatedImageVisual::Action::PLAY),
@@ -246,6 +247,19 @@ void AnimatedImageVisual::GetNaturalSize(Vector2& naturalSize)
 {
   if(mImageSize.GetWidth() == 0 && mImageSize.GetHeight() == 0)
   {
 {
   if(mImageSize.GetWidth() == 0 && mImageSize.GetHeight() == 0)
   {
+    if(mMaskingData && mMaskingData->mAlphaMaskUrl.IsValid() &&
+       mMaskingData->mCropToMask)
+    {
+      ImageDimensions dimensions = Dali::GetClosestImageSize(mMaskingData->mAlphaMaskUrl.GetUrl());
+      if(dimensions != ImageDimensions(0, 0))
+      {
+        mImageSize = dimensions;
+        naturalSize.x = dimensions.GetWidth();
+        naturalSize.y = dimensions.GetHeight();
+        return;
+      }
+    }
+
     if(mImageUrl.IsValid())
     {
       mImageSize = mAnimatedImageLoading.GetImageSize();
     if(mImageUrl.IsValid())
     {
       mImageSize = mAnimatedImageLoading.GetImageSize();
@@ -298,6 +312,13 @@ void AnimatedImageVisual::DoCreatePropertyMap(Property::Map& map) const
 
   map.Insert(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mStopBehavior);
 
 
   map.Insert(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mStopBehavior);
 
+  if(mMaskingData != nullptr)
+  {
+    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);
 }
   map.Insert(Toolkit::ImageVisual::Property::LOAD_POLICY, mLoadPolicy);
   map.Insert(Toolkit::ImageVisual::Property::RELEASE_POLICY, mReleasePolicy);
 }
@@ -413,6 +434,18 @@ void AnimatedImageVisual::DoSetProperties(const Property::Map& propertyMap)
       {
         DoSetProperty(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, keyValue.second);
       }
       {
         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);
       else if(keyValue.first == LOAD_POLICY_NAME)
       {
         DoSetProperty(Toolkit::ImageVisual::Property::LOAD_POLICY, keyValue.second);
@@ -554,6 +587,39 @@ void AnimatedImageVisual::DoSetProperty(Property::Index        index,
       break;
     }
 
       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;
     case Toolkit::ImageVisual::Property::RELEASE_POLICY:
     {
       int releasePolicy = 0;
@@ -851,6 +917,14 @@ TextureSet AnimatedImageVisual::SetLoadingFailed()
   return textureSet;
 }
 
   return textureSet;
 }
 
+void AnimatedImageVisual::AllocateMaskData()
+{
+  if(!mMaskingData)
+  {
+    mMaskingData.reset(new TextureManager::MaskingData());
+  }
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
 } // namespace Internal
 
 } // namespace Toolkit
index 5e70964..4acb736 100644 (file)
@@ -241,6 +241,12 @@ private:
    */
   TextureSet SetLoadingFailed();
 
    */
   TextureSet SetLoadingFailed();
 
+  /**
+   * @brief Allocate mask data.
+   * This is allocated only once.
+   */
+  void AllocateMaskData();
+
   // Undefined
   AnimatedImageVisual(const AnimatedImageVisual& animatedImageVisual);
 
   // Undefined
   AnimatedImageVisual(const AnimatedImageVisual& animatedImageVisual);
 
@@ -268,9 +274,10 @@ private:
   int16_t              mLoopCount;
   int16_t              mCurrentLoopIndex;
 
   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;
   Dali::Toolkit::ImageVisual::LoadPolicy::Type    mLoadPolicy;
   Dali::Toolkit::ImageVisual::ReleasePolicy::Type mReleasePolicy;
+  TextureManager::MaskingDataPointer              mMaskingData;
 
   // Shared variables
   uint32_t        mFrameCount; // Number of frames
 
   // Shared variables
   uint32_t        mFrameCount; // Number of frames
index 192a3c4..8cc69ff 100644 (file)
@@ -35,9 +35,13 @@ constexpr bool ENABLE_ORIENTATION_CORRECTION(true);
 constexpr uint32_t FIRST_FRAME_INDEX = 0u;
 } // namespace
 
 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)
 {
   mImageUrls(urlList),
   mFront(FIRST_FRAME_INDEX)
 {
@@ -122,7 +126,6 @@ void FixedImageCache::LoadBatch()
     bool                               synchronousLoading = false;
     bool                               atlasingStatus     = false;
     bool                               loadingStatus      = false;
     bool                               synchronousLoading = false;
     bool                               atlasingStatus     = false;
     bool                               loadingStatus      = false;
-    TextureManager::MaskingDataPointer maskInfo           = nullptr;
     AtlasUploadObserver*               atlasObserver      = nullptr;
     ImageAtlasManagerPtr               imageAtlasManager  = nullptr;
     Vector4                            textureRect;
     AtlasUploadObserver*               atlasObserver      = nullptr;
     ImageAtlasManagerPtr               imageAtlasManager  = nullptr;
     Vector4                            textureRect;
@@ -130,7 +133,7 @@ void FixedImageCache::LoadBatch()
     auto                               preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
     mTextureManager.LoadTexture(
     auto                               preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
     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);
 
     mRequestingLoad = false;
   }
 
     mRequestingLoad = false;
   }
@@ -157,10 +160,21 @@ void FixedImageCache::ClearCache()
     {
       mTextureManager.Remove(mImageUrls[i].mTextureId, this);
       mImageUrls[i].mTextureId = TextureManager::INVALID_TEXTURE_ID;
     {
       mTextureManager.Remove(mImageUrls[i].mTextureId, this);
       mImageUrls[i].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+
+      if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
+      {
+        // In the CPU alpha masking, each frame increases reference count of masking texture.
+        // We should call TextureManager::Remove to decrease reference count when each frame is removed.
+        mTextureManager.Remove(mMaskingData->mAlphaMaskId, this);
+      }
     }
   }
   mReadyFlags.clear();
   mLoadState = TextureManager::LoadState::NOT_STARTED;
     }
   }
   mReadyFlags.clear();
   mLoadState = TextureManager::LoadState::NOT_STARTED;
+  if(mMaskingData)
+  {
+    mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
+  }
 }
 
 void FixedImageCache::LoadComplete(bool loadSuccess, TextureInformation textureInformation)
 }
 
 void FixedImageCache::LoadComplete(bool loadSuccess, TextureInformation textureInformation)
index 2d446f0..c798a66 100644 (file)
@@ -33,19 +33,21 @@ public:
   /**
    * Constructor.
    * @param[in] textureManager The texture manager
   /**
    * 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.
    */
    *
    * 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;
 
 
   ~FixedImageCache() override;
 
index 27c3ef2..59f0520 100644 (file)
@@ -22,12 +22,14 @@ namespace Toolkit
 {
 namespace Internal
 {
 {
 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),
 : mTextureManager(textureManager),
   mObserver(observer),
+  mMaskingData(maskingData),
   mBatchSize(batchSize),
   mInterval(interval),
   mLoadState(TextureManager::LoadState::NOT_STARTED),
   mBatchSize(batchSize),
   mInterval(interval),
   mLoadState(TextureManager::LoadState::NOT_STARTED),
index 19a8f52..65f39df 100644 (file)
@@ -61,16 +61,18 @@ public:
    * @param[in] textureManager The texture manager
    * @param[in] urlList List of urls to cache
    * @param[in] observer FrameReady observer
    * @param[in] textureManager The texture manager
    * @param[in] urlList List of urls to cache
    * @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] batchSize The size of a batch to load
-   * @param[in] interval Time interval(ms) between each frame 
+   * @param[in] interval Time interval(ms) 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.
    */
    *
    * 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();
 
 
   virtual ~ImageCache();
 
@@ -132,18 +134,21 @@ private:
    */
   void TextureManagerDestroyed() final;
 
    */
   void TextureManagerDestroyed() final;
 
+  void AllocateMaskData();
+
 protected:
 protected:
-  TextureManager&           mTextureManager;
-  FrameReadyObserver&       mObserver;
-  uint32_t                  mBatchSize;
-  uint32_t                  mInterval;
-  TextureManager::LoadState mLoadState;
-  bool                      mRequestingLoad : 1;
-  bool                      mTextureManagerAlive : 1;
+  TextureManager&                     mTextureManager;
+  FrameReadyObserver&                 mObserver;
+  TextureManager::MaskingDataPointer& mMaskingData;
+  uint32_t                            mBatchSize;
+  uint32_t                            mInterval;
+  TextureManager::LoadState           mLoadState;
+  bool                                mRequestingLoad : 1;
+  bool                                mTextureManagerAlive : 1;
 };
 
 };
 
-} //namespace Internal
-} //namespace Toolkit
-} //namespace Dali
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
 
 #endif // DALI_TOOLKIT_INTERNAL_IMAGE_CACHE_H
 
 #endif // DALI_TOOLKIT_INTERNAL_IMAGE_CACHE_H
index 473f276..e5ea68e 100644 (file)
@@ -59,9 +59,14 @@ static constexpr uint32_t SINGLE_IMAGE_COUNT = 1u;
 static constexpr uint32_t FIRST_FRAME_INDEX  = 0u;
 } // namespace
 
 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),
   mAnimatedImageLoading(animatedImageLoading),
   mFrameCount(SINGLE_IMAGE_COUNT),
   mFrameIndex(FIRST_FRAME_INDEX),
@@ -84,10 +89,8 @@ TextureSet RollingAnimatedImageCache::Frame(uint32_t frameIndex)
   bool popExist = false;
   while(!mQueue.IsEmpty() && mQueue.Front().mFrameNumber != 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;
   }
 
   TextureSet textureSet;
@@ -191,6 +194,7 @@ TextureSet RollingAnimatedImageCache::RequestFrameLoading(uint32_t frameIndex, b
   TextureSet                textureSet    = mTextureManager.LoadAnimatedImageTexture(mAnimatedImageLoading,
                                                                    frameIndex,
                                                                    loadTextureId,
   TextureSet                textureSet    = mTextureManager.LoadAnimatedImageTexture(mAnimatedImageLoading,
                                                                    frameIndex,
                                                                    loadTextureId,
+                                                                   mMaskingData,
                                                                    SamplingMode::BOX_THEN_LINEAR,
                                                                    Dali::WrapMode::Type::DEFAULT,
                                                                    Dali::WrapMode::Type::DEFAULT,
                                                                    SamplingMode::BOX_THEN_LINEAR,
                                                                    Dali::WrapMode::Type::DEFAULT,
                                                                    Dali::WrapMode::Type::DEFAULT,
@@ -252,13 +256,27 @@ TextureManager::TextureId RollingAnimatedImageCache::GetCachedTextureId(int inde
   return mImageUrls[mQueue[index].mFrameNumber].mTextureId;
 }
 
   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())
   {
 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();
   mLoadState = TextureManager::LoadState::NOT_STARTED;
   }
   mLoadWaitingQueue.clear();
   mLoadState = TextureManager::LoadState::NOT_STARTED;
index 605fbb9..1b383b5 100644 (file)
@@ -41,22 +41,24 @@ class RollingAnimatedImageCache : public ImageCache, public TextureUploadObserve
 public:
   /**
    * @brief Constructor.
 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.
    */
    * @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
 
   /**
    * @brief Destructor
@@ -149,6 +151,11 @@ private:
    */
   void MakeFrameReady(bool loadSuccess, TextureSet textureSet, uint32_t interval);
 
    */
   void MakeFrameReady(bool loadSuccess, TextureSet textureSet, uint32_t interval);
 
+  /**
+   * @brief Pop front entity of Cache.
+   */
+  void PopFrontCache();
+
 protected:
   /**
    * @copydoc Toolkit::TextureUploadObserver::LoadComplete()
 protected:
   /**
    * @copydoc Toolkit::TextureUploadObserver::LoadComplete()
index 08fe0d0..c0c598a 100644 (file)
@@ -56,9 +56,14 @@ namespace Toolkit
 {
 namespace Internal
 {
 {
 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)
 {
   mImageUrls(urlList),
   mQueue(cacheSize)
 {
@@ -75,9 +80,7 @@ TextureSet RollingImageCache::Frame(uint32_t frameIndex)
   bool popExist = false;
   while(!mQueue.IsEmpty() && mQueue.Front().mUrlIndex != 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;
   }
 
     popExist                                    = true;
   }
 
@@ -156,7 +159,6 @@ void RollingImageCache::LoadBatch(uint32_t frameIndex)
     bool                               synchronousLoading = false;
     bool                               atlasingStatus     = false;
     bool                               loadingStatus      = false;
     bool                               synchronousLoading = false;
     bool                               atlasingStatus     = false;
     bool                               loadingStatus      = false;
-    TextureManager::MaskingDataPointer maskInfo           = nullptr;
     AtlasUploadObserver*               atlasObserver      = nullptr;
     ImageAtlasManagerPtr               imageAtlasManager  = nullptr;
     Vector4                            textureRect;
     AtlasUploadObserver*               atlasObserver      = nullptr;
     ImageAtlasManagerPtr               imageAtlasManager  = nullptr;
     Vector4                            textureRect;
@@ -165,7 +167,7 @@ void RollingImageCache::LoadBatch(uint32_t frameIndex)
 
     TextureManager::TextureId loadTextureId = TextureManager::INVALID_TEXTURE_ID;
     TextureSet                textureSet    = mTextureManager.LoadTexture(
 
     TextureManager::TextureId loadTextureId = TextureManager::INVALID_TEXTURE_ID;
     TextureSet                textureSet    = mTextureManager.LoadTexture(
-      url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, maskInfo, synchronousLoading, loadTextureId, 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, loadTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
     mImageUrls[imageFrame.mUrlIndex].mTextureId = loadTextureId;
 
     mRequestingLoad = false;
     mImageUrls[imageFrame.mUrlIndex].mTextureId = loadTextureId;
 
     mRequestingLoad = false;
@@ -186,13 +188,27 @@ TextureManager::TextureId RollingImageCache::GetCachedTextureId(int index) const
   return mImageUrls[mQueue[index].mUrlIndex].mTextureId;
 }
 
   return mImageUrls[mQueue[index].mUrlIndex].mTextureId;
 }
 
+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())
   {
 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();
   }
   mLoadState = TextureManager::LoadState::NOT_STARTED;
 }
   }
   mLoadState = TextureManager::LoadState::NOT_STARTED;
 }
index 98ba45c..e01f17f 100644 (file)
@@ -38,21 +38,23 @@ public:
   /**
    * Constructor.
    * @param[in] textureManager The texture manager
   /**
    * 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.
    */
    *
    * 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
 
   /**
    * Destructor
@@ -119,11 +121,9 @@ private:
   TextureManager::TextureId GetCachedTextureId(int index) const;
 
   /**
   TextureManager::TextureId GetCachedTextureId(int index) const;
 
   /**
-   * @brief Check if the front frame has become ready - if so, inform observer
-   *
-   * @param[in] wasReady Readiness before call.
+   * @brief Pop front entity of Cache.
    */
    */
-  void CheckFrontFrame(bool wasReady);
+  void PopFrontCache();
 
 protected:
   /**
 
 protected:
   /**