Merge "DALi Version 2.1.22" into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 13 May 2022 11:06:29 +0000 (11:06 +0000)
committerGerrit Code Review <gerrit@review>
Fri, 13 May 2022 11:06:29 +0000 (11:06 +0000)
automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp
dali-toolkit/internal/texture-manager/texture-cache-manager.cpp
dali-toolkit/internal/texture-manager/texture-cache-manager.h
dali-toolkit/internal/texture-manager/texture-manager-impl.cpp
dali-toolkit/internal/texture-manager/texture-manager-impl.h
dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h

index 55745fb..dce317b 100644 (file)
@@ -525,7 +525,6 @@ int UtcDaliAnimatedImageVisualSynchronousLoading(void)
   END_TEST;
 }
 
-
 int UtcDaliAnimatedImageVisualSynchronousLoadingWithAlphaMask(void)
 {
   ToolkitTestApplication application;
@@ -789,6 +788,7 @@ int UtcDaliAnimatedImageVisualAnimatedImage01(void)
   ToolkitTestApplication application;
   TestGlAbstraction&     gl = application.GetGlAbstraction();
 
+  tet_infoline("Set cache size same as GIF frame, and try to load same image at another ImageView");
   {
     Property::Map propertyMap;
     propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE);
@@ -815,6 +815,7 @@ int UtcDaliAnimatedImageVisualAnimatedImage01(void)
 
     DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
+    // Batch 2 frames. Now frame 0, 1 cached.
     application.SendNotification();
     application.Render(20);
 
@@ -832,12 +833,54 @@ int UtcDaliAnimatedImageVisualAnimatedImage01(void)
 
     DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
+    // 0 frame removed. and after, batch 2 frames. Now frame 1, 2, 3 cached.
     application.SendNotification();
     application.Render(20);
 
     DALI_TEST_EQUALS(gl.GetLastGenTextureId(), 4, TEST_LOCATION);
 
+    Visual::Base        visual2       = factory.CreateVisual(propertyMap);
+    DummyControl        dummyControl2 = DummyControl::New(true);
+    Impl::DummyControl& dummyImpl2    = static_cast<Impl::DummyControl&>(dummyControl2.GetImplementation());
+    dummyImpl2.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual2);
+    application.GetScene().Add(dummyControl2);
+
+    tet_infoline("Add new view with same url");
+
+    application.SendNotification();
+    application.Render();
+
+    // Note that we only re-load 0 frame.
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+    tet_infoline("Test that we don't try to re-load new image cause it cached");
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, 1), false, TEST_LOCATION);
+
+    // Batch 2 frames. Now visual frame 1, 2, 3 cached and visual2 frame 0, 1 cached.
+    application.SendNotification();
+    application.Render(20);
+
+    DALI_TEST_EQUALS(gl.GetLastGenTextureId(), 5, TEST_LOCATION);
+
+    textureTrace.Reset();
+
+    tet_infoline("Load some many frames");
+
+    const int repeatCount = 10;
+    for(int repeat = 0; repeat < repeatCount; ++repeat)
+    {
+      Test::EmitGlobalTimerSignal();
+      application.SendNotification();
+      application.Render(2000);
+    }
+
+    DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); // A new texture should NOT be generated.
+    DALI_TEST_EQUALS(gl.GetLastGenTextureId(), 5, TEST_LOCATION);
+
+    textureTrace.Reset();
+
     dummyControl.Unparent();
+    dummyControl2.Unparent();
   }
   tet_infoline("Test that removing the visual from stage deletes all textures");
   application.SendNotification();
@@ -861,7 +904,6 @@ int UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask01(void)
     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);
 
index 9a40691..ccab3e0 100644 (file)
@@ -2309,49 +2309,6 @@ int UtcDaliKeyboardFocusManagerWithHide(void)
   END_TEST;
 }
 
