Add CURRENT_FRAME_NUMBER and TOTAL_FRAME_NUMBER properties to the AnimatedImageVisual
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / animated-image / rolling-image-cache.cpp
index 37c7a7d..dee6149 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
@@ -70,18 +70,55 @@ RollingImageCache::RollingImageCache(
 
 RollingImageCache::~RollingImageCache()
 {
-  while( !mQueue.IsEmpty() )
+  if( mTextureManagerAlive )
   {
-    ImageFrame imageFrame = mQueue.PopFront();
-    mTextureManager.Remove( mImageUrls[ imageFrame.mUrlIndex ].mTextureId );
+    while( !mQueue.IsEmpty() )
+    {
+      ImageFrame imageFrame = mQueue.PopFront();
+      mTextureManager.Remove( mImageUrls[ imageFrame.mUrlIndex ].mTextureId, this );
+    }
   }
 }
 
-TextureSet RollingImageCache::FirstFrame()
+TextureSet RollingImageCache::Frame( uint32_t frameIndex )
 {
-  TextureSet textureSet = GetFrontTextureSet();
+  // If a frame of frameIndex is not loaded, clear the queue and remove all loaded textures.
+  if( mImageUrls[ frameIndex ].mTextureId == TextureManager::INVALID_TEXTURE_ID )
+  {
+    mUrlIndex = frameIndex;
+    while( !mQueue.IsEmpty() )
+    {
+      ImageFrame imageFrame = mQueue.PopFront();
+      mTextureManager.Remove( mImageUrls[ imageFrame.mUrlIndex ].mTextureId, this );
+      mImageUrls[ imageFrame.mUrlIndex ].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+    }
+    LoadBatch();
+  }
+  // If the frame is already loaded, remove previous frames of the frame in the queue
+  // and load new frames amount of removed frames.
+  else
+  {
+    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;
+      popExist = true;
+    }
+    if( popExist )
+    {
+      mUrlIndex = ( mQueue.Back().mUrlIndex + 1 ) % mImageUrls.size();
+      LoadBatch();
+    }
+  }
 
-  if( ! textureSet )
+  TextureSet textureSet;
+  if( IsFrontReady() == true )
+  {
+    textureSet = GetFrontTextureSet();
+  }
+  else
   {
     mWaitingForReadyFrame = true;
   }
@@ -89,28 +126,50 @@ TextureSet RollingImageCache::FirstFrame()
   return textureSet;
 }
 
+TextureSet RollingImageCache::FirstFrame()
+{
+  return Frame( 0u );
+}
+
 TextureSet RollingImageCache::NextFrame()
 {
   TextureSet textureSet;
-
-  ImageFrame imageFrame = mQueue.PopFront();
-  mTextureManager.Remove( mImageUrls[ imageFrame.mUrlIndex ].mTextureId );
-  mImageUrls[ imageFrame.mUrlIndex ].mTextureId = TextureManager::INVALID_TEXTURE_ID;
-
-  if( IsFrontReady() == true )
+  if(!mQueue.IsEmpty())
   {
-    textureSet = GetFrontTextureSet();
+    uint32_t frameIndex = mQueue.Front().mUrlIndex;
+    if(IsFrontReady())
+    {
+      frameIndex = (frameIndex + 1) % mImageUrls.size();
+    }
+    textureSet = Frame(frameIndex);
   }
   else
   {
-    mWaitingForReadyFrame = true;
+    DALI_LOG_ERROR("Cache is empty.");
   }
 
-  LoadBatch();
-
   return textureSet;
 }
 
+uint32_t RollingImageCache::GetFrameInterval( uint32_t frameIndex ) const
+{
+  return 0u;
+}
+
+int32_t RollingImageCache::GetCurrentFrameIndex() const
+{
+  if(mQueue.IsEmpty())
+  {
+    return -1;
+  }
+  return mQueue.Front().mUrlIndex;
+}
+
+int32_t RollingImageCache::GetTotalFrameCount() const
+{
+  return mImageUrls.size();
+}
+
 bool RollingImageCache::IsFrontReady() const
 {
   return ( !mQueue.IsEmpty() && mQueue.Front().mReady );
@@ -121,7 +180,7 @@ void RollingImageCache::LoadBatch()
   // Try and load up to mBatchSize images, until the cache is filled.
   // Once the cache is filled, as frames progress, the old frame is
   // cleared, but not erased, and another image is loaded
-  bool frontFrameReady = IsFrontReady();;
+  bool frontFrameReady = IsFrontReady();
 
   for( unsigned int i=0; i< mBatchSize && !mQueue.IsFull(); ++i )
   {
@@ -148,12 +207,13 @@ void RollingImageCache::LoadBatch()
     AtlasUploadObserver* atlasObserver = nullptr;
     ImageAtlasManagerPtr imageAtlasManager = nullptr;
     Vector4 textureRect;
+    Dali::ImageDimensions textureRectSize;
     auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
     mTextureManager.LoadTexture(
       url, ImageDimensions(), FittingMode::SCALE_TO_FILL,
       SamplingMode::BOX_THEN_LINEAR, maskInfo,
-      synchronousLoading, mImageUrls[ imageFrame.mUrlIndex ].mTextureId, textureRect,
+      synchronousLoading, mImageUrls[ imageFrame.mUrlIndex ].mTextureId, textureRect, textureRectSize,
       atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT,
       Dali::WrapMode::Type::DEFAULT, this,
       atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED,
@@ -227,6 +287,17 @@ void RollingImageCache::UploadComplete(
   LOG_CACHE;
 }
 
+void RollingImageCache::LoadComplete(
+  bool loadSuccess,
+  Devel::PixelBuffer pixelBuffer,
+  const VisualUrl& url,
+  bool preMultiplied )
+{
+  // LoadComplete is called if this TextureUploadObserver requested to load
+  // an image that will be returned as a type of PixelBuffer by using a method
+  // TextureManager::LoadPixelBuffer.
+}
+
 } //namespace Internal
 } //namespace Toolkit
 } //namespace Dali