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=386013a98c470a3349a14861d2ed5a7d99c4fe75;hp=84ae1c920e990fa5239fa4b1dfde21eac2980474;hb=248c644059d4784ab65fe3d2690022c2888edd3b;hpb=c20463e1d4a77117810c67adfec49bcdfab5efde 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 84ae1c9..386013a 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) 2017 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. @@ -30,12 +30,13 @@ #include #include #include +#include #include #include #include -#include #include #include +#include namespace Dali { @@ -48,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 ) @@ -57,6 +65,7 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::WrapMode, MIRRORED_REPEAT ) DALI_ENUM_TO_STRING_TABLE_END( WRAP_MODE ) const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); +constexpr auto LOOP_FOREVER = -1; #if defined(DEBUG_ENABLED) Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ANIMATED_IMAGE"); @@ -99,9 +108,9 @@ Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, " * Time */ -AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl, const Property::Map& properties ) +AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties ) { - AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache ) ); + AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache, shaderFactory ) ); visual->InitializeGif( imageUrl ); visual->SetProperties( properties ); @@ -113,9 +122,9 @@ AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCach return visual; } -AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, const Property::Array& imageUrls, const Property::Map& properties ) +AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const Property::Array& imageUrls, const Property::Map& properties ) { - AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache ) ); + AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache, shaderFactory ) ); visual->mImageUrls = new ImageCache::UrlList(); visual->mImageUrls->reserve( imageUrls.Count() ); @@ -137,9 +146,9 @@ AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCach return visual; } -AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl ) +AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl ) { - AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache ) ); + AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache, shaderFactory ) ); visual->InitializeGif( imageUrl ); if( visual->mFrameCount > 0 ) @@ -153,15 +162,16 @@ AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCach void AnimatedImageVisual::InitializeGif( const VisualUrl& imageUrl ) { mImageUrl = imageUrl; - mGifLoading = GifLoading::New( imageUrl.GetUrl() ); + mGifLoading = GifLoading::New( imageUrl.GetUrl(), imageUrl.IsLocalResource() ); mFrameCount = mGifLoading->GetImageCount(); mGifLoading->LoadFrameDelays( mFrameDelayContainer ); } -AnimatedImageVisual::AnimatedImageVisual( VisualFactoryCache& factoryCache ) -: Visual::Base( factoryCache ), +AnimatedImageVisual::AnimatedImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory ) +: Visual::Base( factoryCache, Visual::FittingMode::FIT_KEEP_ASPECT_RATIO, Toolkit::Visual::ANIMATED_IMAGE ), mFrameDelayTimer(), mPlacementActor(), + mImageVisualShaderFactory( shaderFactory ), mPixelArea( FULL_TEXTURE_RECT ), mImageUrl(), mGifLoading( nullptr ), @@ -171,12 +181,17 @@ AnimatedImageVisual::AnimatedImageVisual( VisualFactoryCache& factoryCache ) mCacheSize( 1 ), mBatchSize( 1 ), mFrameDelay( 100 ), + mLoopCount( LOOP_FOREVER ), + mCurrentLoopIndex( 0 ), mUrlIndex( 0 ), mFrameCount( 0 ), mImageSize(), mWrapModeU( WrapMode::DEFAULT ), mWrapModeV( WrapMode::DEFAULT ), - mStartFirstFrame(false) + mActionStatus( DevelAnimatedImageVisual::Action::PLAY ), + mStopBehavior( DevelImageVisual::StopBehavior::CURRENT_FRAME ), + mStartFirstFrame(false), + mIsJumpTo( false ) {} AnimatedImageVisual::~AnimatedImageVisual() @@ -231,6 +246,9 @@ void AnimatedImageVisual::DoCreatePropertyMap( Property::Map& map ) const map.Insert( Toolkit::ImageVisual::Property::BATCH_SIZE, static_cast(mBatchSize) ); 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 @@ -238,6 +256,62 @@ void AnimatedImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) cons // Do nothing } +void AnimatedImageVisual::OnDoAction( const Dali::Property::Index actionId, const Dali::Property::Value& attributes ) +{ + // Check if action is valid for this visual type and perform action if possible + + switch ( actionId ) + { + case DevelAnimatedImageVisual::Action::PAUSE: + { + // Pause will be executed on next timer tick + mActionStatus = DevelAnimatedImageVisual::Action::PAUSE; + break; + } + case DevelAnimatedImageVisual::Action::PLAY: + { + if( IsOnStage() && mActionStatus != DevelAnimatedImageVisual::Action::PLAY ) + { + mFrameDelayTimer.Start(); + } + mActionStatus = DevelAnimatedImageVisual::Action::PLAY; + break; + } + case DevelAnimatedImageVisual::Action::STOP: + { + // STOP reset functionality will actually be done in a future change + // Stop will be executed on next timer tick + mActionStatus = DevelAnimatedImageVisual::Action::STOP; + if( IsOnStage() ) + { + 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; + mCurrentFrameIndex = frameNumber; + if( IsOnStage() ) + { + DisplayNextFrame(); + } + } + } + break; + } + } +} + void AnimatedImageVisual::DoSetProperties( const Property::Map& propertyMap ) { // url[s] already passed in from constructor @@ -275,6 +349,14 @@ void AnimatedImageVisual::DoSetProperties( const Property::Map& propertyMap ) { DoSetProperty( Toolkit::ImageVisual::Property::FRAME_DELAY, keyValue.second ); } + else if( keyValue.first == LOOP_COUNT_NAME ) + { + DoSetProperty( Toolkit::DevelImageVisual::Property::LOOP_COUNT, keyValue.second ); + } + else if( keyValue.first == STOP_BEHAVIOR_NAME ) + { + DoSetProperty( Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, keyValue.second ); + } } } } @@ -291,7 +373,7 @@ void AnimatedImageVisual::DoSetProperty( Property::Index index, } case Toolkit::ImageVisual::Property::WRAP_MODE_U: { - int wrapMode; + int wrapMode = 0; if(Scripting::GetEnumerationProperty( value, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, wrapMode )) { mWrapModeU = Dali::WrapMode::Type(wrapMode); @@ -304,7 +386,7 @@ void AnimatedImageVisual::DoSetProperty( Property::Index index, } case Toolkit::ImageVisual::Property::WRAP_MODE_V: { - int wrapMode; + int wrapMode = 0; if(Scripting::GetEnumerationProperty( value, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, wrapMode )) { mWrapModeV = Dali::WrapMode::Type(wrapMode); @@ -345,6 +427,26 @@ void AnimatedImageVisual::DoSetProperty( Property::Index index, } break; } + + case Toolkit::DevelImageVisual::Property::LOOP_COUNT: + { + int loopCount; + if( value.Get( loopCount ) ) + { + mLoopCount = loopCount; + } + 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; + } } } @@ -391,7 +493,7 @@ void AnimatedImageVisual::CreateRenderer() { bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE; bool atlasing = false; - Shader shader = ImageVisual::GetImageShader( mFactoryCache, atlasing, defaultWrapMode ); + Shader shader = mImageVisualShaderFactory.GetShader( mFactoryCache, atlasing, defaultWrapMode, IsRoundedCornerRequired() ); Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY ); @@ -444,24 +546,28 @@ void AnimatedImageVisual::LoadFirstBatch() { mImageCache = new RollingGifImageCache( textureManager, *mGifLoading, mFrameCount, *this, cacheSize, batchSize ); } - else if( batchSize > 0 && cacheSize > 0 ) + else if( mImageUrls ) { - if( cacheSize < numUrls ) + if( batchSize > 0 && cacheSize > 0 ) { - mImageCache = new RollingImageCache( textureManager, *mImageUrls, *this, cacheSize, batchSize ); + if( cacheSize < numUrls ) + { + mImageCache = new RollingImageCache( textureManager, *mImageUrls, *this, cacheSize, batchSize ); + } + else + { + mImageCache = new FixedImageCache( textureManager, *mImageUrls, *this, batchSize ); + } } else { - mImageCache = new FixedImageCache( textureManager, *mImageUrls, *this, batchSize ); + mImageCache = new RollingImageCache( textureManager, *mImageUrls, *this, 1, 1 ); } } - else - { - mImageCache = new RollingImageCache( textureManager, *mImageUrls, *this, 1, 1 ); - } + if (!mImageCache) { - DALI_LOG_ERROR("mImageCache is null"); + DALI_LOG_ERROR("mImageCache is null\n"); } } @@ -470,7 +576,10 @@ void AnimatedImageVisual::StartFirstFrame( TextureSet& textureSet ) DALI_LOG_INFO(gAnimImgLogFilter,Debug::Concise,"AnimatedImageVisual::StartFirstFrame()\n"); mStartFirstFrame = false; - mImpl->mRenderer.SetTextures( textureSet ); + if(mImpl->mRenderer) + { + mImpl->mRenderer.SetTextures( textureSet ); + } Actor actor = mPlacementActor.GetHandle(); if( actor ) { @@ -537,41 +646,92 @@ void AnimatedImageVisual::FrameReady( TextureSet textureSet ) } else { - mImpl->mRenderer.SetTextures( textureSet ); + if(mImpl->mRenderer) + { + mImpl->mRenderer.SetTextures( textureSet ); + } } } bool AnimatedImageVisual::DisplayNextFrame() { - if( mFrameCount > 1 ) + if( mIsJumpTo ) { - // Wrap the frame index - ++mCurrentFrameIndex; - mCurrentFrameIndex %= mFrameCount; + mIsJumpTo = false; } - DALI_LOG_INFO( gAnimImgLogFilter,Debug::Concise,"AnimatedImageVisual::DisplayNextFrame(this:%p) FrameCount:%d\n", this, mCurrentFrameIndex); - - if( mFrameDelayContainer.Count() > 0 ) + else if( mActionStatus == DevelAnimatedImageVisual::Action::PAUSE ) + { + return false; + } + else if( mActionStatus == DevelAnimatedImageVisual::Action::STOP ) { - unsigned int delay = mFrameDelayContainer[mCurrentFrameIndex]; + mCurrentLoopIndex = 0; + if( mStopBehavior == DevelImageVisual::StopBehavior::FIRST_FRAME ) + { + mCurrentFrameIndex = 0; + } + else if( mStopBehavior == DevelImageVisual::StopBehavior::LAST_FRAME ) + { + mCurrentFrameIndex = mFrameCount - 1; + } + else + { + return false; // Do not draw already rendered scene twice. + } + } + else + { + if( mFrameCount > 1 ) + { + // Wrap the frame index + bool finished = false; + ++mCurrentFrameIndex; + if( mCurrentFrameIndex >= mFrameCount ) + { + ++mCurrentLoopIndex; + finished = true; + } + + if( mLoopCount < 0 || mCurrentLoopIndex < mLoopCount) + { + if( finished ) + { + mCurrentFrameIndex = 0; // Back to the first frame + } + } + else + { + // This will stop timer + mActionStatus = DevelAnimatedImageVisual::Action::STOP; + return DisplayNextFrame(); + } + } - if( mFrameDelayTimer.GetInterval() != delay ) + if( mFrameDelayContainer.Count() > 0 ) { - mFrameDelayTimer.SetInterval( delay ); + unsigned int delay = mFrameDelayContainer[mCurrentFrameIndex]; + + if( mFrameDelayTimer.GetInterval() != delay ) + { + mFrameDelayTimer.SetInterval( delay ); + } } } + DALI_LOG_INFO( gAnimImgLogFilter,Debug::Concise,"AnimatedImageVisual::DisplayNextFrame(this:%p) CurrentFrameIndex:%d\n", this, mCurrentFrameIndex); + TextureSet textureSet; - if (mImageCache) - textureSet = mImageCache->NextFrame(); - if( textureSet ) + if( mImageCache ) { - SetImageSize( textureSet ); - mImpl->mRenderer.SetTextures( textureSet ); + textureSet = mImageCache->Frame( mCurrentFrameIndex ); + if( textureSet ) + { + SetImageSize( textureSet ); + mImpl->mRenderer.SetTextures( textureSet ); + } } - // Keep timer ticking - return true; + return ( mActionStatus == DevelAnimatedImageVisual::Action::PLAY ) ? true : false; }