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=58506fdbc23e37792ecc1249b2bd93efcab5e07f;hp=a0ebe451facbef332454a5e5ea62e5aae53274fa;hb=8ce82d79da52fcd0ca29ce20b85ba625da067fcf;hpb=a00bbe499550a054e6692eb46b32f8c1548f3647 diff --git a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp old mode 100755 new mode 100644 index a0ebe45..58506fd --- 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) 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. @@ -24,54 +24,50 @@ #include // INTERNAL INCLUDES -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace Dali { - namespace Toolkit { - 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 ) +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 ) -DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::WrapMode, CLAMP_TO_EDGE ) -DALI_ENUM_TO_STRING_WITH_SCOPE( Dali::WrapMode, REPEAT ) -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); +DALI_ENUM_TO_STRING_TABLE_BEGIN(WRAP_MODE) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::WrapMode, DEFAULT) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::WrapMode, CLAMP_TO_EDGE) + DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::WrapMode, REPEAT) + 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"); #endif -} - +} // namespace /** * Multi-image Flow of execution @@ -82,7 +78,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) @@ -108,91 +104,97 @@ Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, " * Time */ -AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, 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, shaderFactory ) ); - visual->InitializeGif( imageUrl ); - visual->SetProperties( properties ); + AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory)); + visual->InitializeAnimatedImage(imageUrl); + visual->SetProperties(properties); - if( visual->mFrameCount > 0 ) + if(visual->mFrameCount > 0) { visual->LoadFirstBatch(); } + visual->Initialize(); + return visual; } -AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, 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, shaderFactory ) ); + AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory)); visual->mImageUrls = new ImageCache::UrlList(); - visual->mImageUrls->reserve( imageUrls.Count() ); + visual->mImageUrls->reserve(imageUrls.Count()); - for( unsigned int i=0; i < imageUrls.Count(); ++i) + for(unsigned int i = 0; i < imageUrls.Count(); ++i) { ImageCache::UrlStore urlStore; urlStore.mTextureId = TextureManager::INVALID_TEXTURE_ID; - urlStore.mUrl = imageUrls[i].Get(); - visual->mImageUrls->push_back( urlStore ); + urlStore.mUrl = imageUrls[i].Get(); + visual->mImageUrls->push_back(urlStore); } visual->mFrameCount = imageUrls.Count(); - visual->SetProperties( properties ); + visual->SetProperties(properties); - if( visual->mFrameCount > 0 ) + if(visual->mFrameCount > 0) { visual->LoadFirstBatch(); } + visual->Initialize(); + return visual; } -AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl ) +AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl) { - AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache, shaderFactory ) ); - visual->InitializeGif( imageUrl ); + AnimatedImageVisualPtr visual(new AnimatedImageVisual(factoryCache, shaderFactory)); + visual->InitializeAnimatedImage(imageUrl); - if( visual->mFrameCount > 0 ) + if(visual->mFrameCount > 0) { visual->LoadFirstBatch(); } + visual->Initialize(); + 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 ); + mImageUrl = imageUrl; + 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 ), +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 ), + mImageVisualShaderFactory(shaderFactory), + mPixelArea(FULL_TEXTURE_RECT), mImageUrl(), - mGifLoading( nullptr ), - mCurrentFrameIndex( 0 ), - mImageUrls( NULL ), - mImageCache( NULL ), - mCacheSize( 1 ), - mBatchSize( 1 ), - mFrameDelay( 100 ), - mLoopCount( LOOP_FOREVER ), - mCurrentLoopIndex( 0 ), - mUrlIndex( 0 ), - mFrameCount( 0 ), + mAnimatedImageLoading(), + mFrameIndexForJumpTo(0), + mImageUrls(NULL), + mImageCache(NULL), + mCacheSize(2), + mBatchSize(2), + mFrameDelay(100), + mLoopCount(LOOP_FOREVER), + mCurrentLoopIndex(0), + mUrlIndex(0), + mFrameCount(0), mImageSize(), - mWrapModeU( WrapMode::DEFAULT ), - mWrapModeV( WrapMode::DEFAULT ), - mActionStatus( DevelAnimatedImageVisual::Action::PLAY ), - mStopBehavior( DevelImageVisual::StopBehavior::CURRENT_FRAME ), + mWrapModeU(WrapMode::DEFAULT), + mWrapModeV(WrapMode::DEFAULT), + mActionStatus(DevelAnimatedImageVisual::Action::PLAY), + mStopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME), mStartFirstFrame(false), - mIsJumpTo( false ) -{} + mIsJumpTo(false) +{ +} AnimatedImageVisual::~AnimatedImageVisual() { @@ -200,67 +202,77 @@ AnimatedImageVisual::~AnimatedImageVisual() delete mImageUrls; } -void AnimatedImageVisual::GetNaturalSize( Vector2& naturalSize ) +void AnimatedImageVisual::GetNaturalSize(Vector2& naturalSize) { - if( mImageSize.GetWidth() == 0 && mImageSize.GetHeight() == 0) + if(mImageSize.GetWidth() == 0 && mImageSize.GetHeight() == 0) { - if( mImageUrl.IsValid() ) + if(mImageUrl.IsValid()) { - mImageSize = mGifLoading->GetImageSize(); + mImageSize = mAnimatedImageLoading.GetImageSize(); } - else if( mImageUrls && mImageUrls->size() > 0 ) + else if(mImageUrls && mImageUrls->size() > 0) { - mImageSize = Dali::GetClosestImageSize( (*mImageUrls)[0].mUrl ); + mImageSize = Dali::GetClosestImageSize((*mImageUrls)[0].mUrl); } } - naturalSize.width = mImageSize.GetWidth(); + naturalSize.width = mImageSize.GetWidth(); naturalSize.height = mImageSize.GetHeight(); } -void AnimatedImageVisual::DoCreatePropertyMap( Property::Map& map ) const +void AnimatedImageVisual::DoCreatePropertyMap(Property::Map& map) const { map.Clear(); - map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::ANIMATED_IMAGE ); + bool sync = IsSynchronousLoadingRequired(); + map.Insert(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, sync); - if( mImageUrl.IsValid() ) + map.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::ANIMATED_IMAGE); + + if(mImageUrl.IsValid()) { - map.Insert( Toolkit::ImageVisual::Property::URL, mImageUrl.GetUrl() ); + map.Insert(Toolkit::ImageVisual::Property::URL, mImageUrl.GetUrl()); } - if( mImageUrls != NULL && ! mImageUrls->empty() ) + if(mImageUrls != NULL && !mImageUrls->empty()) { Property::Array urls; - for( unsigned int i=0; isize(); ++i) + for(unsigned int i = 0; i < mImageUrls->size(); ++i) { - urls.Add( (*mImageUrls)[i].mUrl ); + urls.Add((*mImageUrls)[i].mUrl); } - Property::Value value( const_cast(urls) ); - map.Insert( Toolkit::ImageVisual::Property::URL, value ); + Property::Value value(const_cast(urls)); + map.Insert(Toolkit::ImageVisual::Property::URL, value); } - map.Insert( Toolkit::ImageVisual::Property::PIXEL_AREA, mPixelArea ); - map.Insert( Toolkit::ImageVisual::Property::WRAP_MODE_U, mWrapModeU ); - map.Insert( Toolkit::ImageVisual::Property::WRAP_MODE_V, mWrapModeV ); + map.Insert(Toolkit::ImageVisual::Property::PIXEL_AREA, mPixelArea); + map.Insert(Toolkit::ImageVisual::Property::WRAP_MODE_U, mWrapModeU); + map.Insert(Toolkit::ImageVisual::Property::WRAP_MODE_V, mWrapModeV); - 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::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::CURRENT_FRAME_NUMBER, (mImageCache) ? static_cast(mImageCache->GetCurrentFrameIndex()) : -1); + map.Insert(Toolkit::DevelImageVisual::Property::TOTAL_FRAME_NUMBER, (mImageCache) ? static_cast(mImageCache->GetTotalFrameCount()) : -1); - map.Insert( Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mStopBehavior ); + map.Insert(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mStopBehavior); } -void AnimatedImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const +void AnimatedImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const { // Do nothing } -void AnimatedImageVisual::OnDoAction( const Dali::Property::Index actionId, const Dali::Property::Value& attributes ) +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 + // Make not set any action when the resource status is already failed. + if(mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::FAILED) + { + return; + } - switch ( actionId ) + // Check if action is valid for this visual type and perform action if possible + switch(actionId) { case DevelAnimatedImageVisual::Action::PAUSE: { @@ -270,7 +282,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(); } @@ -282,7 +294,7 @@ 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 mActionStatus = DevelAnimatedImageVisual::Action::STOP; - if( IsOnStage() ) + if(IsOnScene()) { DisplayNextFrame(); } @@ -291,17 +303,17 @@ void AnimatedImageVisual::OnDoAction( const Dali::Property::Index actionId, cons case DevelAnimatedImageVisual::Action::JUMP_TO: { int32_t frameNumber; - if( attributes.Get( frameNumber ) ) + if(attributes.Get(frameNumber)) { - if( frameNumber < 0 || frameNumber >= static_cast( mFrameCount ) ) + if(frameNumber < 0 || frameNumber >= static_cast(mFrameCount)) { - DALI_LOG_ERROR( "Invalid frame index used.\n" ); + DALI_LOG_ERROR("Invalid frame index used.\n"); } else { - mIsJumpTo = true; - mCurrentFrameIndex = frameNumber; - if( IsOnStage() ) + mIsJumpTo = true; + mFrameIndexForJumpTo = frameNumber; + if(IsOnScene()) { DisplayNextFrame(); } @@ -312,69 +324,68 @@ void AnimatedImageVisual::OnDoAction( const Dali::Property::Index actionId, cons } } -void AnimatedImageVisual::DoSetProperties( const Property::Map& propertyMap ) +void AnimatedImageVisual::DoSetProperties(const Property::Map& propertyMap) { // url[s] already passed in from constructor - - for( Property::Map::SizeType iter = 0; iter < propertyMap.Count(); ++iter ) + for(Property::Map::SizeType iter = 0; iter < propertyMap.Count(); ++iter) { - KeyValuePair keyValue = propertyMap.GetKeyValue( iter ); - if( keyValue.first.type == Property::Key::INDEX ) + KeyValuePair keyValue = propertyMap.GetKeyValue(iter); + if(keyValue.first.type == Property::Key::INDEX) { - DoSetProperty( keyValue.first.indexKey, keyValue.second ); + DoSetProperty(keyValue.first.indexKey, keyValue.second); } else { - if( keyValue.first == PIXEL_AREA_UNIFORM_NAME ) + if(keyValue.first == PIXEL_AREA_UNIFORM_NAME) { - DoSetProperty( Toolkit::ImageVisual::Property::PIXEL_AREA, keyValue.second ); + DoSetProperty(Toolkit::ImageVisual::Property::PIXEL_AREA, keyValue.second); } - else if( keyValue.first == IMAGE_WRAP_MODE_U ) + else if(keyValue.first == IMAGE_WRAP_MODE_U) { - DoSetProperty( Toolkit::ImageVisual::Property::WRAP_MODE_U, keyValue.second ); + DoSetProperty(Toolkit::ImageVisual::Property::WRAP_MODE_U, keyValue.second); } - else if( keyValue.first == IMAGE_WRAP_MODE_V ) + else if(keyValue.first == IMAGE_WRAP_MODE_V) { - DoSetProperty( Toolkit::ImageVisual::Property::WRAP_MODE_V, keyValue.second ); + DoSetProperty(Toolkit::ImageVisual::Property::WRAP_MODE_V, keyValue.second); } - else if( keyValue.first == BATCH_SIZE_NAME ) + else if(keyValue.first == BATCH_SIZE_NAME) { - DoSetProperty( Toolkit::ImageVisual::Property::BATCH_SIZE, keyValue.second ); + DoSetProperty(Toolkit::ImageVisual::Property::BATCH_SIZE, keyValue.second); } - else if( keyValue.first == CACHE_SIZE_NAME ) + else if(keyValue.first == CACHE_SIZE_NAME) { - DoSetProperty( Toolkit::ImageVisual::Property::CACHE_SIZE, keyValue.second ); + DoSetProperty(Toolkit::ImageVisual::Property::CACHE_SIZE, keyValue.second); } - else if( keyValue.first == FRAME_DELAY_NAME ) + else if(keyValue.first == FRAME_DELAY_NAME) { - DoSetProperty( Toolkit::ImageVisual::Property::FRAME_DELAY, keyValue.second ); + DoSetProperty(Toolkit::ImageVisual::Property::FRAME_DELAY, keyValue.second); } - else if( keyValue.first == LOOP_COUNT_NAME ) + else if(keyValue.first == LOOP_COUNT_NAME) { - DoSetProperty( Toolkit::DevelImageVisual::Property::LOOP_COUNT, keyValue.second ); + DoSetProperty(Toolkit::DevelImageVisual::Property::LOOP_COUNT, keyValue.second); } - else if( keyValue.first == STOP_BEHAVIOR_NAME ) + else if(keyValue.first == STOP_BEHAVIOR_NAME) { - DoSetProperty( Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, keyValue.second ); + DoSetProperty(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, keyValue.second); } } } } -void AnimatedImageVisual::DoSetProperty( Property::Index index, - const Property::Value& value ) +void AnimatedImageVisual::DoSetProperty(Property::Index index, + const Property::Value& value) { switch(index) { case Toolkit::ImageVisual::Property::PIXEL_AREA: { - value.Get( mPixelArea ); + value.Get(mPixelArea); break; } case Toolkit::ImageVisual::Property::WRAP_MODE_U: { int wrapMode = 0; - if(Scripting::GetEnumerationProperty( value, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, wrapMode )) + if(Scripting::GetEnumerationProperty(value, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, wrapMode)) { mWrapModeU = Dali::WrapMode::Type(wrapMode); } @@ -387,7 +398,7 @@ void AnimatedImageVisual::DoSetProperty( Property::Index index, case Toolkit::ImageVisual::Property::WRAP_MODE_V: { int wrapMode = 0; - if(Scripting::GetEnumerationProperty( value, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, wrapMode )) + if(Scripting::GetEnumerationProperty(value, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, wrapMode)) { mWrapModeV = Dali::WrapMode::Type(wrapMode); } @@ -401,9 +412,16 @@ void AnimatedImageVisual::DoSetProperty( Property::Index index, case Toolkit::ImageVisual::Property::BATCH_SIZE: { int batchSize; - if( value.Get( 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; } @@ -411,9 +429,16 @@ void AnimatedImageVisual::DoSetProperty( Property::Index index, case Toolkit::ImageVisual::Property::CACHE_SIZE: { int cacheSize; - if( value.Get( 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; } @@ -421,7 +446,7 @@ void AnimatedImageVisual::DoSetProperty( Property::Index index, case Toolkit::ImageVisual::Property::FRAME_DELAY: { int frameDelay; - if( value.Get( frameDelay ) ) + if(value.Get(frameDelay)) { mFrameDelay = frameDelay; } @@ -431,7 +456,7 @@ void AnimatedImageVisual::DoSetProperty( Property::Index index, case Toolkit::DevelImageVisual::Property::LOOP_COUNT: { int loopCount; - if( value.Get( loopCount ) ) + if(value.Get(loopCount)) { mLoopCount = loopCount; } @@ -441,24 +466,45 @@ void AnimatedImageVisual::DoSetProperty( Property::Index index, case Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR: { int32_t stopBehavior = mStopBehavior; - if( Scripting::GetEnumerationProperty( value, STOP_BEHAVIOR_TABLE, STOP_BEHAVIOR_TABLE_COUNT, stopBehavior ) ) + if(Scripting::GetEnumerationProperty(value, STOP_BEHAVIOR_TABLE, STOP_BEHAVIOR_TABLE_COUNT, stopBehavior)) { - mStopBehavior = DevelImageVisual::StopBehavior::Type( 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; + mPlacementActor = actor; TextureSet textureSet = PrepareTextureSet(); - CreateRenderer(); // Always create a renderer when on stage - if( textureSet ) // if the image loading is successful + // Loading animated image file is failed. + if(!mImageCache || + (mAnimatedImageLoading && !mAnimatedImageLoading.HasLoadingSucceeded())) + { + textureSet = SetLoadingFailed(); + } + + if(textureSet) // if the image loading is successful { - StartFirstFrame( textureSet ); + StartFirstFrame(textureSet); } else { @@ -466,66 +512,68 @@ 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"); + DALI_ASSERT_DEBUG((bool)mImpl->mRenderer && "There should always be a renderer whilst on stage"); - if( mFrameDelayTimer ) + if(mFrameDelayTimer) { mFrameDelayTimer.Stop(); mFrameDelayTimer.Reset(); } - actor.RemoveRenderer( mImpl->mRenderer ); - mImpl->mRenderer.Reset(); + actor.RemoveRenderer(mImpl->mRenderer); mPlacementActor.Reset(); + mStartFirstFrame = false; } void AnimatedImageVisual::OnSetTransform() { - if( mImpl->mRenderer ) + if(mImpl->mRenderer) { - mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT ); + mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); } } -void AnimatedImageVisual::CreateRenderer() +void AnimatedImageVisual::OnInitialize() { - bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE; - bool atlasing = false; - Shader shader = mImageVisualShaderFactory.GetShader( mFactoryCache, atlasing, defaultWrapMode, IsRoundedCornerRequired() ); + bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE; + Shader shader = mImageVisualShaderFactory.GetShader( + mFactoryCache, + TextureAtlas::DISABLED, + defaultWrapMode ? DefaultTextureWrapMode::APPLY : DefaultTextureWrapMode::DO_NOT_APPLY, + IsRoundedCornerRequired() ? RoundedCorner::ENABLED : RoundedCorner::DISABLED, + IsBorderlineRequired() ? Borderline::ENABLED : Borderline::DISABLED); - Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY ); + Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY); - mImpl->mRenderer = Renderer::New( geometry, shader ); + mImpl->mRenderer = Renderer::New(geometry, shader); // Register transform properties - mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT ); + mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); - if( !defaultWrapMode ) // custom wrap mode + if(!defaultWrapMode) // custom wrap mode { - Vector2 wrapMode(mWrapModeU-WrapMode::CLAMP_TO_EDGE, mWrapModeV-WrapMode::CLAMP_TO_EDGE); - wrapMode.Clamp( Vector2::ZERO, Vector2( 2.f, 2.f ) ); - mImpl->mRenderer.RegisterProperty( WRAP_MODE_UNIFORM_NAME, wrapMode ); + Vector2 wrapMode(mWrapModeU - WrapMode::CLAMP_TO_EDGE, mWrapModeV - WrapMode::CLAMP_TO_EDGE); + wrapMode.Clamp(Vector2::ZERO, Vector2(2.f, 2.f)); + mImpl->mRenderer.RegisterProperty(WRAP_MODE_UNIFORM_NAME, wrapMode); } - if( mPixelArea != FULL_TEXTURE_RECT ) + if(mPixelArea != FULL_TEXTURE_RECT) { - mImpl->mRenderer.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, mPixelArea ); + mImpl->mRenderer.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, mPixelArea); } - - mCurrentFrameIndex = 0; } void AnimatedImageVisual::LoadFirstBatch() { // Ensure the batch size and cache size are no bigger than the number of URLs, // and that the cache is at least as big as the batch size. - uint16_t numUrls = 0; + uint16_t numUrls = 0; uint16_t batchSize = 1; uint16_t cacheSize = 1; - if( mImageUrls ) + if(mImageUrls) { numUrls = mImageUrls->size(); } @@ -534,206 +582,241 @@ void AnimatedImageVisual::LoadFirstBatch() numUrls = mFrameCount; } - batchSize = std::min( mBatchSize, numUrls ); - cacheSize = std::min( std::max( batchSize, mCacheSize ), numUrls ); + batchSize = std::min(mBatchSize, numUrls); + cacheSize = std::min(std::max(batchSize, mCacheSize), numUrls); - DALI_LOG_INFO(gAnimImgLogFilter,Debug::Concise,"AnimatedImageVisual::LoadFirstBatch() batchSize:%d cacheSize:%d\n", batchSize, cacheSize); + DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "AnimatedImageVisual::LoadFirstBatch() batchSize:%d cacheSize:%d\n", batchSize, cacheSize); - mUrlIndex = 0; + 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 ) + else if(mImageUrls) { - if( batchSize > 0 && cacheSize > 0 ) + if(batchSize > 0 && cacheSize > 0) { - if( cacheSize < numUrls ) + if(cacheSize < numUrls) { - mImageCache = new RollingImageCache( textureManager, *mImageUrls, *this, cacheSize, batchSize ); + mImageCache = new RollingImageCache(textureManager, *mImageUrls, *this, cacheSize, batchSize); } else { - mImageCache = new FixedImageCache( textureManager, *mImageUrls, *this, batchSize ); + mImageCache = new FixedImageCache(textureManager, *mImageUrls, *this, batchSize); } } else { - mImageCache = new RollingImageCache( textureManager, *mImageUrls, *this, 1, 1 ); + mImageCache = new RollingImageCache(textureManager, *mImageUrls, *this, 1, 1); } } - if (!mImageCache) + if(!mImageCache) { DALI_LOG_ERROR("mImageCache is null\n"); } } -void AnimatedImageVisual::StartFirstFrame( TextureSet& textureSet ) +void AnimatedImageVisual::StartFirstFrame(TextureSet& textureSet) { - DALI_LOG_INFO(gAnimImgLogFilter,Debug::Concise,"AnimatedImageVisual::StartFirstFrame()\n"); + DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "AnimatedImageVisual::StartFirstFrame()\n"); mStartFirstFrame = false; if(mImpl->mRenderer) { - mImpl->mRenderer.SetTextures( textureSet ); - } - Actor actor = mPlacementActor.GetHandle(); - if( actor ) - { - actor.AddRenderer( mImpl->mRenderer ); - mPlacementActor.Reset(); - } + mImpl->mRenderer.SetTextures(textureSet); - mCurrentFrameIndex = 0; + Actor actor = mPlacementActor.GetHandle(); + if(actor) + { + actor.AddRenderer(mImpl->mRenderer); + mPlacementActor.Reset(); + } + } - if( mFrameCount > 1 ) + 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 = Timer::New(frameDelay); + mFrameDelayTimer.TickSignal().Connect(this, &AnimatedImageVisual::DisplayNextFrame); mFrameDelayTimer.Start(); } - DALI_LOG_INFO(gAnimImgLogFilter,Debug::Concise,"ResourceReady(ResourceStatus::READY)\n"); - ResourceReady( Toolkit::Visual::ResourceStatus::READY ); + + if(mImpl->mResourceStatus != Toolkit::Visual::ResourceStatus::FAILED) + { + DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "ResourceReady(ResourceStatus::READY)\n"); + ResourceReady(Toolkit::Visual::ResourceStatus::READY); + } } TextureSet AnimatedImageVisual::PrepareTextureSet() { TextureSet textureSet; - if (mImageCache) - textureSet = mImageCache->FirstFrame(); - if( textureSet ) + if(mImageCache) { - SetImageSize( textureSet ); + textureSet = mImageCache->FirstFrame(); } - else + + if(textureSet) { - DALI_LOG_INFO(gAnimImgLogFilter,Debug::Concise,"ResourceReady(ResourceStatus::FAILED)\n"); - ResourceReady( Toolkit::Visual::ResourceStatus::FAILED ); + SetImageSize(textureSet); } return textureSet; } -void AnimatedImageVisual::SetImageSize( TextureSet& textureSet ) +void AnimatedImageVisual::SetImageSize(TextureSet& textureSet) { - if( textureSet ) + if(textureSet) { - Texture texture = textureSet.GetTexture( 0 ); - if( texture ) + Texture texture = textureSet.GetTexture(0); + if(texture) { - mImageSize.SetWidth( texture.GetWidth() ); - mImageSize.SetHeight( texture.GetHeight() ); + mImageSize.SetWidth(texture.GetWidth()); + mImageSize.SetHeight(texture.GetHeight()); } } } -void AnimatedImageVisual::FrameReady( TextureSet textureSet ) +void AnimatedImageVisual::FrameReady(TextureSet textureSet) { - SetImageSize( textureSet ); + // When image visual requested to load new frame to mImageCache and it is failed. + if(!textureSet) + { + textureSet = SetLoadingFailed(); + } - if( mStartFirstFrame ) + SetImageSize(textureSet); + + if(mStartFirstFrame) { - StartFirstFrame( textureSet ); + StartFirstFrame(textureSet); } else { if(mImpl->mRenderer) { - mImpl->mRenderer.SetTextures( textureSet ); + mImpl->mRenderer.SetTextures(textureSet); } } } bool AnimatedImageVisual::DisplayNextFrame() { - if( mIsJumpTo ) - { - mIsJumpTo = false; - } - else if( mActionStatus == DevelAnimatedImageVisual::Action::PAUSE ) - { - return false; - } - else if( mActionStatus == DevelAnimatedImageVisual::Action::STOP ) + TextureSet textureSet; + bool continueTimer = false; + + if(mImageCache) { - mCurrentLoopIndex = 0; - if( mStopBehavior == DevelImageVisual::StopBehavior::FIRST_FRAME ) + bool nextFrame = false; + uint32_t frameIndex = mImageCache->GetCurrentFrameIndex(); + + if(mIsJumpTo) { - mCurrentFrameIndex = 0; + mIsJumpTo = false; + frameIndex = mFrameIndexForJumpTo; } - else if( mStopBehavior == DevelImageVisual::StopBehavior::LAST_FRAME ) + else if(mActionStatus == DevelAnimatedImageVisual::Action::PAUSE) { - mCurrentFrameIndex = mFrameCount - 1; + return false; } - else + else if(mActionStatus == DevelAnimatedImageVisual::Action::STOP) { - return false; // Do not draw already rendered scene twice. - } - } - else - { - if( mFrameCount > 1 ) - { - // Wrap the frame index - bool finished = false; - ++mCurrentFrameIndex; - if( mCurrentFrameIndex >= mFrameCount ) + frameIndex = 0; + if(mStopBehavior == DevelImageVisual::StopBehavior::FIRST_FRAME) { - ++mCurrentLoopIndex; - finished = true; + frameIndex = 0; } - - if( mLoopCount < 0 || mCurrentLoopIndex < mLoopCount) + else if(mStopBehavior == DevelImageVisual::StopBehavior::LAST_FRAME) { - if( finished ) - { - mCurrentFrameIndex = 0; // Back to the first frame - } + frameIndex = mFrameCount - 1; } else { - // This will stop timer - mActionStatus = DevelAnimatedImageVisual::Action::STOP; - return DisplayNextFrame(); + return false; // Do not draw already rendered scene twice. } } - - if( mFrameDelayContainer.Count() > 0 ) + else { - unsigned int delay = mFrameDelayContainer[mCurrentFrameIndex]; + 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(); + } + } - if( mFrameDelayTimer.GetInterval() != delay ) + unsigned int delay = mImageCache->GetFrameInterval(frameIndex); + if(delay > 0u) { - mFrameDelayTimer.SetInterval( delay ); + 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 ) + if(nextFrame) + { + textureSet = mImageCache->NextFrame(); + } + else + { + textureSet = mImageCache->Frame(frameIndex); + } + + continueTimer = (mActionStatus == DevelAnimatedImageVisual::Action::PLAY) ? true : false; + } + + if(textureSet) { - textureSet = mImageCache->Frame( mCurrentFrameIndex ); - if( textureSet ) + SetImageSize(textureSet); + if(mImpl->mRenderer) { - SetImageSize( textureSet ); - mImpl->mRenderer.SetTextures( textureSet ); + mImpl->mRenderer.SetTextures(textureSet); } } - return ( mActionStatus == DevelAnimatedImageVisual::Action::PLAY ) ? true : false; + return continueTimer; } +TextureSet AnimatedImageVisual::SetLoadingFailed() +{ + DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "ResourceReady(ResourceStatus::FAILED)\n"); + ResourceReady(Toolkit::Visual::ResourceStatus::FAILED); + + TextureSet textureSet = TextureSet::New(); + Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); + textureSet.SetTexture(0u, brokenImage); + + if(mFrameDelayTimer) + { + mFrameDelayTimer.Stop(); + mFrameDelayTimer.Reset(); + } + + SetImageSize(textureSet); + + return textureSet; +} } // namespace Internal