X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Fanimated-image%2Fanimated-image-visual.cpp;h=382d52be83d775fec9eed00de954c6133db4773b;hb=HEAD;hp=f4a83dc4190afeda4928550cec45219ec8b9f44e;hpb=1e96141086594b45635f880aa31163db803bb9c6;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git 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 f4a83dc..d94e0b5 100644 --- 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) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 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. @@ -19,8 +19,8 @@ #include // EXTERNAL INCLUDES -#include #include +#include #include #include #include @@ -190,6 +190,22 @@ void AnimatedImageVisual::InitializeAnimatedImage(const VisualUrl& imageUrl) { mImageUrl = imageUrl; mAnimatedImageLoading = AnimatedImageLoading::New(imageUrl.GetUrl(), imageUrl.IsLocalResource()); + + // If we fail to load the animated image, we will try to load as a normal image. + if(!mAnimatedImageLoading) + { + mImageUrls = new ImageCache::UrlList(); + mImageUrls->reserve(SINGLE_IMAGE_COUNT); + + for(unsigned int i = 0; i < SINGLE_IMAGE_COUNT; ++i) + { + ImageCache::UrlStore urlStore; + urlStore.mTextureId = TextureManager::INVALID_TEXTURE_ID; + urlStore.mUrl = imageUrl; + mImageUrls->push_back(urlStore); + } + mFrameCount = SINGLE_IMAGE_COUNT; + } } void AnimatedImageVisual::CreateImageCache() @@ -219,14 +235,14 @@ void AnimatedImageVisual::CreateImageCache() } } - if(!mImageCache) + if(DALI_UNLIKELY(!mImageCache)) { DALI_LOG_ERROR("mImageCache is null\n"); } } AnimatedImageVisual::AnimatedImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, ImageDimensions desiredSize) -: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::ANIMATED_IMAGE), +: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, Toolkit::Visual::ANIMATED_IMAGE), mFrameDelayTimer(), mPlacementActor(), mImageVisualShaderFactory(shaderFactory), @@ -251,7 +267,7 @@ AnimatedImageVisual::AnimatedImageVisual(VisualFactoryCache& factoryCache, Image mActionStatus(DevelAnimatedImageVisual::Action::PLAY), mWrapModeU(WrapMode::DEFAULT), mWrapModeV(WrapMode::DEFAULT), - mFittingMode(FittingMode::SCALE_TO_FILL), + mFittingMode(FittingMode::VISUAL_FITTING), mSamplingMode(SamplingMode::BOX_THEN_LINEAR), mStopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME), mStartFirstFrame(false), @@ -266,7 +282,10 @@ AnimatedImageVisual::~AnimatedImageVisual() // If this is animated image, clear cache. Else if this is single frame image, this is affected be release policy. if(mFrameCount > SINGLE_IMAGE_COUNT || mReleasePolicy != Toolkit::ImageVisual::ReleasePolicy::NEVER) { - mImageCache->ClearCache(); + if(DALI_LIKELY(mImageCache)) + { + mImageCache->ClearCache(); + } } delete mImageCache; delete mImageUrls; @@ -276,6 +295,26 @@ void AnimatedImageVisual::GetNaturalSize(Vector2& naturalSize) { if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0) { + if(mImpl->mRenderer) + { + auto textureSet = mImpl->mRenderer.GetTextures(); + if(textureSet && textureSet.GetTextureCount()) + { + auto texture = textureSet.GetTexture(0); + if(texture) + { + Dali::Vector2 textureSize; + textureSize.x = texture.GetWidth(); + textureSize.y = texture.GetHeight(); + if(textureSize != Vector2::ZERO) + { + naturalSize = textureSize; + return; + } + } + } + } + naturalSize.x = mDesiredSize.GetWidth(); naturalSize.y = mDesiredSize.GetHeight(); return; @@ -297,7 +336,7 @@ void AnimatedImageVisual::GetNaturalSize(Vector2& naturalSize) } } - if(mImageUrl.IsValid()) + if(mImageUrl.IsValid() && mAnimatedImageLoading) { mImageSize = mAnimatedImageLoading.GetImageSize(); } @@ -344,7 +383,24 @@ void AnimatedImageVisual::DoCreatePropertyMap(Property::Map& map) const 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((mAnimatedImageLoading) ? mAnimatedImageLoading.GetImageCount() : mImageCache->GetTotalFrameCount()) : -1); + + // This returns -1 until the loading is finished. + auto frameCount = int32_t(mFrameCount); + if(mImageCache && frameCount == 0) + { + frameCount = mImageCache->GetTotalFrameCount(); + + if(frameCount <= int32_t(SINGLE_IMAGE_COUNT) && mAnimatedImageLoading && mAnimatedImageLoading.HasLoadingSucceeded()) + { + frameCount = int32_t(mAnimatedImageLoading.GetImageCount()); + } + else + { + frameCount = -1; + } + } + + map.Insert(Toolkit::DevelImageVisual::Property::TOTAL_FRAME_NUMBER, static_cast(frameCount)); map.Insert(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mStopBehavior); @@ -368,11 +424,8 @@ void AnimatedImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const { map.Clear(); map.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::ANIMATED_IMAGE); - if(mImageUrl.IsValid()) - { - map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth()); - map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight()); - } + map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth()); + map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight()); } void AnimatedImageVisual::OnDoAction(const Dali::Property::Index actionId, const Dali::Property::Value& attributes) @@ -611,7 +664,7 @@ void AnimatedImageVisual::DoSetProperty(Property::Index index, if(value.Get(frameDelay)) { mFrameDelay = frameDelay; - if(mImageCache) + if(DALI_LIKELY(mImageCache)) { mImageCache->SetInterval(static_cast(mFrameDelay)); } @@ -766,7 +819,7 @@ void AnimatedImageVisual::DoSetOnScene(Actor& actor) mPlacementActor = actor; PrepareTextureSet(); - DevelActor::VisibilityChangedSignal(actor).Connect(this, &AnimatedImageVisual::OnControlVisibilityChanged); + actor.InheritedVisibilityChangedSignal().Connect(this, &AnimatedImageVisual::OnControlInheritedVisibilityChanged); Window window = DevelWindow::Get(actor); if(window) @@ -789,7 +842,10 @@ void AnimatedImageVisual::DoSetOffScene(Actor& actor) actor.RemoveRenderer(mImpl->mRenderer); if(mReleasePolicy == Toolkit::ImageVisual::ReleasePolicy::DETACHED) { - mImageCache->ClearCache(); // If INVALID_TEXTURE_ID then removal will be attempted on atlas + if(DALI_LIKELY(mImageCache)) + { + mImageCache->ClearCache(); // If INVALID_TEXTURE_ID then removal will be attempted on atlas + } mImpl->mResourceStatus = Toolkit::Visual::ResourceStatus::PREPARING; TextureSet textureSet = TextureSet::New(); @@ -801,7 +857,7 @@ void AnimatedImageVisual::DoSetOffScene(Actor& actor) mCurrentFrameIndex = FIRST_FRAME_INDEX; mCurrentLoopIndex = FIRST_LOOP; - DevelActor::VisibilityChangedSignal(actor).Disconnect(this, &AnimatedImageVisual::OnControlVisibilityChanged); + actor.InheritedVisibilityChangedSignal().Disconnect(this, &AnimatedImageVisual::OnControlInheritedVisibilityChanged); Window window = mPlacementWindow.GetHandle(); if(window) @@ -919,10 +975,15 @@ void AnimatedImageVisual::StartFirstFrame(TextureSet& textureSet, uint32_t first void AnimatedImageVisual::PrepareTextureSet() { TextureSet textureSet; - if(mImageCache) + if(DALI_LIKELY(mImageCache)) { textureSet = mImageCache->FirstFrame(); } + else + { + // preMultiplied should be false because broken image don't premultiply alpha on load + FrameReady(TextureSet(), 0, false); + } // Check whether synchronous loading is true or false for the first frame. if(textureSet) @@ -973,7 +1034,10 @@ void AnimatedImageVisual::FrameReady(TextureSet textureSet, uint32_t interval, b if(mStartFirstFrame) { - mFrameCount = mImageCache->GetTotalFrameCount(); + if(DALI_LIKELY(mImageCache)) + { + mFrameCount = mImageCache->GetTotalFrameCount(); + } StartFirstFrame(textureSet, interval); } else @@ -995,7 +1059,7 @@ bool AnimatedImageVisual::DisplayNextFrame() TextureSet textureSet; bool continueTimer = false; - if(mImageCache) + if(DALI_LIKELY(mImageCache)) { uint32_t frameIndex = mImageCache->GetCurrentFrameIndex(); @@ -1077,8 +1141,13 @@ TextureSet AnimatedImageVisual::SetLoadingFailed() { imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); } - mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); - TextureSet textureSet = mImpl->mRenderer.GetTextures(); + + TextureSet textureSet; + if(DALI_LIKELY(mImpl->mRenderer)) + { + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); + textureSet = mImpl->mRenderer.GetTextures(); + } if(mFrameDelayTimer) { @@ -1117,13 +1186,13 @@ void AnimatedImageVisual::CheckMaskTexture() } } -void AnimatedImageVisual::OnControlVisibilityChanged(Actor actor, bool visible, DevelActor::VisibilityChange::Type type) +void AnimatedImageVisual::OnControlInheritedVisibilityChanged(Actor actor, bool visible) { if(!visible && mActionStatus != DevelAnimatedImageVisual::Action::STOP) { mActionStatus = DevelAnimatedImageVisual::Action::STOP; DisplayNextFrame(); - DALI_LOG_INFO(gAnimImgLogFilter, Debug::Verbose, "AnimatedImageVisual::OnControlVisibilityChanged: invisibile. Pause animation [%p]\n", this); + DALI_LOG_INFO(gAnimImgLogFilter, Debug::Verbose, "AnimatedImageVisual::OnControlInheritedVisibilityChanged: invisibile. Pause animation [%p]\n", this); } }