X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Fanimated-image%2Frolling-animated-image-cache.cpp;h=e5ea68e809329cbe61ad1167c5b96319fbde7503;hp=565252fb9567081df4f62ff1c51e42937f4a6194;hb=4464c30c30e68c6eee56cda1a201b22eb164fd20;hpb=02557f62f8d171115d885c87c138faec2a3cb923 diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp index 565252f..e5ea68e 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -17,8 +17,6 @@ // CLASS HEADER #include "rolling-animated-image-cache.h" -// EXTERNAL HEADERS - // INTERNAL HEADERS #include #include // For ImageAtlasManagerPtr @@ -29,27 +27,25 @@ 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:"<= mIntervals.size()) { - DALI_LOG_ERROR("Cache is empty."); + return 0u; } - - return textureSet; -} - -uint32_t RollingAnimatedImageCache::GetFrameInterval( uint32_t frameIndex ) const -{ - return mAnimatedImageLoading.GetFrameInterval( frameIndex ); + return mIntervals[frameIndex]; } int32_t RollingAnimatedImageCache::GetCurrentFrameIndex() const @@ -199,10 +177,10 @@ int32_t RollingAnimatedImageCache::GetTotalFrameCount() const bool RollingAnimatedImageCache::IsFrontReady() const { - return ( !mQueue.IsEmpty() && mQueue.Front().mReady ); + return (!mQueue.IsEmpty() && mQueue.Front().mReady); } -void RollingAnimatedImageCache::RequestFrameLoading( uint32_t frameIndex ) +TextureSet RollingAnimatedImageCache::RequestFrameLoading(uint32_t frameIndex, bool useCache, bool synchronousLoading) { ImageFrame imageFrame; imageFrame.mFrameNumber = frameIndex; @@ -210,49 +188,54 @@ void RollingAnimatedImageCache::RequestFrameLoading( uint32_t frameIndex ) mQueue.PushBack(imageFrame); - mRequestingLoad = true; + mLoadState = TextureManager::LoadState::LOADING; + + TextureManager::TextureId loadTextureId = TextureManager::INVALID_TEXTURE_ID; + TextureSet textureSet = mTextureManager.LoadAnimatedImageTexture(mAnimatedImageLoading, + frameIndex, + loadTextureId, + mMaskingData, + SamplingMode::BOX_THEN_LINEAR, + Dali::WrapMode::Type::DEFAULT, + Dali::WrapMode::Type::DEFAULT, + synchronousLoading, + useCache, + this); - bool synchronousLoading = false; - mTextureManager.LoadAnimatedImageTexture( mAnimatedImageLoading, frameIndex, SamplingMode::BOX_THEN_LINEAR, - synchronousLoading, mImageUrls[ frameIndex ].mTextureId, Dali::WrapMode::Type::DEFAULT, - Dali::WrapMode::Type::DEFAULT, this ); + mImageUrls[frameIndex].mTextureId = loadTextureId; - mRequestingLoad = false; + return textureSet; } -void RollingAnimatedImageCache::LoadBatch() +void RollingAnimatedImageCache::LoadBatch(uint32_t frameIndex) { // Try and load up to mBatchSize images, until the cache is filled. // Once the cache is filled, as frames progress, the old frame is // removed, and another frame is loaded - - bool frontFrameReady = IsFrontReady(); - for( unsigned int i=0; i< mBatchSize && mQueue.Count() + mLoadWaitingQueue.size() < static_cast(mCacheSize) && !mQueue.IsFull(); ++i ) + uint32_t minimumSize = std::min(mCacheSize, mFrameCount); + for(uint32_t i = 0; i < mBatchSize && (mQueue.Count() + mLoadWaitingQueue.size()) < minimumSize; ++i) { - if( !mOnLoading ) + if(mLoadState != TextureManager::LoadState::LOADING) { - mOnLoading = true; - RequestFrameLoading( mFrameIndex ); + RequestFrameLoading(frameIndex, frameIndex == FIRST_FRAME_INDEX, false); } else { - mLoadWaitingQueue.push_back( mFrameIndex ); + mLoadWaitingQueue.push_back(frameIndex); } - mFrameIndex++; - mFrameIndex %= mFrameCount; + frameIndex++; + frameIndex %= mFrameCount; } - CheckFrontFrame( frontFrameReady ); - LOG_CACHE; } -void RollingAnimatedImageCache::SetImageFrameReady( TextureManager::TextureId textureId ) +void RollingAnimatedImageCache::SetImageFrameReady(TextureManager::TextureId textureId) { - for( std::size_t i = 0; i < mQueue.Count() ; ++i ) + for(std::size_t i = 0; i < mQueue.Count(); ++i) { - if( GetCachedTextureId( i ) == textureId ) + if(GetCachedTextureId(i) == textureId) { mQueue[i].mReady = true; break; @@ -262,79 +245,114 @@ void RollingAnimatedImageCache::SetImageFrameReady( TextureManager::TextureId te TextureSet RollingAnimatedImageCache::GetFrontTextureSet() const { - DALI_LOG_INFO( gAnimImgLogFilter, Debug::Concise, "RollingAnimatedImageCache::GetFrontTextureSet() FrameNumber:%d\n", mQueue[ 0 ].mFrameNumber ); + 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); + return mTextureManager.GetTextureSet(textureId); } -TextureManager::TextureId RollingAnimatedImageCache::GetCachedTextureId( int index ) const +TextureManager::TextureId RollingAnimatedImageCache::GetCachedTextureId(int index) const { - return mImageUrls[ mQueue[ index ].mFrameNumber ].mTextureId; + return mImageUrls[mQueue[index].mFrameNumber].mTextureId; } -void RollingAnimatedImageCache::CheckFrontFrame( bool wasReady ) +void RollingAnimatedImageCache::PopFrontCache() { - if( mWaitingForReadyFrame && wasReady == false && IsFrontReady() ) + ImageFrame imageFrame = mQueue.PopFront(); + mTextureManager.Remove(mImageUrls[imageFrame.mFrameNumber].mTextureId, this); + mImageUrls[imageFrame.mFrameNumber].mTextureId = TextureManager::INVALID_TEXTURE_ID; + + if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID) { - mWaitingForReadyFrame = false; - mObserver.FrameReady( GetFrontTextureSet() ); + mTextureManager.Remove(mMaskingData->mAlphaMaskId, this); + if(mQueue.IsEmpty()) + { + mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID; + } } } -void RollingAnimatedImageCache::UploadComplete( - bool loadSuccess, - int32_t textureId, - TextureSet textureSet, - bool useAtlasing, - const Vector4& atlasRect, - bool preMultiplied ) +void RollingAnimatedImageCache::ClearCache() { - DALI_LOG_INFO(gAnimImgLogFilter,Debug::Concise,"AnimatedImageVisual::UploadComplete(textureId:%d) start\n", textureId); - LOG_CACHE; - - bool frontFrameReady = IsFrontReady(); - - if( !mRequestingLoad ) + while(mTextureManagerAlive && !mQueue.IsEmpty()) { - SetImageFrameReady( textureId ); + PopFrontCache(); + } + mLoadWaitingQueue.clear(); + mLoadState = TextureManager::LoadState::NOT_STARTED; +} - CheckFrontFrame( frontFrameReady ); +void RollingAnimatedImageCache::MakeFrameReady(bool loadSuccess, TextureSet textureSet, uint32_t interval) +{ + if(!loadSuccess) + { + mLoadState = TextureManager::LoadState::LOAD_FAILED; + mObserver.FrameReady(TextureSet(), 0); } else { - // UploadComplete has been called from within RequestLoad. TextureManager must - // therefore already have the texture cached, so make the texture ready. - // (Use the last texture, as the texture id hasn't been assigned yet) - mQueue.Back().mReady = true; + mLoadState = TextureManager::LoadState::LOAD_FINISHED; + + // Reset size of Queue according to the real frame count. + if(mFrameCount != mAnimatedImageLoading.GetImageCount()) + { + mFrameCount = mAnimatedImageLoading.GetImageCount(); + mImageUrls.resize(mFrameCount); + mIntervals.assign(mFrameCount, 0u); + } + + bool frontFrameReady = IsFrontReady(); + // Because only one frame is on loading and the others are in mLoadWaitingQueue, + // mQueue.Back() is always the frame currently loaded. + mQueue.Back().mReady = true; + mIntervals[mQueue.Back().mFrameNumber] = interval; + // Check whether currently loaded frame is front of queue or not. + // If it is, notify frame ready to observer. + if(frontFrameReady == false && IsFrontReady()) + { + mObserver.FrameReady(textureSet, interval); + } } +} - mOnLoading = false; - // The frames of a single animated image can not be loaded parallelly. - // Therefore, a frame is now loading, other orders are waiting. - // And, after the frame is loaded, requests load of next order. - if( !mLoadWaitingQueue.empty() ) +void RollingAnimatedImageCache::LoadComplete(bool loadSuccess, TextureInformation textureInformation) +{ + 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(loadSuccess) { - uint32_t loadingIndex = mLoadWaitingQueue.front(); - mLoadWaitingQueue.erase( mLoadWaitingQueue.begin() ); - mOnLoading = true; - RequestFrameLoading( loadingIndex ); + // The frames of a single animated image can not be loaded parallelly. + // Therefore, a frame is now loading, other orders are waiting. + // And, after the frame is loaded, requests load of next order. + if(!mLoadWaitingQueue.empty()) + { + uint32_t loadingIndex = mLoadWaitingQueue.front(); + mLoadWaitingQueue.erase(mLoadWaitingQueue.begin()); + RequestFrameLoading(loadingIndex, loadingIndex == FIRST_FRAME_INDEX, false); + } + else if(mQueue.Count() == 1u && textureInformation.frameCount > SINGLE_IMAGE_COUNT) + { + // There is only an image in queue and no waiting queue. + // Request to load batch once again. + uint32_t batchFrameIndex = 0u; + if(!mLoadWaitingQueue.empty()) + { + batchFrameIndex = (mLoadWaitingQueue.back() + 1) % mFrameCount; + } + else + { + batchFrameIndex = (mQueue.Back().mFrameNumber + 1) % mFrameCount; + } + LoadBatch(batchFrameIndex); + } } LOG_CACHE; } -void RollingAnimatedImageCache::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