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%2Fanimated-image-visual.cpp;h=5a83d9219bfc1d13738fbc99ff2d5d29a4823d0e;hp=f2160ef669801a2bbc3568e9ac1445fa41a5feb2;hb=e3ca2d8166cf74b2b0072ce491e9a4275a98b1cc;hpb=2ffc3a77b8aa6f8ccdbaaef41c0fa14034853582 diff --git a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp index f2160ef..5a83d92 100755 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 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. @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include @@ -49,6 +49,13 @@ namespace Internal namespace { +// stop behavior +DALI_ENUM_TO_STRING_TABLE_BEGIN( STOP_BEHAVIOR ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::StopBehavior, CURRENT_FRAME ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::StopBehavior, FIRST_FRAME ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::Toolkit::DevelImageVisual::StopBehavior, LAST_FRAME ) +DALI_ENUM_TO_STRING_TABLE_END( STOP_BEHAVIOR ) + // wrap modes DALI_ENUM_TO_STRING_TABLE_BEGIN( WRAP_MODE ) DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::WrapMode, DEFAULT ) @@ -75,7 +82,7 @@ Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, " * | new cache * | cache->LoadBatch() * | - * | DoSetOnStage() + * | DoSetOnScene() * | PrepareTextureSet() * | cache->FirstFrame() * | CreateRenderer() (Doesn't become ready until first frame loads) @@ -104,7 +111,7 @@ Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, " AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties ) { AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache, shaderFactory ) ); - visual->InitializeGif( imageUrl ); + visual->InitializeAnimatedImage( imageUrl ); visual->SetProperties( properties ); if( visual->mFrameCount > 0 ) @@ -142,7 +149,7 @@ AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCach AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl ) { AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache, shaderFactory ) ); - visual->InitializeGif( imageUrl ); + visual->InitializeAnimatedImage( imageUrl ); if( visual->mFrameCount > 0 ) { @@ -152,27 +159,26 @@ AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCach return visual; } -void AnimatedImageVisual::InitializeGif( const VisualUrl& imageUrl ) +void AnimatedImageVisual::InitializeAnimatedImage( const VisualUrl& imageUrl ) { mImageUrl = imageUrl; - mGifLoading = GifLoading::New( imageUrl.GetUrl(), imageUrl.IsLocalResource() ); - mFrameCount = mGifLoading->GetImageCount(); - mGifLoading->LoadFrameDelays( mFrameDelayContainer ); + mAnimatedImageLoading = AnimatedImageLoading::New( imageUrl.GetUrl(), imageUrl.IsLocalResource() ); + mFrameCount = mAnimatedImageLoading.GetImageCount(); } AnimatedImageVisual::AnimatedImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory ) -: Visual::Base( factoryCache, Visual::FittingMode::FIT_KEEP_ASPECT_RATIO ), +: Visual::Base( factoryCache, Visual::FittingMode::FIT_KEEP_ASPECT_RATIO, Toolkit::Visual::ANIMATED_IMAGE ), mFrameDelayTimer(), mPlacementActor(), mImageVisualShaderFactory( shaderFactory ), mPixelArea( FULL_TEXTURE_RECT ), mImageUrl(), - mGifLoading( nullptr ), - mCurrentFrameIndex( 0 ), + mAnimatedImageLoading(), + mFrameIndexForJumpTo( 0 ), mImageUrls( NULL ), mImageCache( NULL ), - mCacheSize( 1 ), - mBatchSize( 1 ), + mCacheSize( 2 ), + mBatchSize( 2 ), mFrameDelay( 100 ), mLoopCount( LOOP_FOREVER ), mCurrentLoopIndex( 0 ), @@ -182,7 +188,9 @@ AnimatedImageVisual::AnimatedImageVisual( VisualFactoryCache& factoryCache, Imag mWrapModeU( WrapMode::DEFAULT ), mWrapModeV( WrapMode::DEFAULT ), mActionStatus( DevelAnimatedImageVisual::Action::PLAY ), - mStartFirstFrame(false) + mStopBehavior( DevelImageVisual::StopBehavior::CURRENT_FRAME ), + mStartFirstFrame(false), + mIsJumpTo( false ) {} AnimatedImageVisual::~AnimatedImageVisual() @@ -197,7 +205,7 @@ void AnimatedImageVisual::GetNaturalSize( Vector2& naturalSize ) { if( mImageUrl.IsValid() ) { - mImageSize = mGifLoading->GetImageSize(); + mImageSize = mAnimatedImageLoading.GetImageSize(); } else if( mImageUrls && mImageUrls->size() > 0 ) { @@ -213,6 +221,9 @@ void AnimatedImageVisual::DoCreatePropertyMap( Property::Map& map ) const { map.Clear(); + bool sync = IsSynchronousLoadingRequired(); + map.Insert( Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, sync ); + map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::ANIMATED_IMAGE ); if( mImageUrl.IsValid() ) @@ -238,6 +249,8 @@ void AnimatedImageVisual::DoCreatePropertyMap( Property::Map& map ) const map.Insert( Toolkit::ImageVisual::Property::CACHE_SIZE, static_cast(mCacheSize) ); map.Insert( Toolkit::ImageVisual::Property::FRAME_DELAY, static_cast(mFrameDelay) ); map.Insert( Toolkit::DevelImageVisual::Property::LOOP_COUNT, static_cast(mLoopCount) ); + + map.Insert( Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mStopBehavior ); } void AnimatedImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const @@ -259,7 +272,7 @@ void AnimatedImageVisual::OnDoAction( const Dali::Property::Index actionId, cons } case DevelAnimatedImageVisual::Action::PLAY: { - if( IsOnStage() && mActionStatus != DevelAnimatedImageVisual::Action::PLAY ) + if( mFrameDelayTimer && IsOnScene() && mActionStatus != DevelAnimatedImageVisual::Action::PLAY ) { mFrameDelayTimer.Start(); } @@ -270,8 +283,32 @@ void AnimatedImageVisual::OnDoAction( const Dali::Property::Index actionId, cons { // STOP reset functionality will actually be done in a future change // Stop will be executed on next timer tick - mCurrentFrameIndex = 0; mActionStatus = DevelAnimatedImageVisual::Action::STOP; + if( IsOnScene() ) + { + DisplayNextFrame(); + } + break; + } + case DevelAnimatedImageVisual::Action::JUMP_TO: + { + int32_t frameNumber; + if( attributes.Get( frameNumber ) ) + { + if( frameNumber < 0 || frameNumber >= static_cast( mFrameCount ) ) + { + DALI_LOG_ERROR( "Invalid frame index used.\n" ); + } + else + { + mIsJumpTo = true; + mFrameIndexForJumpTo = frameNumber; + if( IsOnScene() ) + { + DisplayNextFrame(); + } + } + } break; } } @@ -318,6 +355,10 @@ void AnimatedImageVisual::DoSetProperties( const Property::Map& propertyMap ) { DoSetProperty( Toolkit::DevelImageVisual::Property::LOOP_COUNT, keyValue.second ); } + else if( keyValue.first == STOP_BEHAVIOR_NAME ) + { + DoSetProperty( Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, keyValue.second ); + } } } } @@ -364,7 +405,14 @@ void AnimatedImageVisual::DoSetProperty( Property::Index index, int batchSize; if( value.Get( batchSize ) ) { - mBatchSize = batchSize; + if( batchSize < 2 ) + { + DALI_LOG_ERROR( "The minimum value of batch size is 2." ); + } + else + { + mBatchSize = batchSize; + } } break; } @@ -374,7 +422,14 @@ void AnimatedImageVisual::DoSetProperty( Property::Index index, int cacheSize; if( value.Get( cacheSize ) ) { - mCacheSize = cacheSize; + if( cacheSize < 2 ) + { + DALI_LOG_ERROR( "The minimum value of cache size is 2." ); + } + else + { + mCacheSize = cacheSize; + } } break; } @@ -398,10 +453,35 @@ void AnimatedImageVisual::DoSetProperty( Property::Index index, } break; } + + case Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR: + { + int32_t stopBehavior = mStopBehavior; + if( Scripting::GetEnumerationProperty( value, STOP_BEHAVIOR_TABLE, STOP_BEHAVIOR_TABLE_COUNT, stopBehavior ) ) + { + mStopBehavior = DevelImageVisual::StopBehavior::Type( stopBehavior ); + } + break; + } + + case Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING: + { + bool sync = false; + value.Get( sync ); + if( sync ) + { + mImpl->mFlags |= Impl::IS_SYNCHRONOUS_RESOURCE_LOADING; + } + else + { + mImpl->mFlags &= ~Impl::IS_SYNCHRONOUS_RESOURCE_LOADING; + } + break; + } } } -void AnimatedImageVisual::DoSetOnStage( Actor& actor ) +void AnimatedImageVisual::DoSetOnScene( Actor& actor ) { mPlacementActor = actor; TextureSet textureSet = PrepareTextureSet(); @@ -417,7 +497,7 @@ void AnimatedImageVisual::DoSetOnStage( Actor& actor ) } } -void AnimatedImageVisual::DoSetOffStage( Actor& actor ) +void AnimatedImageVisual::DoSetOffScene( Actor& actor ) { DALI_ASSERT_DEBUG( (bool)mImpl->mRenderer && "There should always be a renderer whilst on stage"); @@ -430,6 +510,7 @@ void AnimatedImageVisual::DoSetOffStage( Actor& actor ) actor.RemoveRenderer( mImpl->mRenderer ); mImpl->mRenderer.Reset(); mPlacementActor.Reset(); + mStartFirstFrame = false; } void AnimatedImageVisual::OnSetTransform() @@ -464,8 +545,6 @@ void AnimatedImageVisual::CreateRenderer() { mImpl->mRenderer.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, mPixelArea ); } - - mCurrentFrameIndex = 0; } void AnimatedImageVisual::LoadFirstBatch() @@ -493,9 +572,9 @@ void AnimatedImageVisual::LoadFirstBatch() mUrlIndex = 0; TextureManager& textureManager = mFactoryCache.GetTextureManager(); - if( mGifLoading != nullptr ) + if( mAnimatedImageLoading ) { - mImageCache = new RollingGifImageCache( textureManager, *mGifLoading, mFrameCount, *this, cacheSize, batchSize ); + mImageCache = new RollingAnimatedImageCache( textureManager, mAnimatedImageLoading, mFrameCount, *this, cacheSize, batchSize, IsSynchronousLoadingRequired() ); } else if( mImageUrls ) { @@ -518,7 +597,7 @@ void AnimatedImageVisual::LoadFirstBatch() if (!mImageCache) { - DALI_LOG_ERROR("mImageCache is null"); + DALI_LOG_ERROR("mImageCache is null\n"); } } @@ -530,24 +609,22 @@ void AnimatedImageVisual::StartFirstFrame( TextureSet& textureSet ) if(mImpl->mRenderer) { mImpl->mRenderer.SetTextures( textureSet ); - } - Actor actor = mPlacementActor.GetHandle(); - if( actor ) - { - actor.AddRenderer( mImpl->mRenderer ); - mPlacementActor.Reset(); - } - mCurrentFrameIndex = 0; + Actor actor = mPlacementActor.GetHandle(); + if( actor ) + { + actor.AddRenderer( mImpl->mRenderer ); + mPlacementActor.Reset(); + } + } if( mFrameCount > 1 ) { - int frameDelay = mFrameDelay; // from URL array - if( mFrameDelayContainer.Count() > 0 ) // from GIF + int frameDelay = mImageCache->GetFrameInterval( 0 ); + if( frameDelay == 0u ) { - frameDelay = mFrameDelayContainer[0]; + frameDelay = mFrameDelay; // from URL array } - mFrameDelayTimer = Timer::New( frameDelay ); mFrameDelayTimer.TickSignal().Connect( this, &AnimatedImageVisual::DisplayNextFrame ); mFrameDelayTimer.Start(); @@ -560,16 +637,14 @@ TextureSet AnimatedImageVisual::PrepareTextureSet() { TextureSet textureSet; if (mImageCache) + { 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; } @@ -589,71 +664,118 @@ 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() { - if( mActionStatus == DevelAnimatedImageVisual::Action::STOP || mActionStatus == DevelAnimatedImageVisual::Action::PAUSE ) - { - return false; - } - if( mFrameCount > 1 ) + bool continueTimer = false; + + if(mImageCache) { - // Wrap the frame index - ++mCurrentFrameIndex; + bool nextFrame = false; + uint32_t frameIndex = mImageCache->GetCurrentFrameIndex(); - if( mLoopCount < 0 || mCurrentLoopIndex <= mLoopCount) + if( mIsJumpTo ) { - mCurrentFrameIndex %= mFrameCount; - if( mCurrentFrameIndex == 0 ) + mIsJumpTo = false; + frameIndex = mFrameIndexForJumpTo; + } + else if( mActionStatus == DevelAnimatedImageVisual::Action::PAUSE ) + { + return false; + } + else if( mActionStatus == DevelAnimatedImageVisual::Action::STOP ) + { + frameIndex = 0; + if( mStopBehavior == DevelImageVisual::StopBehavior::FIRST_FRAME ) { - ++mCurrentLoopIndex; + frameIndex = 0; + } + else if( mStopBehavior == DevelImageVisual::StopBehavior::LAST_FRAME ) + { + frameIndex = mFrameCount - 1; + } + else + { + return false; // Do not draw already rendered scene twice. } } else { - // This will stop timer - return false; + if( mFrameCount > 1 ) + { + nextFrame = true; + frameIndex++; + if( frameIndex >= mFrameCount ) + { + frameIndex %= mFrameCount; + ++mCurrentLoopIndex; + } + + if(mLoopCount >= 0 && mCurrentLoopIndex >= mLoopCount) + { + // This will stop timer + mActionStatus = DevelAnimatedImageVisual::Action::STOP; + return DisplayNextFrame(); + } + } + + unsigned int delay = mImageCache->GetFrameInterval( frameIndex ); + if( delay > 0u ) + { + if( mFrameDelayTimer.GetInterval() != delay ) + { + mFrameDelayTimer.SetInterval( delay ); + } + } } - } - DALI_LOG_INFO( gAnimImgLogFilter,Debug::Concise,"AnimatedImageVisual::DisplayNextFrame(this:%p) FrameCount:%d\n", this, mCurrentFrameIndex); - if( mFrameDelayContainer.Count() > 0 ) - { - unsigned int delay = mFrameDelayContainer[mCurrentFrameIndex]; + DALI_LOG_INFO( gAnimImgLogFilter,Debug::Concise,"AnimatedImageVisual::DisplayNextFrame(this:%p) CurrentFrameIndex:%d\n", this, frameIndex); - if( mFrameDelayTimer.GetInterval() != delay ) + TextureSet textureSet; + if(nextFrame) { - mFrameDelayTimer.SetInterval( delay ); + textureSet = mImageCache->NextFrame(); + } + else + { + textureSet = mImageCache->Frame( frameIndex ); } - } - TextureSet textureSet; - if( mImageCache ) - { - textureSet = mImageCache->NextFrame(); if( textureSet ) { SetImageSize( textureSet ); - mImpl->mRenderer.SetTextures( textureSet ); + if( mImpl->mRenderer ) + { + mImpl->mRenderer.SetTextures( textureSet ); + } } + + continueTimer = ( mActionStatus == DevelAnimatedImageVisual::Action::PLAY ) ? true : false; } - // Keep timer ticking - return true; + return continueTimer; }