-int UtcDaliKeyboardFocusManagerWithVisible(void)
-{
-  ToolkitTestApplication application;
-
-  tet_infoline(" UtcDaliKeyboardFocusManagerWithVisible");
-
-  KeyboardFocusManager manager = KeyboardFocusManager::Get();
-  DALI_TEST_CHECK(manager);
-
-  // Create the first actor and add it to the stage
-  Actor first = Actor::New();
-  first.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
-  application.GetScene().Add(first);
-
-  // Create the second actor and add it to the first actor.
-  Actor second = Actor::New();
-  second.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true);
-  first.Add(second);
-
-  // Check that no actor is being focused yet.
-  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == Actor());
-
-  // Check that the focus is set on the first actor
-  DALI_TEST_CHECK(manager.SetCurrentFocusActor(first) == true);
-  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
-
-  // Set visible false.
-  first.SetProperty(Actor::Property::VISIBLE, false);
-
-  // Check that it will fail to set focus on the second actor as it's not focusable
-  DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == false);
-  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
-
-  // Set visible true.
-  first.SetProperty(Actor::Property::VISIBLE, true);
-
-  // Check that the focus is set on the second actor
-  DALI_TEST_CHECK(manager.SetCurrentFocusActor(second) == true);
-  DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
-
-  END_TEST;
-}
-
 int UtcDaliKeyboardFocusManagerFocusFinderRootActor(void)
 {
   ToolkitTestApplication application;
@@ -2480,4 +2437,4 @@ int UtcDaliKeyboardFocusManagerFocusFinderRootActor(void)
   Dali::Toolkit::DevelKeyboardFocusManager::ResetFocusFinderRootActor(manager);
 
   END_TEST;
-}
\ No newline at end of file
+}
index b77b2b8..c65abbb 100644 (file)
@@ -213,13 +213,13 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor(Actor actor)
      actor.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE) &&
      actor.GetProperty<bool>(Actor::Property::VISIBLE))
   {
-    // If the parent's KEYBOARD_FOCUSABLE_CHILDREN is false or VISIBLE is false, it cannot have focus.
+    // If the parent's KEYBOARD_FOCUSABLE_CHILDREN is false, it cannot have focus.
     Actor parent = actor.GetParent();
     while(parent)
     {
-      if(!parent.GetProperty<bool>(DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN) || !parent.GetProperty<bool>(Actor::Property::VISIBLE))
+      if(!parent.GetProperty<bool>(DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN))
       {
-        DALI_LOG_INFO(gLogFilter, Debug::General, "[%s:%d] Parent Actor has KEYBOARD_FOCUSABLE_CHILDREN false or VISIBLE false,\n", __FUNCTION__, __LINE__);
+        DALI_LOG_INFO(gLogFilter, Debug::General, "[%s:%d] Parent Actor has KEYBOARD_FOCUSABLE_CHILDREN false\n", __FUNCTION__, __LINE__);
         return false;
       }
       parent = parent.GetParent();
@@ -420,11 +420,11 @@ bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction
   bool succeed = false;
 
   // Go through the actor's hierarchy until we find a layout control that knows how to move the focus
-  Toolkit::Control parentLayoutControl = GetParentLayoutControl(currentFocusActor);
-  while(parentLayoutControl && !succeed)
+  Toolkit::Control layoutControl = IsLayoutControl(currentFocusActor) ? Toolkit::Control::DownCast(currentFocusActor) : GetParentLayoutControl(currentFocusActor);
+  while(layoutControl && !succeed)
   {
-    succeed             = DoMoveFocusWithinLayoutControl(parentLayoutControl, currentFocusActor, direction);
-    parentLayoutControl = GetParentLayoutControl(parentLayoutControl);
+    succeed       = DoMoveFocusWithinLayoutControl(layoutControl, currentFocusActor, direction);
+    layoutControl = GetParentLayoutControl(layoutControl);
   }
 
   if(!succeed)
@@ -556,9 +556,9 @@ bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction
         Toolkit::Control layoutControl = Toolkit::Control::DownCast(nextFocusableActor);
         succeed                        = DoMoveFocusWithinLayoutControl(layoutControl, currentFocusActor, direction);
       }
-      else
+      if(!succeed)
       {
-        // Otherwise, just set focus to the next focusable actor
+        // Just set focus to the next focusable actor
         succeed = SetCurrentFocusActor(nextFocusableActor);
       }
     }
