[Tizen] Add NextFrame method at ImageCache 13/248413/7 accepted/tizen/6.0/unified/20201202.212221 submit/tizen_6.0/20201201.081346
authorSeungho Baek <sbsh.baek@samsung.com>
Mon, 23 Nov 2020 04:01:58 +0000 (13:01 +0900)
committerseungho <sbsh.baek@samsung.com>
Tue, 1 Dec 2020 03:23:37 +0000 (12:23 +0900)
 - Load next frame without frame index

Change-Id: I7725ba0b9e931a6748b4e8019c65d5d3572aad6b
Signed-off-by: Seungho Baek <sbsh.baek@samsung.com>
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.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 456b89e..a6332c2 100755 (executable)
@@ -174,7 +174,7 @@ AnimatedImageVisual::AnimatedImageVisual( VisualFactoryCache& factoryCache, Imag
   mPixelArea( FULL_TEXTURE_RECT ),
   mImageUrl(),
   mAnimatedImageLoading(),
-  mCurrentFrameIndex( 0 ),
+  mFrameIndexForJumpTo( 0 ),
   mImageUrls( NULL ),
   mImageCache( NULL ),
   mCacheSize( 2 ),
@@ -302,7 +302,7 @@ void AnimatedImageVisual::OnDoAction( const Dali::Property::Index actionId, cons
         else
         {
           mIsJumpTo = true;
-          mCurrentFrameIndex = frameNumber;
+          mFrameIndexForJumpTo = frameNumber;
           if( IsOnScene() )
           {
             DisplayNextFrame();
@@ -544,8 +544,6 @@ void AnimatedImageVisual::CreateRenderer()
   {
     mImpl->mRenderer.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, mPixelArea );
   }
-
-  mCurrentFrameIndex = 0;
 }
 
 void AnimatedImageVisual::LoadFirstBatch()
@@ -618,8 +616,6 @@ void AnimatedImageVisual::StartFirstFrame( TextureSet& textureSet )
     mPlacementActor.Reset();
   }
 
-  mCurrentFrameIndex = 0;
-
   if( mFrameCount > 1 )
   {
     int frameDelay = mFrameDelay; // from URL array
@@ -642,15 +638,11 @@ TextureSet AnimatedImageVisual::PrepareTextureSet()
   {
     textureSet = mImageCache->FirstFrame();
   }
+
   if( textureSet )
   {
     SetImageSize( textureSet );
   }
-  else
-  {
-    DALI_LOG_INFO( gAnimImgLogFilter, Debug::Concise, "ResourceReady(ResourceStatus::FAILED)\n" );
-    ResourceReady( Toolkit::Visual::ResourceStatus::FAILED );
-  }
 
   return textureSet;
 }
@@ -670,26 +662,38 @@ void AnimatedImageVisual::SetImageSize( TextureSet& textureSet )
 
 void AnimatedImageVisual::FrameReady( TextureSet textureSet )
 {
-  SetImageSize( textureSet );
-
-  if( mStartFirstFrame )
+  if(textureSet)
   {
-    StartFirstFrame( textureSet );
+    SetImageSize(textureSet);
+
+    if(mStartFirstFrame)
+    {
+      StartFirstFrame(textureSet);
+    }
+    else
+    {
+      if(mImpl->mRenderer)
+      {
+        mImpl->mRenderer.SetTextures(textureSet);
+      }
+    }
   }
   else
   {
-    if( mImpl->mRenderer )
-    {
-      mImpl->mRenderer.SetTextures( textureSet );
-    }
+    DALI_LOG_INFO( gAnimImgLogFilter, Debug::Concise, "ResourceReady(ResourceStatus::FAILED)\n" );
+    ResourceReady( Toolkit::Visual::ResourceStatus::FAILED );
   }
 }
 
 bool AnimatedImageVisual::DisplayNextFrame()
 {
+  bool nextFrame = false;
+  uint32_t frameIndex = mImageCache->GetCurrentFrameIndex();
+
   if( mIsJumpTo )
   {
     mIsJumpTo = false;
+    frameIndex = mFrameIndexForJumpTo;
   }
   else if( mActionStatus == DevelAnimatedImageVisual::Action::PAUSE )
   {
@@ -697,14 +701,14 @@ bool AnimatedImageVisual::DisplayNextFrame()
   }
   else if( mActionStatus == DevelAnimatedImageVisual::Action::STOP )
   {
-    mCurrentLoopIndex = 0;
+    frameIndex = 0;
     if( mStopBehavior == DevelImageVisual::StopBehavior::FIRST_FRAME )
     {
-      mCurrentFrameIndex = 0;
+      frameIndex = 0;
     }
     else if( mStopBehavior == DevelImageVisual::StopBehavior::LAST_FRAME )
     {
-      mCurrentFrameIndex = mFrameCount - 1;
+      frameIndex = mFrameCount - 1;
     }
     else
     {
@@ -715,23 +719,15 @@ bool AnimatedImageVisual::DisplayNextFrame()
   {
     if( mFrameCount > 1 )
     {
-      // Wrap the frame index
-      bool finished = false;
-      ++mCurrentFrameIndex;
-      if( mCurrentFrameIndex >= mFrameCount )
+      nextFrame = true;
+      frameIndex++;
+      if( frameIndex >= mFrameCount )
       {
+        frameIndex %= mFrameCount;
         ++mCurrentLoopIndex;
-        finished = true;
       }
 
-      if( mLoopCount < 0 || mCurrentLoopIndex < mLoopCount)
-      {
-        if( finished )
-        {
-          mCurrentFrameIndex = 0; // Back to the first frame
-        }
-      }
-      else
+      if(mLoopCount >= 0 && mCurrentLoopIndex >= mLoopCount)
       {
         // This will stop timer
         mActionStatus = DevelAnimatedImageVisual::Action::STOP;
@@ -741,7 +737,7 @@ bool AnimatedImageVisual::DisplayNextFrame()
     // TODO : newly added one.
     if( mAnimatedImageLoading && mImageCache )
     {
-      unsigned int delay = mImageCache->GetFrameInterval( mCurrentFrameIndex );
+      unsigned int delay = mImageCache->GetFrameInterval( frameIndex );
       if( mFrameDelayTimer.GetInterval() != delay )
       {
         mFrameDelayTimer.SetInterval( delay );
@@ -749,12 +745,20 @@ bool AnimatedImageVisual::DisplayNextFrame()
     }
   }
 
-  DALI_LOG_INFO( gAnimImgLogFilter,Debug::Concise,"AnimatedImageVisual::DisplayNextFrame(this:%p) CurrentFrameIndex:%d\n", this, mCurrentFrameIndex);
+  DALI_LOG_INFO( gAnimImgLogFilter,Debug::Concise,"AnimatedImageVisual::DisplayNextFrame(this:%p) CurrentFrameIndex:%d\n", this, frameIndex);
 
   TextureSet textureSet;
   if( mImageCache )
   {
-    textureSet = mImageCache->Frame( mCurrentFrameIndex );
+    if(nextFrame)
+    {
+      textureSet = mImageCache->NextFrame();
+    }
+    else
+    {
+      textureSet = mImageCache->Frame( frameIndex );
+    }
+
     if( textureSet )
     {
       SetImageSize( textureSet );
index 8e91623..862dbb8 100644 (file)
@@ -246,7 +246,7 @@ private:
   Vector4 mPixelArea;
   VisualUrl mImageUrl;
   Dali::AnimatedImageLoading mAnimatedImageLoading; // Only needed for animated image
-  uint32_t mCurrentFrameIndex; // Frame index into textureRects
+  uint32_t mFrameIndexForJumpTo; // Frame index into textureRects
 
   // Variables for Multi-Image player
   ImageCache::UrlList* mImageUrls;
index 726cd39..fbc0284 100644 (file)
@@ -93,11 +93,23 @@ TextureSet FixedImageCache::FirstFrame()
   return textureSet;
 }
 
+TextureSet FixedImageCache::NextFrame()
+{
+  TextureSet textureSet = Frame((mFront + 1) % mImageUrls.size());
+
+  return textureSet;
+}
+
 uint32_t FixedImageCache::GetFrameInterval( uint32_t frameIndex )
 {
   return 0u;
 }
 
+int32_t FixedImageCache::GetCurrentFrameIndex()
+{
+  return static_cast<int32_t>(mFront);
+}
+
 bool FixedImageCache::IsFrontReady() const
 {
   return ( mReadyFlags.size() > 0 && mReadyFlags[mFront] == true );
index ec7f419..c160be3 100644 (file)
@@ -61,10 +61,22 @@ public:
   TextureSet FirstFrame() override;
 
   /**
+   * Get the next frame. If it's not ready, this will trigger the
+   * sending of FrameReady() when the image becomes ready.
+   */
+  TextureSet NextFrame() override;
+
+  /**
    * Get the interval of Nth frame.
    */
   uint32_t GetFrameInterval( uint32_t frameIndex ) override;
 
+  /**
+   * Get the current rendered frame index.
+   * If there isn't any loaded frame, returns -1.
+   */
+  int32_t GetCurrentFrameIndex() override;
+
 private:
   /**
    * @return true if the front frame is ready
index 1d385c8..c132fcf 100644 (file)
@@ -79,6 +79,12 @@ public:
   virtual TextureSet FirstFrame() = 0;
 
   /**
+   * Get the next frame. If it's not ready, this will trigger the
+   * sending of FrameReady() when the image becomes ready.
+   */
+  virtual TextureSet NextFrame() = 0;
+
+  /**
    * Get the Nth frame. If it's not ready, this will trigger the
    * sending of FrameReady() when the image becomes ready.
    */
@@ -89,6 +95,12 @@ public:
    */
   virtual uint32_t GetFrameInterval( uint32_t frameIndex ) = 0;
 
+  /**
+   * Get the current rendered frame index.
+   * If there isn't any loaded frame, returns -1.
+   */
+  virtual int32_t GetCurrentFrameIndex() = 0;
+
 private:
 
   /**
index 3992b08..20265ca 100644 (file)
@@ -65,6 +65,7 @@ RollingAnimatedImageCache::RollingAnimatedImageCache(
   mAnimatedImageLoading( animatedImageLoading ),
   mFrameCount( frameCount ),
   mFrameIndex( 0 ),
+  mCacheSize( cacheSize ),
   mQueue( cacheSize ),
   mIsSynchronousLoading( isSynchronousLoading ),
   mOnLoading( false )
@@ -114,10 +115,18 @@ TextureSet RollingAnimatedImageCache::Frame( uint32_t frameIndex )
     // If the frame of frameIndex was already loaded, load batch from the last frame of queue
     if( !mQueue.IsEmpty() )
     {
-      mFrameIndex = ( mQueue.Back().mFrameNumber + 1 ) % mFrameCount;
+      if(!mLoadWaitingQueue.empty())
+      {
+        mFrameIndex = ( mLoadWaitingQueue.back() + 1 ) % mFrameCount;
+      }
+      else
+      {
+        mFrameIndex = ( mQueue.Back().mFrameNumber + 1 ) % mFrameCount;
+      }
     }
     else
     {
+      mOnLoading = false;
       // If the request is for the first frame or a jumped frame(JUMP_TO) remove current waiting queue.
       mLoadWaitingQueue.clear();
       // If the queue is empty, and the frame of frameIndex is not loaded synchronously. load batch from the frame of frameIndex
@@ -149,11 +158,40 @@ TextureSet RollingAnimatedImageCache::FirstFrame()
   return Frame( 0u );
 }
 
+TextureSet RollingAnimatedImageCache::NextFrame()
+{
+  TextureSet textureSet;
+  if(!mQueue.IsEmpty())
+  {
+    uint32_t frameIndex = mQueue.Front().mFrameNumber;
+    if(IsFrontReady())
+    {
+      frameIndex = (frameIndex + 1) % mFrameCount;
+    }
+    textureSet = Frame(frameIndex);
+  }
+  else
+  {
+    DALI_LOG_ERROR("Cache is empty.");
+  }
+  
+  return textureSet;
+}
+
 uint32_t RollingAnimatedImageCache::GetFrameInterval( uint32_t frameIndex )
 {
   return mAnimatedImageLoading.GetFrameInterval( frameIndex );
 }
 
+int32_t RollingAnimatedImageCache::GetCurrentFrameIndex()
+{
+  if(mQueue.IsEmpty())
+  {
+    return -1;
+  }
+  return mQueue.Front().mFrameNumber;
+}
+
 bool RollingAnimatedImageCache::IsFrontReady() const
 {
   return ( !mQueue.IsEmpty() && mQueue.Front().mReady );
@@ -161,6 +199,12 @@ bool RollingAnimatedImageCache::IsFrontReady() const
 
 void RollingAnimatedImageCache::RequestFrameLoading( uint32_t frameIndex )
 {
+  ImageFrame imageFrame;
+  imageFrame.mFrameNumber = frameIndex;
+  imageFrame.mReady       = false;
+
+  mQueue.PushBack(imageFrame);
+
   mRequestingLoad = true;
 
   bool synchronousLoading = false;
@@ -178,14 +222,8 @@ void RollingAnimatedImageCache::LoadBatch()
   // removed, and another frame is loaded
 
   bool frontFrameReady = IsFrontReady();
-  for( unsigned int i=0; i< mBatchSize && !mQueue.IsFull(); ++i )
+  for( unsigned int i=0; i< mBatchSize && mQueue.Count() + mLoadWaitingQueue.size() < static_cast<uint32_t>(mCacheSize) && !mQueue.IsFull(); ++i )
   {
-    ImageFrame imageFrame;
-    imageFrame.mFrameNumber = mFrameIndex;
-    imageFrame.mReady = false;
-
-    mQueue.PushBack( imageFrame );
-
     if( !mOnLoading )
     {
       mOnLoading = true;
index 3a24eb6..620d373 100644 (file)
@@ -79,10 +79,22 @@ public:
   TextureSet FirstFrame() override;
 
   /**
+   * Get the next frame. If it's not ready, this will trigger the
+   * sending of FrameReady() when the image becomes ready.
+   */
+  TextureSet NextFrame() override;
+
+  /**
    * Get the interval of Nth frame.
    */
   uint32_t GetFrameInterval( uint32_t frameIndex ) override;
 
+  /**
+   * Get the current rendered frame index.
+   * If there isn't any loaded frame, returns -1.
+   */
+  int32_t GetCurrentFrameIndex() override;
+
 private:
   /**
    * @return true if the front frame is ready
@@ -149,6 +161,7 @@ private:
   Dali::AnimatedImageLoading  mAnimatedImageLoading;
   uint32_t                    mFrameCount;
   int                         mFrameIndex;
+  int                         mCacheSize;
   std::vector<UrlStore>       mImageUrls;
   std::vector<int32_t>        mIntervals;
   std::vector<uint32_t>       mLoadWaitingQueue;
index 2284778..d802d2c 100644 (file)
@@ -131,11 +131,40 @@ TextureSet RollingImageCache::FirstFrame()
   return Frame( 0u );
 }
 
+TextureSet RollingImageCache::NextFrame()
+{
+  TextureSet textureSet;
+  if(!mQueue.IsEmpty())
+  {
+    uint32_t frameIndex = mQueue.Front().mUrlIndex;
+    if(IsFrontReady())
+    {
+      frameIndex = (frameIndex + 1) % mImageUrls.size();
+    }
+    textureSet = Frame(frameIndex);
+  }
+  else
+  {
+    DALI_LOG_ERROR("Cache is empty.");
+  }
+
+  return textureSet;
+}
+
 uint32_t RollingImageCache::GetFrameInterval( uint32_t frameIndex )
 {
   return 0u;
 }
 
+int32_t RollingImageCache::GetCurrentFrameIndex()
+{
+  if(mQueue.IsEmpty())
+  {
+    return -1;
+  }
+  return mQueue.Front().mUrlIndex;
+}
+
 bool RollingImageCache::IsFrontReady() const
 {
   return ( !mQueue.IsEmpty() && mQueue.Front().mReady );
index 5f4aa46..921e29a 100644 (file)
@@ -72,10 +72,22 @@ public:
   TextureSet FirstFrame() override;
 
   /**
+   * Get the next frame. If it's not ready, this will trigger the
+   * sending of FrameReady() when the image becomes ready.
+   */
+  TextureSet NextFrame() override;
+
+  /**
    * Get the interval of Nth frame.
    */
   uint32_t GetFrameInterval( uint32_t frameIndex ) override;
 
+  /**
+   * Get the current rendered frame index.
+   * If there isn't any loaded frame, returns -1.
+   */
+  int32_t GetCurrentFrameIndex() override;
+
 private:
   /**
    * @return true if the front frame is ready