From a74518c907ed5b42ec396184b59062d3e098d889 Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Thu, 4 Feb 2021 19:36:06 +0900 Subject: [PATCH] (Vector) Show the broken image when loading is failed Change-Id: I3910b78c72fb4a81b0f33a7e211bb1dd717ca8f8 --- .../toolkit-vector-animation-renderer.cpp | 23 ++++++++-- .../utc-Dali-AnimatedVectorImageVisual.cpp | 39 ++++++++++++++++ .../animated-vector-image-visual.cpp | 45 +++++++++++++----- .../animated-vector-image-visual.h | 1 + .../vector-animation-task.cpp | 53 ++++++++++++---------- .../animated-vector-image/vector-animation-task.h | 16 ++++--- 6 files changed, 131 insertions(+), 46 deletions(-) diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp index b0075d2..18ce2ef 100755 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp @@ -35,8 +35,8 @@ class VectorAnimationRenderer: public Dali::BaseObject { public: - VectorAnimationRenderer( const std::string& url ) - : mUrl( url ), + VectorAnimationRenderer() + : mUrl(), mRenderer(), mWidth( 0 ), mHeight( 0 ), @@ -57,6 +57,16 @@ public: mCount--; } + bool Load(const std::string& url) + { + mUrl = url; + if(mUrl == "invalid.json") + { + return false; + } + return true; + } + void SetRenderer( Dali::Renderer renderer ) { mRenderer = renderer; @@ -187,9 +197,9 @@ inline const VectorAnimationRenderer& GetImplementation( const Dali::VectorAnima /********************************* PUBLIC CLASS *******************************/ /********************************************************************************/ -VectorAnimationRenderer VectorAnimationRenderer::New( const std::string& url ) +VectorAnimationRenderer VectorAnimationRenderer::New() { - Internal::Adaptor::VectorAnimationRenderer* animationRenderer = new Internal::Adaptor::VectorAnimationRenderer( url ); + Internal::Adaptor::VectorAnimationRenderer* animationRenderer = new Internal::Adaptor::VectorAnimationRenderer(); return VectorAnimationRenderer( animationRenderer ); } @@ -222,6 +232,11 @@ void VectorAnimationRenderer::Finalize() { } +bool VectorAnimationRenderer::Load(const std::string& url) +{ + return Internal::Adaptor::GetImplementation( *this ).Load(url); +} + void VectorAnimationRenderer::SetRenderer( Renderer renderer ) { Internal::Adaptor::GetImplementation( *this ).SetRenderer( renderer ); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp index 42a9e91..b692ebb 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp @@ -50,6 +50,7 @@ namespace { const char* TEST_VECTOR_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/insta_camera.json"; +const char* TEST_VECTOR_IMAGE_INVALID_FILE_NAME = "invalid.json"; bool gAnimationFinishedSignalFired = false; @@ -1491,3 +1492,41 @@ int UtcDaliAnimatedVectorImageVisualWindowVisibilityChanged(void) END_TEST; } + +int UtcDaliAnimatedVectorImageVisualInvalidFile(void) +{ + ToolkitTestApplication application; + tet_infoline("Request loading with invalid file - should draw broken image"); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + Property::Map propertyMap; + propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE) + .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_INVALID_FILE_NAME); + + Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + DummyControl actor = DummyControl::New(true); + DummyControlImpl& dummyImpl = static_cast< DummyControlImpl& >(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f)); + + application.GetScene().Add(actor); + + application.SendNotification(); + application.Render(); + + // Check resource status + Visual::ResourceStatus status = actor.GetVisualResourceStatus(DummyControl::Property::TEST_VISUAL); + DALI_TEST_EQUALS(status, Visual::ResourceStatus::FAILED, TEST_LOCATION); + + // The broken image should be shown. + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + + END_TEST; +} diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp index ee5b0f3..c6604ad 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp @@ -83,13 +83,14 @@ AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factory : Visual::Base(factoryCache, Visual::FittingMode::FILL, static_cast(Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE)), mUrl(imageUrl), mAnimationData(), - mVectorAnimationTask(new VectorAnimationTask(factoryCache, imageUrl.GetUrl())), + mVectorAnimationTask(new VectorAnimationTask(factoryCache)), mImageVisualShaderFactory(shaderFactory), mVisualSize(), mVisualScale(Vector2::ONE), mPlacementActor(), mPlayState(DevelImageVisual::PlayState::STOPPED), mEventCallback(nullptr), + mLoadFailed(false), mRendererAdded(false), mCoreShutdown(false), mRedrawInScalingDown(true) @@ -97,6 +98,11 @@ AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factory // the rasterized image is with pre-multiplied alpha format mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA; + if(!mVectorAnimationTask->Load(mUrl.GetUrl())) + { + mLoadFailed = true; + } + mVectorAnimationTask->UploadCompletedSignal().Connect(this, &AnimatedVectorImageVisual::OnUploadCompleted); mVectorAnimationTask->SetAnimationFinishedCallback(new EventThreadCallback(MakeCallback(this, &AnimatedVectorImageVisual::OnAnimationFinished))); @@ -310,21 +316,36 @@ void AnimatedVectorImageVisual::DoSetOnScene(Actor& actor) // Hold the weak handle of the placement actor and delay the adding of renderer until the rasterization is finished. mPlacementActor = actor; - mVectorAnimationTask->SetRenderer(mImpl->mRenderer); - - // Add property notification for scaling & size - mScaleNotification = actor.AddPropertyNotification(Actor::Property::WORLD_SCALE, StepCondition(0.1f, 1.0f)); - mScaleNotification.NotifySignal().Connect(this, &AnimatedVectorImageVisual::OnScaleNotification); + if(mLoadFailed) + { + TextureSet textureSet = TextureSet::New(); + mImpl->mRenderer.SetTextures(textureSet); - mSizeNotification = actor.AddPropertyNotification(Actor::Property::SIZE, StepCondition(3.0f)); - mSizeNotification.NotifySignal().Connect(this, &AnimatedVectorImageVisual::OnSizeNotification); + Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); + textureSet.SetTexture(0u, brokenImage); - DevelActor::VisibilityChangedSignal(actor).Connect(this, &AnimatedVectorImageVisual::OnControlVisibilityChanged); + actor.AddRenderer(mImpl->mRenderer); - Window window = DevelWindow::Get(actor); - if(window) + ResourceReady(Toolkit::Visual::ResourceStatus::FAILED); + } + else { - DevelWindow::VisibilityChangedSignal(window).Connect(this, &AnimatedVectorImageVisual::OnWindowVisibilityChanged); + mVectorAnimationTask->SetRenderer(mImpl->mRenderer); + + // Add property notification for scaling & size + mScaleNotification = actor.AddPropertyNotification(Actor::Property::WORLD_SCALE, StepCondition(0.1f, 1.0f)); + mScaleNotification.NotifySignal().Connect(this, &AnimatedVectorImageVisual::OnScaleNotification); + + mSizeNotification = actor.AddPropertyNotification(Actor::Property::SIZE, StepCondition(3.0f)); + mSizeNotification.NotifySignal().Connect(this, &AnimatedVectorImageVisual::OnSizeNotification); + + DevelActor::VisibilityChangedSignal(actor).Connect(this, &AnimatedVectorImageVisual::OnControlVisibilityChanged); + + Window window = DevelWindow::Get(actor); + if(window) + { + DevelWindow::VisibilityChangedSignal(window).Connect(this, &AnimatedVectorImageVisual::OnWindowVisibilityChanged); + } } DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::DoSetOnScene [%p]\n", this); diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h index 0270268..c809634 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h @@ -225,6 +225,7 @@ private: WeakHandle mPlacementActor; DevelImageVisual::PlayState::Type mPlayState; CallbackBase* mEventCallback; // Not owned + bool mLoadFailed; bool mRendererAdded; bool mCoreShutdown; bool mRedrawInScalingDown; diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp index c229a99..d9d6d5a 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp @@ -45,9 +45,9 @@ Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New(Debug::NoLogging, } // unnamed namespace -VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache, const std::string& url) -: mUrl(url), - mVectorRenderer(), +VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache) +: mUrl(), + mVectorRenderer(VectorAnimationRenderer::New()), mAnimationData(), mVectorAnimationThread(factoryCache.GetVectorAnimationManager().GetVectorAnimationThread()), mConditionalWait(), @@ -73,7 +73,6 @@ VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache, const mAnimationDataUpdated(false), mDestroyTask(false) { - Initialize(); } VectorAnimationTask::~VectorAnimationTask() @@ -96,6 +95,33 @@ void VectorAnimationTask::Finalize() mDestroyTask = true; } +bool VectorAnimationTask::Load(const std::string& url) +{ + mUrl = url; + + if(!mVectorRenderer.Load(mUrl)) + { + DALI_LOG_ERROR("VectorAnimationTask::Load: Load failed [%s]\n", mUrl.c_str()); + return false; + } + + mTotalFrame = mVectorRenderer.GetTotalFrameNumber(); + + mEndFrame = mTotalFrame - 1; + + mFrameRate = mVectorRenderer.GetFrameRate(); + mFrameDurationNanoSeconds = NANOSECONDS_PER_SECOND / mFrameRate; + + uint32_t width, height; + mVectorRenderer.GetDefaultSize(width, height); + + SetSize(width, height); + + DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Load: file = %s [%d frames, %f fps] [%p]\n", mUrl.c_str(), mTotalFrame, mFrameRate, this); + + return true; +} + void VectorAnimationTask::SetRenderer(Renderer renderer) { ConditionalWait::ScopedLock lock(mConditionalWait); @@ -343,25 +369,6 @@ VectorAnimationTask::UploadCompletedSignalType& VectorAnimationTask::UploadCompl return mVectorRenderer.UploadCompletedSignal(); } -void VectorAnimationTask::Initialize() -{ - mVectorRenderer = VectorAnimationRenderer::New(mUrl); - - mTotalFrame = mVectorRenderer.GetTotalFrameNumber(); - - mEndFrame = mTotalFrame - 1; - - mFrameRate = mVectorRenderer.GetFrameRate(); - mFrameDurationNanoSeconds = NANOSECONDS_PER_SECOND / mFrameRate; - - uint32_t width, height; - mVectorRenderer.GetDefaultSize(width, height); - - SetSize(width, height); - - DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Initialize: file = %s [%d frames, %f fps] [%p]\n", mUrl.c_str(), mTotalFrame, mFrameRate, this); -} - bool VectorAnimationTask::Rasterize() { bool stopped = false; diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h index 702a718..03b8a89 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h @@ -108,9 +108,8 @@ public: * @brief Constructor. * * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object - * @param[in] url The url of the vector animation file */ - VectorAnimationTask(VisualFactoryCache& factoryCache, const std::string& url); + VectorAnimationTask(VisualFactoryCache& factoryCache); /** * @brief Destructor. @@ -123,6 +122,14 @@ public: void Finalize(); /** + * @brief Loads the animation file. + * + * @param[in] url The url of the vector animation file + * @return True if loading success, false otherwise. + */ + bool Load(const std::string& url); + + /** * @brief Sets the renderer used to display the result image. * * @param[in] renderer The renderer used to display the result image @@ -198,11 +205,6 @@ public: private: /** - * @brief Initializes the vector renderer. - */ - void Initialize(); - - /** * @brief Play the vector animation. */ void PlayAnimation(); -- 2.7.4