Merge "Refactoring model-impl.cpp" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / animated-image / rolling-animated-image-cache.cpp
index 473f276..b6a9ae8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,24 +27,22 @@ namespace
 #if defined(DEBUG_ENABLED)
 Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ANIMATED_IMAGE");
 
-#define LOG_CACHE                                                                                                                 \
-  {                                                                                                                               \
-    std::ostringstream oss;                                                                                                       \
-    oss << "Size:" << mQueue.Count() << " [ ";                                                                                    \
-    for(std::size_t _i = 0; _i < mQueue.Count(); ++_i)                                                                            \
-    {                                                                                                                             \
-      oss << _i << "={ frm#: " << mQueue[_i].mFrameNumber << " tex: " << mImageUrls[mQueue[_i].mFrameNumber].mTextureId << "}, "; \
-    }                                                                                                                             \
-    oss << " ]" << std::endl;                                                                                                     \
-    DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "%s", oss.str().c_str());                                                    \
+#define LOG_CACHE                                                                                                       \
+  if(gAnimImgLogFilter->IsEnabledFor(Debug::Concise))                                                                   \
+  {                                                                                                                     \
+    std::ostringstream oss;                                                                                             \
+    oss << "Size:" << mQueue.Count() << " [ ";                                                                          \
+    for(std::size_t _i = 0; _i < mQueue.Count(); ++_i)                                                                  \
+    {                                                                                                                   \
+      oss << _i << "={ frm#: " << mQueue[_i].mFrameNumber << " tex: " << mTextureIds[mQueue[_i].mFrameNumber] << "}, "; \
+    }                                                                                                                   \
+    oss << " ]" << std::endl;                                                                                           \
+    DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "%s", oss.str().c_str());                                          \
   }
 
 #else
 #define LOG_CACHE
 #endif
-
-static constexpr bool ENABLE_ORIENTATION_CORRECTION(true);
-
 } // namespace
 
 namespace Dali
@@ -59,17 +57,31 @@ 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,
+                                                     ImageDimensions                     size,
+                                                     Dali::FittingMode::Type             fittingMode,
+                                                     Dali::SamplingMode::Type            samplingMode,
+                                                     AnimatedImageLoading&               animatedImageLoading,
+                                                     TextureManager::MaskingDataPointer& maskingData,
+                                                     ImageCache::FrameReadyObserver&     observer,
+                                                     uint16_t                            cacheSize,
+                                                     uint16_t                            batchSize,
+                                                     const Dali::WrapMode::Type&         wrapModeU,
+                                                     const Dali::WrapMode::Type&         wrapModeV,
+                                                     bool                                isSynchronousLoading,
+                                                     bool                                preMultiplyOnLoad)
+: ImageCache(textureManager, size, fittingMode, samplingMode, maskingData, observer, batchSize, 0u, preMultiplyOnLoad),
+  mImageUrl(animatedImageLoading.GetUrl()),
   mAnimatedImageLoading(animatedImageLoading),
   mFrameCount(SINGLE_IMAGE_COUNT),
   mFrameIndex(FIRST_FRAME_INDEX),
   mCacheSize(cacheSize),
   mQueue(cacheSize),
+  mWrapModeU(wrapModeU),
+  mWrapModeV(wrapModeV),
   mIsSynchronousLoading(isSynchronousLoading)
 {
-  mImageUrls.resize(mFrameCount);
+  mTextureIds.resize(mFrameCount);
   mIntervals.assign(mFrameCount, 0);
 }
 