@@ -595,7 +595,7 @@ bool KeyboardFocusManager::DoMoveFocusWithinLayoutControl(Toolkit::Control contr
       if(committedFocusActor && committedFocusActor.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE) && committedFocusActor.GetProperty<bool>(DevelActor::Property::USER_INTERACTION_ENABLED))
       {
         // Whether the commited focusable actor is a layout control
-        if(IsLayoutControl(committedFocusActor))
+        if(IsLayoutControl(committedFocusActor) && committedFocusActor != control)
         {
           // If so, move the focus inside it.
           Toolkit::Control layoutControl = Toolkit::Control::DownCast(committedFocusActor);
index a561161..01e43a4 100644 (file)
@@ -481,7 +481,8 @@ TextureCacheManager::TextureHash TextureCacheManager::GenerateHash(
   const Dali::SamplingMode::Type&       samplingMode,
   const TextureCacheManager::UseAtlas&  useAtlas,
   const TextureCacheManager::TextureId& maskTextureId,
-  const bool&                           cropToMask)
+  const bool&                           cropToMask,
+  const std::uint32_t&                  frameIndex)
 {
   std::vector<std::uint8_t> hashTarget(url.GetUrl().begin(), url.GetUrl().end());
   const size_t              urlLength = hashTarget.size();
@@ -543,6 +544,22 @@ TextureCacheManager::TextureHash TextureCacheManager::GenerateHash(
     *hashTargetPtr++ = (cropToMask ? 'C' : 'M');
   }
 
+  // Append the frameIndex. We don't do additional job when frameIndex = 0u due to the non-animated image case.
+  if(frameIndex > 0u)
+  {
+    auto textureIdIndex = hashTarget.size();
+    hashTarget.resize(hashTarget.size() + sizeof(std::uint32_t));
+    std::uint8_t* hashTargetPtr = reinterpret_cast<std::uint8_t*>(&(hashTarget[textureIdIndex]));
+
+    // Append the frame index to the end of the URL byte by byte:
+    std::uint32_t saltedFrameIndex = frameIndex;
+    for(size_t byteIter = 0; byteIter < sizeof(std::uint8_t); ++byteIter)
+    {
+      *hashTargetPtr++ = saltedFrameIndex & 0xff;
+      saltedFrameIndex >>= 8u;
+    }
+  }
+
   return Dali::CalculateHash(hashTarget);
 }
 
@@ -556,7 +573,8 @@ TextureCacheManager::TextureCacheIndex TextureCacheManager::FindCachedTexture(
   const TextureCacheManager::TextureId&      maskTextureId,
   const bool&                                cropToMask,
   const TextureCacheManager::MultiplyOnLoad& preMultiplyOnLoad,
-  const bool&                                isAnimatedImage)
+  const bool&                                isAnimatedImage,
+  const std::uint32_t&                       frameIndex)
 {
   // Iterate through our hashes to find a match.
   const auto& hashIterator = mTextureHashContainer.find(hash);
@@ -576,6 +594,7 @@ TextureCacheManager::TextureCacheIndex TextureCacheManager::FindCachedTexture(
            (cropToMask == textureInfo.cropToMask) &&
            (size == textureInfo.desiredSize) &&
            (isAnimatedImage == textureInfo.isAnimatedImageFormat) &&
+           (frameIndex == textureInfo.frameIndex) &&
            ((size.GetWidth() == 0 && size.GetHeight() == 0) ||
             (fittingMode == textureInfo.fittingMode &&
              samplingMode == textureInfo.samplingMode)))
index dbd3e62..ac70426 100644 (file)
@@ -208,6 +208,7 @@ public:
    * @param[in] useAtlas         True if atlased
    * @param[in] maskTextureId    The masking texture id (or INVALID_TEXTURE_ID)
    * @param[in] cropToMask       True if crop to mask
+   * @param[in] frameIndex       The frame index to use
    * @return                     A hash of the provided data for caching.
    */
   TextureCacheManager::TextureHash GenerateHash(
@@ -217,7 +218,8 @@ public:
     const Dali::SamplingMode::Type&       samplingMode,
     const TextureCacheManager::UseAtlas&  useAtlas,
     const TextureCacheManager::TextureId& maskTextureId,
-    const bool&                           cropToMask);
+    const bool&                           cropToMask,
+    const std::uint32_t&                  frameIndex);
 
   /**
    * @brief Looks up a cached texture by its hash.
@@ -229,9 +231,10 @@ public:
    * @param[in] samplingMode      The SamplingMode to use
    * @param[in] useAtlas          True if atlased
    * @param[in] maskTextureId     Optional texture ID to use to mask this image
+   * @param[in] cropToMask        True if crop to mask
    * @param[in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha.
    * @param[in] isAnimatedImage   True if the texture is from animated image.
-   * @param[in] cropToMask        True if crop to mask
+   * @param[in] frameIndex        The frame index to use
    * @return                      A TextureCacheIndex of a cached Texture if found. Or INVALID_CACHE_INDEX if not found.
    */
   TextureCacheManager::TextureCacheIndex FindCachedTexture(
@@ -244,7 +247,8 @@ public:
     const TextureCacheManager::TextureId&      maskTextureId,
     const bool&                                cropToMask,
     const TextureCacheManager::MultiplyOnLoad& preMultiplyOnLoad,
-    const bool&                                isAnimatedImage);
+    const bool&                                isAnimatedImage,
+    const std::uint32_t&                       frameIndex);
 
   /**
    * @brief Append a Texture to the TextureCacheManager.
index 880a075..6ace549 100644 (file)
@@ -147,7 +147,6 @@ TextureSet TextureManager::LoadAnimatedImageTexture(
   const Dali::WrapMode::Type&     wrapModeU,
   const Dali::WrapMode::Type&     wrapModeV,
   const bool&                     synchronousLoading,
-  const bool&                     useCache,
   TextureUploadObserver*          textureObserver)
 {
   TextureSet textureSet;
@@ -201,7 +200,7 @@ TextureSet TextureManager::LoadAnimatedImageTexture(
     }
 
     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);
+    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);
 
     TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
     if(loadState == TextureManager::LoadState::UPLOADED)
@@ -256,7 +255,7 @@ Devel::PixelBuffer TextureManager::LoadPixelBuffer(
   }
   else
   {
-    RequestLoadInternal(url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, UseAtlas::NO_ATLAS, false, StorageType::RETURN_PIXEL_BUFFER, textureObserver, orientationCorrection, TextureManager::ReloadPolicy::FORCED, preMultiplyOnLoad, Dali::AnimatedImageLoading(), 0u, false, false);
+    RequestLoadInternal(url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, UseAtlas::NO_ATLAS, false, StorageType::RETURN_PIXEL_BUFFER, textureObserver, orientationCorrection, TextureManager::ReloadPolicy::FORCED, preMultiplyOnLoad, Dali::AnimatedImageLoading(), 0u, false);
   }
 
   return pixelBuffer;
@@ -442,7 +441,7 @@ TextureManager::TextureId TextureManager::RequestLoad(
   TextureManager::MultiplyOnLoad&     preMultiplyOnLoad,
   const bool&                         synchronousLoading)
 {
-  return RequestLoadInternal(url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, useAtlas, false, StorageType::UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy, preMultiplyOnLoad, Dali::AnimatedImageLoading(), 0u, synchronousLoading, true);
+  return RequestLoadInternal(url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, useAtlas, false, StorageType::UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy, preMultiplyOnLoad, Dali::AnimatedImageLoading(), 0u, synchronousLoading);
 }
 
 TextureManager::TextureId TextureManager::RequestLoad(
@@ -460,7 +459,7 @@ TextureManager::TextureId TextureManager::RequestLoad(
   TextureManager::MultiplyOnLoad&     preMultiplyOnLoad,
   const bool&                         synchronousLoading)
 {
-  return RequestLoadInternal(url, maskTextureId, contentScale, desiredSize, fittingMode, samplingMode, useAtlas, cropToMask, StorageType::UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy, preMultiplyOnLoad, Dali::AnimatedImageLoading(), 0u, synchronousLoading, true);
+  return RequestLoadInternal(url, maskTextureId, contentScale, desiredSize, fittingMode, samplingMode, useAtlas, cropToMask, StorageType::UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy, preMultiplyOnLoad, Dali::AnimatedImageLoading(), 0u, synchronousLoading);
 }
 
 TextureManager::TextureId TextureManager::RequestMaskLoad(
@@ -469,7 +468,7 @@ TextureManager::TextureId TextureManager::RequestMaskLoad(
 {
   // Use the normal load procedure to get the alpha mask.
   auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
-  return RequestLoadInternal(maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, UseAtlas::NO_ATLAS, false, StorageType::KEEP_PIXEL_BUFFER, NULL, true, TextureManager::ReloadPolicy::CACHED, preMultiply, Dali::AnimatedImageLoading(), 0u, synchronousLoading, true);
+  return RequestLoadInternal(maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, UseAtlas::NO_ATLAS, false, StorageType::KEEP_PIXEL_BUFFER, NULL, true, TextureManager::ReloadPolicy::CACHED, preMultiply, Dali::AnimatedImageLoading(), 0u, synchronousLoading);
 }
 
 TextureManager::TextureId TextureManager::RequestLoadInternal(
@@ -488,17 +487,16 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
   TextureManager::MultiplyOnLoad&     preMultiplyOnLoad,
   Dali::AnimatedImageLoading          animatedImageLoading,
   const std::uint32_t&                frameIndex,
-  const bool&                         synchronousLoading,
-  const bool&                         useCache)
+  const bool&                         synchronousLoading)
 {
   TextureHash       textureHash = INITIAL_HASH_NUMBER;
   TextureCacheIndex cacheIndex  = INVALID_CACHE_INDEX;
-  if(storageType != StorageType::RETURN_PIXEL_BUFFER && useCache)
+  if(storageType != StorageType::RETURN_PIXEL_BUFFER)
   {
-    textureHash = mTextureCacheManager.GenerateHash(url, desiredSize, fittingMode, samplingMode, useAtlas, maskTextureId, cropToMask);
+    textureHash = mTextureCacheManager.GenerateHash(url, desiredSize, fittingMode, samplingMode, useAtlas, maskTextureId, cropToMask, frameIndex);
 
     // Look up the texture by hash. Note: The extra parameters are used in case of a hash collision.
-    cacheIndex = mTextureCacheManager.FindCachedTexture(textureHash, url, desiredSize, fittingMode, samplingMode, useAtlas, maskTextureId, cropToMask, preMultiplyOnLoad, (animatedImageLoading) ? true : false);
+    cacheIndex = mTextureCacheManager.FindCachedTexture(textureHash, url, desiredSize, fittingMode, samplingMode, useAtlas, maskTextureId, cropToMask, preMultiplyOnLoad, (animatedImageLoading) ? true : false, frameIndex);
   }
 
   TextureManager::TextureId textureId = INVALID_TEXTURE_ID;
@@ -516,7 +514,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
     // Update preMultiplyOnLoad value. It should be changed according to preMultiplied value of the cached info.
     preMultiplyOnLoad = mTextureCacheManager[cacheIndex].preMultiplied ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
-    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d premultiplied=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, mTextureCacheManager[cacheIndex].preMultiplied ? 1 : 0);
+    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d, frameindex=%d, premultiplied=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, frameIndex, mTextureCacheManager[cacheIndex].preMultiplied ? 1 : 0);
   }
 
   if(textureId == INVALID_TEXTURE_ID) // There was no caching, or caching not required
@@ -528,7 +526,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
     // Cache new texutre, and get cacheIndex.
     cacheIndex = mTextureCacheManager.AppendCache(TextureInfo(textureId, maskTextureId, url, desiredSize, contentScale, fittingMode, samplingMode, false, cropToMask, useAtlas, textureHash, orientationCorrection, preMultiply, animatedImageLoading, frameIndex));
 
-    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId);
+    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d, frameindex=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, frameIndex);
   }
 
   // The below code path is common whether we are using the cache or not.
@@ -1066,9 +1064,12 @@ void TextureManager::NotifyObservers(TextureManager::TextureInfo& textureInfo, c
 
   mQueueLoadFlag = true;
 
+  // Reverse observer list that we can pop_back the observer.
+  std::reverse(info->observerList.Begin(), info->observerList.End());
+
   while(info->observerList.Count())
   {
-    TextureUploadObserver* observer = info->observerList[0];
+    TextureUploadObserver* observer = *(info->observerList.End() - 1u);
 
     // During LoadComplete() a Control ResourceReady() signal is emitted.
     // During that signal the app may add remove /add Textures (e.g. via
@@ -1084,7 +1085,7 @@ void TextureManager::NotifyObservers(TextureManager::TextureInfo& textureInfo, c
     // Disconnect and remove the observer first.
     observer->DestructionSignal().Disconnect(this, &TextureManager::ObserverDestroyed);
 
-    info->observerList.Erase(info->observerList.Begin());
+    info->observerList.Erase(info->observerList.End() - 1u);
 
     EmitLoadComplete(observer, *info, success);
 
index 36219cc..5800e54 100644 (file)
@@ -120,7 +120,6 @@ public:
    * @param[in]  wrapModeU             Horizontal Wrap mode
    * @param[in]  wrapModeV             Vertical Wrap mode
    * @param[in]  synchronousLoading    true if the frame should be loaded synchronously
-   * @param[in]  useCache              true if this frame loading uses cache.
    * @param[in]  textureObserver       The client object should inherit from this and provide the "LoadCompleted" virtual.
    *                                   This is called when an image load completes (or fails).
    *
@@ -134,7 +133,6 @@ public:
                                       const Dali::WrapMode::Type&     wrapModeU,
                                       const Dali::WrapMode::Type&     wrapModeV,
                                       const bool&                     synchronousLoading,
-                                      const bool&                     useCache,
                                       TextureUploadObserver*          textureObserver);
 
   /**
@@ -456,7 +454,6 @@ private:
    * @param[in] frameIndex            The frame index of a frame to be loaded frame
    * @param[in] synchronousLoading    True if the frame should be loaded synchronously. If you skip this parameter,
    *                                  default is false.
-   * @param[in] useCache              True if the texture will be cached.
    * @return                          A TextureId to use as a handle to reference this Texture
    */
   TextureId RequestLoadInternal(
@@ -475,8 +472,7 @@ private:
     TextureManager::MultiplyOnLoad&     preMultiplyOnLoad,
     Dali::AnimatedImageLoading          animatedImageLoading,
     const std::uint32_t&                frameIndex,
-    const bool&                         synchronousLoading,
-    const bool&                         useCache);
+    const bool&                         synchronousLoading);
 
   /**
    * @brief Load a new image synchronously.
index e5ea68e..33df7b8 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.
@@ -100,13 +100,13 @@ 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;
+    textureSet        = RequestFrameLoading(frameIndex, true);
+    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);
   }
@@ -180,7 +180,7 @@ 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, bool synchronousLoading)
 {
   ImageFrame imageFrame;
   imageFrame.mFrameNumber = frameIndex;
@@ -199,7 +199,6 @@ TextureSet RollingAnimatedImageCache::RequestFrameLoading(uint32_t frameIndex, b
                                                                    Dali::WrapMode::Type::DEFAULT,
                                                                    Dali::WrapMode::Type::DEFAULT,
                                                                    synchronousLoading,
-                                                                   useCache,
                                                                    this);
 
   mImageUrls[frameIndex].mTextureId = loadTextureId;
@@ -217,7 +216,7 @@ void RollingAnimatedImageCache::LoadBatch(uint32_t frameIndex)
   {
     if(mLoadState != TextureManager::LoadState::LOADING)
     {
-      RequestFrameLoading(frameIndex, frameIndex == FIRST_FRAME_INDEX, false);
+      RequestFrameLoading(frameIndex, false);
     }
     else
     {
@@ -331,7 +330,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, false);
     }
     else if(mQueue.Count() == 1u && textureInformation.frameCount > SINGLE_IMAGE_COUNT)
     {
index 1b383b5..1a772ce 100644 (file)
@@ -107,12 +107,11 @@ private:
    * @brief Request to Load a frame
    *
    * @param[in] frameIndex          index of frame to be loaded.
-   * @param[in] useCache            true if this frame loading uses cache.
    * @param[in] synchronousLoading  true if the frame should be loaded synchronously
    *
    * @return the texture set currently loaded.
    */
-  TextureSet RequestFrameLoading(uint32_t frameIndex, bool useCache, bool synchronousLoading);
+  TextureSet RequestFrameLoading(uint32_t frameIndex, bool synchronousLoading);
 
   /**
    * @brief Load the next batch of images
@@ -163,7 +162,6 @@ protected:
   void LoadComplete(bool loadSuccess, TextureInformation textureInformation) override;
 
 private:
-
   /**
    * Secondary class to hold readiness and index into url
    */