From: Heeyong Song Date: Tue, 19 Apr 2022 03:23:40 +0000 (+0900) Subject: Remove ResourceReady before rasterization in SvgVisual X-Git-Tag: dali_2.1.21~2^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=df0ba815340cb09f10cb3e84358718310ef0bffb Remove ResourceReady before rasterization in SvgVisual It will use a default size of the content file if the size is not set. Change-Id: I5dbfe79146a461d412c39ab5dcf37fabd94b683c --- diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp index b0365ff..cf276f4 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -18,25 +18,21 @@ #include #include #include +#include #include #include -#include #include -#include +#include namespace Dali { - namespace Internal { - namespace Adaptor { - -class VectorImageRenderer: public Dali::BaseObject +class VectorImageRenderer : public Dali::BaseObject { public: - VectorImageRenderer() : mWidth(0), mHeight(0), @@ -61,43 +57,46 @@ public: return true; } - bool Rasterize(Dali::Devel::PixelBuffer& buffer, float scale) + Dali::Devel::PixelBuffer Rasterize(uint32_t width, uint32_t height) { - return mRasterizeSuccess; + if(mRasterizeSuccess) + { + Devel::PixelBuffer pixelBuffer = Devel::PixelBuffer::New(width, height, Dali::Pixel::RGBA8888); + return pixelBuffer; + } + return Dali::Devel::PixelBuffer(); } void GetDefaultSize(uint32_t& width, uint32_t& height) const { - width = 100; + width = 100; height = 100; } public: - uint32_t mWidth; uint32_t mHeight; bool mRasterizeSuccess; }; -inline VectorImageRenderer& GetImplementation( Dali::VectorImageRenderer& renderer ) +inline VectorImageRenderer& GetImplementation(Dali::VectorImageRenderer& renderer) { - DALI_ASSERT_ALWAYS( renderer && "VectorImageRenderer handle is empty." ); + DALI_ASSERT_ALWAYS(renderer && "VectorImageRenderer handle is empty."); BaseObject& handle = renderer.GetBaseObject(); - return static_cast< Internal::Adaptor::VectorImageRenderer& >( handle ); + return static_cast(handle); } -inline const VectorImageRenderer& GetImplementation( const Dali::VectorImageRenderer& renderer ) +inline const VectorImageRenderer& GetImplementation(const Dali::VectorImageRenderer& renderer) { - DALI_ASSERT_ALWAYS( renderer && "VectorImageRenderer handle is empty." ); + DALI_ASSERT_ALWAYS(renderer && "VectorImageRenderer handle is empty."); const BaseObject& handle = renderer.GetBaseObject(); - return static_cast< const Internal::Adaptor::VectorImageRenderer& >( handle ); + return static_cast(handle); } } // namespace Adaptor } // namespace Internal - /********************************************************************************/ /********************************* PUBLIC CLASS *******************************/ /********************************************************************************/ @@ -106,7 +105,7 @@ VectorImageRenderer VectorImageRenderer::New() { Internal::Adaptor::VectorImageRenderer* imageRenderer = new Internal::Adaptor::VectorImageRenderer(); - return VectorImageRenderer( imageRenderer ); + return VectorImageRenderer(imageRenderer); } VectorImageRenderer::VectorImageRenderer() @@ -117,8 +116,8 @@ VectorImageRenderer::~VectorImageRenderer() { } -VectorImageRenderer::VectorImageRenderer( Internal::Adaptor::VectorImageRenderer* internal ) -: BaseHandle( internal ) +VectorImageRenderer::VectorImageRenderer(Internal::Adaptor::VectorImageRenderer* internal) +: BaseHandle(internal) { } @@ -127,14 +126,14 @@ bool VectorImageRenderer::Load(const Vector& data, float dpi) return Internal::Adaptor::GetImplementation(*this).Load(data, dpi); } -bool VectorImageRenderer::Rasterize(Dali::Devel::PixelBuffer& buffer, float scale) +Dali::Devel::PixelBuffer VectorImageRenderer::Rasterize(uint32_t width, uint32_t height) { - return Internal::Adaptor::GetImplementation(*this).Rasterize(buffer, scale); + return Internal::Adaptor::GetImplementation(*this).Rasterize(width, height); } -void VectorImageRenderer::GetDefaultSize( uint32_t& width, uint32_t& height ) const +void VectorImageRenderer::GetDefaultSize(uint32_t& width, uint32_t& height) const { - Internal::Adaptor::GetImplementation( *this ).GetDefaultSize( width, height ); + Internal::Adaptor::GetImplementation(*this).GetDefaultSize(width, height); } } // namespace Dali diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index 5694d9f..e16e93e 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@ -2645,30 +2645,56 @@ int UtcDaliImageViewLoadRemoteSVG(void) tet_infoline("Test load from a remote server."); ToolkitTestApplication application; - Toolkit::ImageView imageView; - imageView = Toolkit::ImageView::New(); - imageView.SetImage("https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/check.svg"); - // Victor. Temporary (or permanent?) update as the url above seems not to work from time to time ... - // imageView.SetImage("https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/SVG_logo.svg/64px-SVG_logo.svg.png"); - imageView.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT); - imageView.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); - imageView.SetProperty(Actor::Property::SIZE, Vector2(300, 300)); - imageView.SetProperty(Actor::Property::POSITION, Vector3(150.0f, 150.0f, 0.0f)); - application.GetScene().Add(imageView); + { + Toolkit::ImageView imageView; + imageView = Toolkit::ImageView::New(); + imageView.SetImage("https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/check.svg"); + imageView.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT); + imageView.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + imageView.SetProperty(Actor::Property::SIZE, Vector2(300, 300)); + imageView.SetProperty(Actor::Property::POSITION, Vector3(150.0f, 150.0f, 0.0f)); - DALI_TEST_CHECK(imageView); + application.GetScene().Add(imageView); - DALI_TEST_EQUALS(imageView.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_CHECK(imageView); - application.SendNotification(); + DALI_TEST_EQUALS(imageView.GetRendererCount(), 0u, TEST_LOCATION); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + application.SendNotification(); - application.SendNotification(); - application.Render(); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION); + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION); + } + + // Without size set + { + Toolkit::ImageView imageView; + imageView = Toolkit::ImageView::New(); + imageView.SetImage("https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/check.svg"); + imageView.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT); + imageView.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + imageView.SetProperty(Actor::Property::POSITION, Vector3(150.0f, 150.0f, 0.0f)); + + application.GetScene().Add(imageView); + + DALI_TEST_CHECK(imageView); + + DALI_TEST_EQUALS(imageView.GetRendererCount(), 0u, TEST_LOCATION); + + application.SendNotification(); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION); + } END_TEST; } @@ -2791,6 +2817,10 @@ int UtcDaliImageViewSvgLoadingFailure(void) { ToolkitTestApplication application; + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + // Local svg file - invalid file path { gResourceReadySignalFired = false; @@ -2809,11 +2839,40 @@ int UtcDaliImageViewSvgLoadingFailure(void) DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); DALI_TEST_EQUALS(imageView.IsResourceReady(), true, TEST_LOCATION); DALI_TEST_EQUALS(imageView.GetVisualResourceStatus(ImageView::Property::IMAGE), Visual::ResourceStatus::FAILED, TEST_LOCATION); + + // Should be shown a broken image + DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + } + + // Local svg file - invalid file path without size set + { + gResourceReadySignalFired = false; + textureTrace.Reset(); + + ImageView imageView = ImageView::New(TEST_RESOURCE_DIR "/foo.svg"); + imageView.ResourceReadySignal().Connect(&ResourceReadySignal); + + DALI_TEST_EQUALS(imageView.IsResourceReady(), false, TEST_LOCATION); + + application.GetScene().Add(imageView); + + application.SendNotification(); + application.Render(16); + + DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); + DALI_TEST_EQUALS(imageView.IsResourceReady(), true, TEST_LOCATION); + DALI_TEST_EQUALS(imageView.GetVisualResourceStatus(ImageView::Property::IMAGE), Visual::ResourceStatus::FAILED, TEST_LOCATION); + + // Should be shown a broken image + DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); } // Local svg file - invalid file { gResourceReadySignalFired = false; + textureTrace.Reset(); ImageView imageView = ImageView::New(TEST_RESOURCE_DIR "/invalid.svg"); imageView.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); @@ -2829,11 +2888,16 @@ int UtcDaliImageViewSvgLoadingFailure(void) DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); DALI_TEST_EQUALS(imageView.IsResourceReady(), true, TEST_LOCATION); DALI_TEST_EQUALS(imageView.GetVisualResourceStatus(ImageView::Property::IMAGE), Visual::ResourceStatus::FAILED, TEST_LOCATION); + + // Should be shown a broken image + DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); } // Remote svg file { gResourceReadySignalFired = false; + textureTrace.Reset(); ImageView imageView = ImageView::New("https://bar.org/foobar.svg"); imageView.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); @@ -2854,6 +2918,39 @@ int UtcDaliImageViewSvgLoadingFailure(void) DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); DALI_TEST_EQUALS(imageView.IsResourceReady(), true, TEST_LOCATION); DALI_TEST_EQUALS(imageView.GetVisualResourceStatus(ImageView::Property::IMAGE), Visual::ResourceStatus::FAILED, TEST_LOCATION); + + // Should be shown a broken image + DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + } + + // Remote svg file without size set + { + gResourceReadySignalFired = false; + textureTrace.Reset(); + + ImageView imageView = ImageView::New("https://bar.org/foobar.svg"); + imageView.ResourceReadySignal().Connect(&ResourceReadySignal); + + DALI_TEST_EQUALS(imageView.IsResourceReady(), false, TEST_LOCATION); + + application.GetScene().Add(imageView); + + application.SendNotification(); + + // loading started, this waits for the loader thread + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(16); + + DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); + DALI_TEST_EQUALS(imageView.IsResourceReady(), true, TEST_LOCATION); + DALI_TEST_EQUALS(imageView.GetVisualResourceStatus(ImageView::Property::IMAGE), Visual::ResourceStatus::FAILED, TEST_LOCATION); + + // Should be shown a broken image + DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); } END_TEST; @@ -2865,7 +2962,11 @@ int UtcDaliImageViewSvgRasterizationFailure(void) gResourceReadySignalFired = false; - ImageView imageView = ImageView::New(TEST_RESOURCE_DIR "/svg1.svg"); + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + ImageView imageView = ImageView::New(TEST_RESOURCE_DIR "/invalid1.svg"); imageView.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); imageView.ResourceReadySignal().Connect(&ResourceReadySignal); @@ -2883,27 +2984,12 @@ int UtcDaliImageViewSvgRasterizationFailure(void) DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); DALI_TEST_EQUALS(imageView.IsResourceReady(), true, TEST_LOCATION); - DALI_TEST_EQUALS(imageView.GetVisualResourceStatus(ImageView::Property::IMAGE), Visual::ResourceStatus::READY, TEST_LOCATION); - - // Reset flag - gResourceReadySignalFired = false; - - // Change size - imageView.SetProperty(Actor::Property::SIZE, Vector2(0.f, 0.f)); - - application.SendNotification(); - - // rasterization started, this waits for the rasterize thread - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - - application.SendNotification(); - application.Render(16); - - DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); - DALI_TEST_EQUALS(imageView.IsResourceReady(), true, TEST_LOCATION); - // Fail to rasterize because the size is 0. DALI_TEST_EQUALS(imageView.GetVisualResourceStatus(ImageView::Property::IMAGE), Visual::ResourceStatus::FAILED, TEST_LOCATION); + // Should be shown a broken image + DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + END_TEST; } @@ -2927,6 +3013,7 @@ int UtcDaliImageViewTVGLoading(void) } END_TEST; } + int UtcDaliImageViewImageLoadFailure01(void) { ToolkitTestApplication application; @@ -3088,7 +3175,7 @@ void OnResourceReadySignal01(Control control) else if(control.GetVisualResourceStatus(ImageView::Property::IMAGE) == Visual::ResourceStatus::FAILED) { // Make the resource ready immediately - control[ImageView::Property::IMAGE] = TEST_RESOURCE_DIR "/svg1.svg"; + control[ImageView::Property::IMAGE] = gImage_600_RGB; } } @@ -3222,6 +3309,15 @@ int UtcDaliImageViewSetImageOnResourceReadySignal01(void) DALI_TEST_EQUALS(imageView.IsResourceReady(), true, TEST_LOCATION); + // Create a new ImageView to cache the image + ImageView imageView1 = ImageView::New(gImage_600_RGB); + application.GetScene().Add(imageView1); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + // Reset count gResourceReadySignalCounter = 0; diff --git a/dali-toolkit/internal/controls/control/control-data-impl.cpp b/dali-toolkit/internal/controls/control/control-data-impl.cpp index b49f9d0..d4de79a 100644 --- a/dali-toolkit/internal/controls/control/control-data-impl.cpp +++ b/dali-toolkit/internal/controls/control/control-data-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -36,11 +36,11 @@ #include // INTERNAL INCLUDES -#include #include #include #include #include +#include #include #include #include @@ -448,7 +448,7 @@ static bool IsShowingGeometryOnScreen(Dali::Rect<> rect) Dali::Accessibility::Accessible* ExternalAccessibleGetter(Dali::Actor actor) { auto control = Toolkit::Control::DownCast(actor); - if (!control) + if(!control) { return nullptr; } @@ -565,7 +565,7 @@ void Control::Impl::CheckHighlightedObjectGeometry() auto accessible = GetAccessibleObject(); auto lastPosition = accessible->GetLastPosition(); auto accessibleRect = accessible->GetExtents(Dali::Accessibility::CoordinateType::WINDOW); - auto rect = GetShowingGeometry(accessibleRect, accessible); + auto rect = GetShowingGeometry(accessibleRect, accessible); switch(mAccessibilityLastScreenRelativeMoveType) { @@ -626,9 +626,9 @@ void Control::Impl::RegisterAccessibilityPositionPropertyNotification() mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE; // recalculate mAccessibilityLastScreenRelativeMoveType accordingly to the initial position CheckHighlightedObjectGeometry(); - mAccessibilityPositionNotification = mControlImpl.Self().AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f)); + mAccessibilityPositionNotification = mControlImpl.Self().AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f)); mAccessibilityPositionNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); - mAccessibilityPositionNotification.NotifySignal().Connect(this, [this](PropertyNotification&){ CheckHighlightedObjectGeometry(); }); + mAccessibilityPositionNotification.NotifySignal().Connect(this, [this](PropertyNotification&) { CheckHighlightedObjectGeometry(); }); mIsAccessibilityPositionPropertyNotificationSet = true; } @@ -967,6 +967,11 @@ void Control::Impl::NotifyVisualEvent(Visual::Base& object, Property::Index sign } } +void Control::Impl::RelayoutRequest(Visual::Base& object) +{ + mControlImpl.RelayoutRequest(); +} + bool Control::Impl::IsResourceReady() const { // Iterate through and check all the enabled visuals are ready @@ -1364,7 +1369,7 @@ void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const auto* accessible = controlImpl.GetAccessibleObject(); auto* parent = dynamic_cast(accessible->GetParent()); - if (parent) + if(parent) { parent->OnChildrenChanged(); } @@ -1993,7 +1998,8 @@ Dali::Property Control::Impl::GetVisualProperty(Dali::Property::Index index, Dal void Control::Impl::CreateTransitions(std::vector>& sourceProperties, std::vector>& destinationProperties, - Dali::Toolkit::Control source, Dali::Toolkit::Control destination) + Dali::Toolkit::Control source, + Dali::Toolkit::Control destination) { // Retrieves background properties to be transitioned. Dali::Property::Map backgroundSourcePropertyMap, backgroundDestinationPropertyMap; diff --git a/dali-toolkit/internal/controls/control/control-data-impl.h b/dali-toolkit/internal/controls/control/control-data-impl.h index 2354a94..593ab7d 100644 --- a/dali-toolkit/internal/controls/control/control-data-impl.h +++ b/dali-toolkit/internal/controls/control/control-data-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_CONTROL_DATA_IMPL_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -141,6 +141,12 @@ public: void NotifyVisualEvent(Visual::Base& object, Property::Index signalId) override; /** + * @brief Called when the visual needs relayout request. + * @param[in] object The visual who requests relayout + */ + void RelayoutRequest(Visual::Base& object) override; + + /** * @copydoc Dali::Toolkit::DevelControl::RegisterVisual() */ void RegisterVisual(Property::Index index, Toolkit::Visual::Base& visual); @@ -412,7 +418,8 @@ public: */ void CreateTransitions(std::vector>& sourceProperties, std::vector>& destinationProperties, - Dali::Toolkit::Control source, Dali::Toolkit::Control destination); + Dali::Toolkit::Control source, + Dali::Toolkit::Control destination); /** * @brief Update visual properties. @@ -496,12 +503,12 @@ public: std::string mSubStateName; Property::Map mAccessibilityAttributes; - int mLeftFocusableActorId; ///< Actor ID of Left focusable control. - int mRightFocusableActorId; ///< Actor ID of Right focusable control. - int mUpFocusableActorId; ///< Actor ID of Up focusable control. - int mDownFocusableActorId; ///< Actor ID of Down focusable control. - int mClockwiseFocusableActorId; ///< Actor ID of Clockwise focusable control. - int mCounterClockwiseFocusableActorId; ///< Actor ID of Counter clockwise focusable control. + int mLeftFocusableActorId; ///< Actor ID of Left focusable control. + int mRightFocusableActorId; ///< Actor ID of Right focusable control. + int mUpFocusableActorId; ///< Actor ID of Up focusable control. + int mDownFocusableActorId; ///< Actor ID of Down focusable control. + int mClockwiseFocusableActorId; ///< Actor ID of Clockwise focusable control. + int mCounterClockwiseFocusableActorId; ///< Actor ID of Counter clockwise focusable control. RegisteredVisualContainer mVisuals; ///< Stores visuals needed by the control, non trivial type so std::vector used. std::string mStyleName; diff --git a/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp b/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp index aed445d..08e416e 100644 --- a/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -77,24 +77,10 @@ void RasterizingTask::Load() void RasterizingTask::Rasterize() { - if(mWidth <= 0u || mHeight <= 0u) + Devel::PixelBuffer pixelBuffer = mVectorRenderer.Rasterize(mWidth, mHeight); + if(!pixelBuffer) { - DALI_LOG_ERROR("RasterizingTask::Rasterize: Size is zero!\n"); - return; - } - - Devel::PixelBuffer pixelBuffer = Devel::PixelBuffer::New(mWidth, mHeight, Dali::Pixel::RGBA8888); - - uint32_t defaultWidth, defaultHeight; - mVectorRenderer.GetDefaultSize(defaultWidth, defaultHeight); - - float scaleX = static_cast(mWidth) / static_cast(defaultWidth); - float scaleY = static_cast(mHeight) / static_cast(defaultHeight); - float scale = scaleX < scaleY ? scaleX : scaleY; - - if(!mVectorRenderer.Rasterize(pixelBuffer, scale)) - { - DALI_LOG_ERROR("RasterizingTask::Rasterize: Rasterize is failed! [%s]\n", mUrl.GetUrl().c_str()); + DALI_LOG_ERROR("Rasterize is failed! [%s]\n", mUrl.GetUrl().c_str()); return; } diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.cpp b/dali-toolkit/internal/visuals/svg/svg-visual.cpp index 9a47462..6851c75 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-visual.cpp @@ -72,7 +72,7 @@ SvgVisual::SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& mDefaultWidth(0), mDefaultHeight(0), mPlacementActor(), - mVisualSize(Vector2::ZERO), + mRasterizedSize(Vector2::ZERO), mLoadFailed(false), mAttemptAtlasing(false) { @@ -169,8 +169,11 @@ void SvgVisual::DoSetOnScene(Actor& actor) } else { - // SVG visual needs it's size set before it can be rasterized hence set ResourceReady once on stage - ResourceReady(Toolkit::Visual::ResourceStatus::READY); + if(mImpl->mEventObserver) + { + // SVG visual needs it's size set before it can be rasterized hence request relayout once on stage + mImpl->mEventObserver->RelayoutRequest(*this); + } } } @@ -182,13 +185,31 @@ void SvgVisual::DoSetOffScene(Actor& actor) mPlacementActor.Reset(); // Reset the visual size to zero so that when adding the actor back to stage the SVG rasterization is forced - mVisualSize = Vector2::ZERO; + mRasterizedSize = Vector2::ZERO; } void SvgVisual::GetNaturalSize(Vector2& naturalSize) { - naturalSize.x = mDefaultWidth; - naturalSize.y = mDefaultHeight; + if(mLoadFailed && mImpl->mRenderer) + { + // Load failed, use broken image size + auto textureSet = mImpl->mRenderer.GetTextures(); + if(textureSet && textureSet.GetTextureCount()) + { + auto texture = textureSet.GetTexture(0); + if(texture) + { + naturalSize.x = texture.GetWidth(); + naturalSize.y = texture.GetHeight(); + return; + } + } + } + else + { + naturalSize.x = mDefaultWidth; + naturalSize.y = mDefaultHeight; + } } void SvgVisual::DoCreatePropertyMap(Property::Map& map) const @@ -273,6 +294,14 @@ void SvgVisual::ApplyRasterizedImage(VectorImageRenderer vectorRenderer, PixelDa { if(isLoaded && rasterizedPixelData && IsOnScene()) { + if(mDefaultWidth == 0 || mDefaultHeight == 0) + { + mVectorRenderer.GetDefaultSize(mDefaultWidth, mDefaultHeight); + } + + mRasterizedSize.x = static_cast(rasterizedPixelData.GetWidth()); + mRasterizedSize.y = static_cast(rasterizedPixelData.GetHeight()); + TextureSet currentTextureSet = mImpl->mRenderer.GetTextures(); if(mImpl->mFlags & Impl::IS_ATLASING_APPLIED) { @@ -336,6 +365,8 @@ void SvgVisual::ApplyRasterizedImage(VectorImageRenderer vectorRenderer, PixelDa } else if(!isLoaded || !rasterizedPixelData) { + mLoadFailed = true; + Actor actor = mPlacementActor.GetHandle(); if(actor) { @@ -355,10 +386,10 @@ void SvgVisual::OnSetTransform() if(IsOnScene() && !mLoadFailed) { - if(visualSize != mVisualSize) + if(visualSize != mRasterizedSize || mDefaultWidth == 0 || mDefaultHeight == 0) { AddRasterizationTask(visualSize); - mVisualSize = visualSize; + mRasterizedSize = visualSize; } } diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.h b/dali-toolkit/internal/visuals/svg/svg-visual.h index c005691..2b1dbe1 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.h +++ b/dali-toolkit/internal/visuals/svg/svg-visual.h @@ -191,7 +191,7 @@ private: uint32_t mDefaultWidth; uint32_t mDefaultHeight; WeakHandle mPlacementActor; - Vector2 mVisualSize; + Vector2 mRasterizedSize; bool mLoadFailed; bool mAttemptAtlasing; ///< If true will attempt atlasing, otherwise create unique texture }; diff --git a/dali-toolkit/internal/visuals/visual-event-observer.h b/dali-toolkit/internal/visuals/visual-event-observer.h index 799962f..35a48fa 100644 --- a/dali-toolkit/internal/visuals/visual-event-observer.h +++ b/dali-toolkit/internal/visuals/visual-event-observer.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_TOOLKIT_VISUAL_EVENT_OBSERVER_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -49,6 +49,12 @@ public: */ virtual void NotifyVisualEvent(Visual::Base& object, Property::Index signalId) = 0; + /** + * Requests a relayout to the observer. + * @param[in] object The connection owner + */ + virtual void RelayoutRequest(Visual::Base& object) = 0; + protected: /** * constructor