@@ -84,10 +96,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;
@@ -97,15 +107,18 @@ TextureSet RollingAnimatedImageCache::Frame(uint32_t frameIndex)
   bool synchronouslyLoaded = false;
   if(mIsSynchronousLoading && mQueue.IsEmpty())
   {
-    textureSet          = RequestFrameLoading(frameIndex, frameIndex == FIRST_FRAME_INDEX, true);
-    batchFrameIndex     = (frameIndex + 1) % mFrameCount;
+    auto preMultiplyOnLoading = mPreMultiplyOnLoad ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
+                                                   : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
+    textureSet        = RequestFrameLoading(frameIndex, true, preMultiplyOnLoading);
+    batchFrameIndex   = (frameIndex + 1) % mFrameCount;
     uint32_t interval = 0u;
     if(textureSet)
     {
       synchronouslyLoaded = true;
-      interval = mAnimatedImageLoading.GetFrameInterval(mQueue.Back().mFrameNumber);
+      interval            = mAnimatedImageLoading.GetFrameInterval(mQueue.Back().mFrameNumber);
     }
-    MakeFrameReady(synchronouslyLoaded, textureSet, interval);
+    MakeFrameReady(synchronouslyLoaded, textureSet, interval, preMultiplyOnLoading == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD);
   }
 
   if(popExist || mQueue.IsEmpty() || synchronouslyLoaded)
@@ -177,7 +190,15 @@ bool RollingAnimatedImageCache::IsFrontReady() const
   return (!mQueue.IsEmpty() && mQueue.Front().mReady);
 }
 
