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-image-cache.cpp;h=7a84f5b225894691a6524487ac4605f9aca24d5d;hp=dee6149c16216cea1ba056366d24df1aaf022767;hb=750fadba87bb959c9af32e89e3f1bc7af6cb6dd2;hpb=06390b11a4bbb71ee3d9a0508ed33cb3aa14d8a3 diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp index dee6149..7a84f5b 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 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. @@ -28,28 +28,28 @@ 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:"<IsEnabledFor(Debug::Concise)) \ + { \ + std::ostringstream oss; \ + oss << "Size:" << mQueue.Count() << " [ "; \ + for(std::size_t _i = 0; _i < mQueue.Count(); ++_i) \ + { \ + oss << _i << "={ tex:" << mImageUrls[mQueue[_i].mUrlIndex].mTextureId << " urlId:" << mQueue[_i].mUrlIndex << " rdy:" << (mQueue[_i].mReady ? "T" : "F") << "}, "; \ + } \ + oss << " ]" << std::endl; \ + DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "%s", oss.str().c_str()); \ } #else - #define LOG_CACHE +#define LOG_CACHE #endif -const bool ENABLE_ORIENTATION_CORRECTION( true ); +static constexpr bool ENABLE_ORIENTATION_CORRECTION(true); -} +static constexpr uint32_t FIRST_FRAME_INDEX = 0u; + +} // namespace namespace Dali { @@ -57,103 +57,64 @@ namespace Toolkit { namespace Internal { - -RollingImageCache::RollingImageCache( - TextureManager& textureManager, UrlList& urlList, ImageCache::FrameReadyObserver& observer, - uint16_t cacheSize, uint16_t batchSize ) -: ImageCache( textureManager, observer, batchSize ), - mImageUrls( urlList ), - mQueue( cacheSize ) +RollingImageCache::RollingImageCache(TextureManager& textureManager, + UrlList& urlList, + TextureManager::MaskingDataPointer& maskingData, + ImageCache::FrameReadyObserver& observer, + uint16_t cacheSize, + uint16_t batchSize, + uint32_t interval) +: ImageCache(textureManager, maskingData, observer, batchSize, interval), + mImageUrls(urlList), + mQueue(cacheSize) { - LoadBatch(); } RollingImageCache::~RollingImageCache() { - if( mTextureManagerAlive ) - { - while( !mQueue.IsEmpty() ) - { - ImageFrame imageFrame = mQueue.PopFront(); - mTextureManager.Remove( mImageUrls[ imageFrame.mUrlIndex ].mTextureId, this ); - } - } + ClearCache(); } -TextureSet RollingImageCache::Frame( uint32_t frameIndex ) +TextureSet RollingImageCache::Frame(uint32_t frameIndex) { - // If a frame of frameIndex is not loaded, clear the queue and remove all loaded textures. - if( mImageUrls[ frameIndex ].mTextureId == TextureManager::INVALID_TEXTURE_ID ) + // Pop frames until the frame of frameIndex become front frame. + bool popExist = false; + while(!mQueue.IsEmpty() && mQueue.Front().mUrlIndex != frameIndex) { - 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(); + PopFrontCache(); + popExist = true; } - // If the frame is already loaded, remove previous frames of the frame in the queue - // and load new frames amount of removed frames. - else + + // TODO: synchronous loading of first frame. + if(popExist || mQueue.IsEmpty()) { - bool popExist = false; - while( !mQueue.IsEmpty() && mQueue.Front().mUrlIndex != frameIndex ) + uint32_t batchFrameIndex = frameIndex; + // If the frame of frameIndex was already loaded, load batch from the last frame of queue + if(!mQueue.IsEmpty()) { - 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(); + batchFrameIndex = (mQueue.Back().mUrlIndex + 1) % mImageUrls.size(); } + LoadBatch(batchFrameIndex); } TextureSet textureSet; - if( IsFrontReady() == true ) + if(IsFrontReady() == true && mLoadState != TextureManager::LoadState::LOAD_FAILED) { textureSet = GetFrontTextureSet(); } - else - { - mWaitingForReadyFrame = true; - } return textureSet; } 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."); - } - + TextureSet textureSet = Frame(FIRST_FRAME_INDEX); return textureSet; } -uint32_t RollingImageCache::GetFrameInterval( uint32_t frameIndex ) const +uint32_t RollingImageCache::GetFrameInterval(uint32_t frameIndex) const { - return 0u; + return mInterval; } int32_t RollingImageCache::GetCurrentFrameIndex() const @@ -172,132 +133,129 @@ int32_t RollingImageCache::GetTotalFrameCount() const bool RollingImageCache::IsFrontReady() const { - return ( !mQueue.IsEmpty() && mQueue.Front().mReady ); + return (!mQueue.IsEmpty() && mQueue.Front().mReady); } -void RollingImageCache::LoadBatch() +void RollingImageCache::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 // cleared, but not erased, and another image is loaded - bool frontFrameReady = IsFrontReady(); - - for( unsigned int i=0; i< mBatchSize && !mQueue.IsFull(); ++i ) + for(unsigned int i = 0; i < mBatchSize && !mQueue.IsFull(); ++i) { ImageFrame imageFrame; - std::string& url = mImageUrls[ mUrlIndex ].mUrl; - imageFrame.mUrlIndex = mUrlIndex; - imageFrame.mReady = false; + VisualUrl& url = mImageUrls[frameIndex].mUrl; + imageFrame.mUrlIndex = frameIndex; + imageFrame.mReady = false; - ++mUrlIndex; - mUrlIndex %= mImageUrls.size(); + mQueue.PushBack(imageFrame); - mQueue.PushBack( imageFrame ); - - // Note, if the image is already loaded, then UploadComplete will get called + // Note, if the image is already loaded, then LoadComplete will get called // from within this method. This means it won't yet have a texture id, so we - // need to account for this inside the UploadComplete method using mRequestingLoad. + // need to account for this inside the LoadComplete method using mRequestingLoad. mRequestingLoad = true; - - bool synchronousLoading = false; - bool atlasingStatus = false; - bool loadingStatus = false; - TextureManager::MaskingDataPointer maskInfo = nullptr; - AtlasUploadObserver* atlasObserver = nullptr; - ImageAtlasManagerPtr imageAtlasManager = nullptr; - Vector4 textureRect; + mLoadState = TextureManager::LoadState::LOADING; + + bool synchronousLoading = false; + bool atlasingStatus = false; + bool loadingStatus = false; + AtlasUploadObserver* atlasObserver = nullptr; + ImageAtlasManagerPtr imageAtlasManager = nullptr; + Vector4 textureRect; Dali::ImageDimensions textureRectSize; - auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + 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, textureRectSize, - atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, - Dali::WrapMode::Type::DEFAULT, this, - atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, - preMultiply ); + TextureManager::TextureId loadTextureId = TextureManager::INVALID_TEXTURE_ID; + TextureSet textureSet = mTextureManager.LoadTexture( + url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, loadTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply); + mImageUrls[imageFrame.mUrlIndex].mTextureId = loadTextureId; mRequestingLoad = false; - } - CheckFrontFrame( frontFrameReady ); + ++frameIndex; + frameIndex %= mImageUrls.size(); + } } -void RollingImageCache::SetImageFrameReady( TextureManager::TextureId textureId ) +TextureSet RollingImageCache::GetFrontTextureSet() const { - for( std::size_t i = 0; i < mQueue.Count() ; ++i ) - { - if( GetCachedTextureId(i) == textureId ) - { - mQueue[i].mReady = true; - break; - } - } + TextureManager::TextureId textureId = GetCachedTextureId(0); + return mTextureManager.GetTextureSet(textureId); } -TextureSet RollingImageCache::GetFrontTextureSet() const +TextureManager::TextureId RollingImageCache::GetCachedTextureId(int index) const { - TextureManager::TextureId textureId = GetCachedTextureId( 0 ); - return mTextureManager.GetTextureSet( textureId ); + return mImageUrls[mQueue[index].mUrlIndex].mTextureId; } -TextureManager::TextureId RollingImageCache::GetCachedTextureId( int index ) const +void RollingImageCache::PopFrontCache() { - return mImageUrls[ mQueue[ index ].mUrlIndex ].mTextureId; + ImageFrame imageFrame = mQueue.PopFront(); + mTextureManager.Remove(mImageUrls[imageFrame.mUrlIndex].mTextureId, this); + mImageUrls[imageFrame.mUrlIndex].mTextureId = TextureManager::INVALID_TEXTURE_ID; + + if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID) + { + mTextureManager.Remove(mMaskingData->mAlphaMaskId, this); + if(mQueue.IsEmpty()) + { + mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID; + } + } } -void RollingImageCache::CheckFrontFrame( bool wasReady ) +void RollingImageCache::ClearCache() { - if( mWaitingForReadyFrame && wasReady == false && IsFrontReady() ) + while(mTextureManagerAlive && !mQueue.IsEmpty()) { - mWaitingForReadyFrame = false; - mObserver.FrameReady( GetFrontTextureSet() ); + PopFrontCache(); } + mLoadState = TextureManager::LoadState::NOT_STARTED; } -void RollingImageCache::UploadComplete( - bool loadSuccess, - int32_t textureId, - TextureSet textureSet, - bool useAtlasing, - const Vector4& atlasRect, - bool preMultiplied ) +void RollingImageCache::LoadComplete(bool loadSuccess, TextureInformation textureInformation) { - DALI_LOG_INFO(gAnimImgLogFilter,Debug::Concise,"AnimatedImageVisual::UploadComplete(textureId:%d) start\n", textureId); + DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "AnimatedImageVisual::LoadComplete(textureId:%d) start\n", textureInformation.textureId); LOG_CACHE; - bool frontFrameReady = IsFrontReady(); - - if( ! mRequestingLoad ) + if(loadSuccess) { - SetImageFrameReady( textureId ); + mLoadState = TextureManager::LoadState::LOAD_FINISHED; + bool frontFrameReady = IsFrontReady(); + if(!mRequestingLoad) + { + for(std::size_t i = 0; i < mQueue.Count(); ++i) + { + if(GetCachedTextureId(i) == textureInformation.textureId) + { + mQueue[i].mReady = true; + break; + } + } + } + else + { + // LoadComplete 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; + } - CheckFrontFrame( frontFrameReady ); + if(!frontFrameReady && IsFrontReady()) + { + mObserver.FrameReady(mTextureManager.GetTextureSet(textureInformation.textureId), mInterval); + } } 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_FAILED; + mObserver.FrameReady(TextureSet(), 0); } 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