mPixelArea( FULL_TEXTURE_RECT ),
mImageUrl(),
mAnimatedImageLoading(),
- mCurrentFrameIndex( 0 ),
+ mFrameIndexForJumpTo( 0 ),
mImageUrls( NULL ),
mImageCache( NULL ),
mCacheSize( 2 ),
else
{
mIsJumpTo = true;
- mCurrentFrameIndex = frameNumber;
+ mFrameIndexForJumpTo = frameNumber;
if( IsOnScene() )
{
DisplayNextFrame();
{
mImpl->mRenderer.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, mPixelArea );
}
-
- mCurrentFrameIndex = 0;
}
void AnimatedImageVisual::LoadFirstBatch()
mPlacementActor.Reset();
}
- mCurrentFrameIndex = 0;
-
if( mFrameCount > 1 )
{
int frameDelay = mFrameDelay; // from URL array
{
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;
}
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 )
{
}
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
{
{
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;
// 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 );
}
}
- 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 );
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;
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 );
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
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.
*/
*/
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:
/**
mAnimatedImageLoading( animatedImageLoading ),
mFrameCount( frameCount ),
mFrameIndex( 0 ),
+ mCacheSize( cacheSize ),
mQueue( cacheSize ),
mIsSynchronousLoading( isSynchronousLoading ),
mOnLoading( false )
// 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
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 );
void RollingAnimatedImageCache::RequestFrameLoading( uint32_t frameIndex )
{
+ ImageFrame imageFrame;
+ imageFrame.mFrameNumber = frameIndex;
+ imageFrame.mReady = false;
+
+ mQueue.PushBack(imageFrame);
+
mRequestingLoad = true;
bool synchronousLoading = false;
// 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;
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
Dali::AnimatedImageLoading mAnimatedImageLoading;
uint32_t mFrameCount;
int mFrameIndex;
+ int mCacheSize;
std::vector<UrlStore> mImageUrls;
std::vector<int32_t> mIntervals;
std::vector<uint32_t> mLoadWaitingQueue;
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 );
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