-TextureSet RollingAnimatedImageCache::RequestFrameLoading(uint32_t frameIndex, bool useCache, bool synchronousLoading)
+TextureSet RollingAnimatedImageCache::RequestFrameLoading(uint32_t frameIndex)
+{
+  auto preMultiplyOnLoading = mPreMultiplyOnLoad ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
+                                                 : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
+  return RequestFrameLoading(frameIndex, false, preMultiplyOnLoading);
+}
+
+TextureSet RollingAnimatedImageCache::RequestFrameLoading(uint32_t frameIndex, bool synchronousLoading, TextureManager::MultiplyOnLoad& preMultiplyOnLoading)
 {
   ImageFrame imageFrame;
   imageFrame.mFrameNumber = frameIndex;
@@ -188,17 +209,25 @@ TextureSet RollingAnimatedImageCache::RequestFrameLoading(uint32_t frameIndex, b
   mLoadState = TextureManager::LoadState::LOADING;
 
   TextureManager::TextureId loadTextureId = TextureManager::INVALID_TEXTURE_ID;
-  TextureSet                textureSet    = mTextureManager.LoadAnimatedImageTexture(mAnimatedImageLoading,
+  TextureSet                textureSet    = mTextureManager.LoadAnimatedImageTexture(mImageUrl,
+                                                                   mAnimatedImageLoading,
                                                                    frameIndex,
                                                                    loadTextureId,
-                                                                   SamplingMode::BOX_THEN_LINEAR,
-                                                                   Dali::WrapMode::Type::DEFAULT,
-                                                                   Dali::WrapMode::Type::DEFAULT,
+                                                                   mMaskingData,
+                                                                   mDesiredSize,
+                                                                   mFittingMode,
+                                                                   mSamplingMode,
                                                                    synchronousLoading,
-                                                                   useCache,
-                                                                   this);
+                                                                   this,
+                                                                   preMultiplyOnLoading);
+  if(textureSet)
+  {
+    Sampler sampler = Sampler::New();
+    sampler.SetWrapMode(mWrapModeU, mWrapModeV);
+    textureSet.SetSampler(0u, sampler);
+  }
 
-  mImageUrls[frameIndex].mTextureId = loadTextureId;
+  mTextureIds[frameIndex] = loadTextureId;
 
   return textureSet;
 }
@@ -213,7 +242,7 @@ void RollingAnimatedImageCache::LoadBatch(uint32_t frameIndex)
   {
     if(mLoadState != TextureManager::LoadState::LOADING)
     {
-      RequestFrameLoading(frameIndex, frameIndex == FIRST_FRAME_INDEX, false);
+      RequestFrameLoading(frameIndex);
     }
     else
     {
@@ -243,33 +272,54 @@ TextureSet RollingAnimatedImageCache::GetFrontTextureSet() const
 {
   DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "RollingAnimatedImageCache::GetFrontTextureSet() FrameNumber:%d\n", mQueue[0].mFrameNumber);
 
-  TextureManager::TextureId textureId = GetCachedTextureId(0);
-  return mTextureManager.GetTextureSet(textureId);
+  TextureManager::TextureId textureId  = GetCachedTextureId(0);
+  TextureSet                textureSet = mTextureManager.GetTextureSet(textureId);
+  if(textureSet)
+  {
+    Sampler sampler = Sampler::New();
+    sampler.SetWrapMode(mWrapModeU, mWrapModeV);
+    textureSet.SetSampler(0u, sampler);
+  }
+  return textureSet;
 }
 
 TextureManager::TextureId RollingAnimatedImageCache::GetCachedTextureId(int index) const
 {
-  return mImageUrls[mQueue[index].mFrameNumber].mTextureId;
+  return mTextureIds[mQueue[index].mFrameNumber];
+}
+
+void RollingAnimatedImageCache::PopFrontCache()
+{
+  ImageFrame imageFrame = mQueue.PopFront();
+  mTextureManager.Remove(mTextureIds[imageFrame.mFrameNumber], this);
+  mTextureIds[imageFrame.mFrameNumber] = TextureManager::INVALID_TEXTURE_ID;
+
+  if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
+  {
+    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();
   mLoadState = TextureManager::LoadState::NOT_STARTED;
 }
 
-void RollingAnimatedImageCache::MakeFrameReady(bool loadSuccess, TextureSet textureSet, uint32_t interval)
+void RollingAnimatedImageCache::MakeFrameReady(bool loadSuccess, TextureSet textureSet, uint32_t interval, bool preMultiplied)
 {
   if(!loadSuccess)
   {
     mLoadState = TextureManager::LoadState::LOAD_FAILED;
-    mObserver.FrameReady(TextureSet(), 0);
+    // preMultiplied should be false because broken image don't premultiply alpha on load
+    mObserver.FrameReady(TextureSet(), 0, false);
   }
   else
   {
@@ -279,7 +329,7 @@ void RollingAnimatedImageCache::MakeFrameReady(bool loadSuccess, TextureSet text
     if(mFrameCount != mAnimatedImageLoading.GetImageCount())
     {
       mFrameCount = mAnimatedImageLoading.GetImageCount();
-      mImageUrls.resize(mFrameCount);
+      mTextureIds.resize(mFrameCount);
       mIntervals.assign(mFrameCount, 0u);
     }
 
@@ -292,7 +342,7 @@ void RollingAnimatedImageCache::MakeFrameReady(bool loadSuccess, TextureSet text
     // If it is, notify frame ready to observer.
     if(frontFrameReady == false && IsFrontReady())
     {
-      mObserver.FrameReady(textureSet, interval);
+      mObserver.FrameReady(textureSet, interval, preMultiplied);
     }
   }
 }
@@ -302,7 +352,14 @@ void RollingAnimatedImageCache::LoadComplete(bool loadSuccess, TextureInformatio
   DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "AnimatedImageVisual::LoadComplete(textureId:%d) start\n", textureInformation.textureId);
   LOG_CACHE;
 
-  MakeFrameReady(loadSuccess, mTextureManager.GetTextureSet(textureInformation.textureId), textureInformation.interval);
+  if(textureInformation.textureSet)
+  {
+    Sampler sampler = Sampler::New();
+    sampler.SetWrapMode(mWrapModeU, mWrapModeV);
+    textureInformation.textureSet.SetSampler(0u, sampler);
+  }
+
+  MakeFrameReady(loadSuccess, textureInformation.textureSet, textureInformation.interval, textureInformation.preMultiplied);
 
   if(loadSuccess)
   {
@@ -313,7 +370,7 @@ void RollingAnimatedImageCache::LoadComplete(bool loadSuccess, TextureInformatio
     {
       uint32_t loadingIndex = mLoadWaitingQueue.front();
       mLoadWaitingQueue.erase(mLoadWaitingQueue.begin());
-      RequestFrameLoading(loadingIndex, loadingIndex == FIRST_FRAME_INDEX, false);
+      RequestFrameLoading(loadingIndex);
     }
     else if(mQueue.Count() == 1u && textureInformation.frameCount > SINGLE_IMAGE_COUNT)
     {