Remove ResourceReady before rasterization in SvgVisual 56/273956/4
authorHeeyong Song <heeyong.song@samsung.com>
Tue, 19 Apr 2022 03:23:40 +0000 (12:23 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Mon, 2 May 2022 02:58:31 +0000 (02:58 +0000)
It will use a default size of the content file if the size is not set.

Change-Id: I5dbfe79146a461d412c39ab5dcf37fabd94b683c

automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.h
dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp
dali-toolkit/internal/visuals/svg/svg-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.h
dali-toolkit/internal/visuals/visual-event-observer.h

index b0365ff..cf276f4 100644 (file)
@@ -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.
 #include <dali/devel-api/adaptor-framework/vector-image-renderer.h>
 #include <dali/public-api/object/base-object.h>
 #include <dali/public-api/rendering/renderer.h>
+#include <sys/stat.h>
 #include <toolkit-application.h>
 #include <toolkit-event-thread-callback.h>
-#include <memory>
 #include <cstring>
-#include <sys/stat.h>
+#include <memory>
 
 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<Internal::Adaptor::VectorImageRenderer&>(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<const Internal::Adaptor::VectorImageRenderer&>(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<uint8_t>& 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
index 5694d9f..e16e93e 100644 (file)
@@ -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;
 
index b49f9d0..d4de79a 100644 (file)
@@ -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.
 #include <limits>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
 #include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/controls/control-wrapper-impl.h>
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
@@ -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<Dali::Accessibility::ActorAccessible*>(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<std::pair<Dali::Property::Index, Dali::Property::Map>>& sourceProperties,
                                       std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& 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;
index 2354a94..593ab7d 100644 (file)
@@ -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<std::pair<Dali::Property::Index, Dali::Property::Map>>& sourceProperties,
                          std::vector<std::pair<Dali::Property::Index, Dali::Property::Map>>& 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;
index aed445d..08e416e 100644 (file)
@@ -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<float>(mWidth) / static_cast<float>(defaultWidth);
-  float scaleY = static_cast<float>(mHeight) / static_cast<float>(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;
   }
 
index 9a47462..6851c75 100644 (file)
@@ -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<float>(rasterizedPixelData.GetWidth());
+    mRasterizedSize.y = static_cast<float>(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;
     }
   }
 
index c005691..2b1dbe1 100644 (file)
@@ -191,7 +191,7 @@ private:
   uint32_t                  mDefaultWidth;
   uint32_t                  mDefaultHeight;
   WeakHandle<Actor>         mPlacementActor;
-  Vector2                   mVisualSize;
+  Vector2                   mRasterizedSize;
   bool                      mLoadFailed;
   bool                      mAttemptAtlasing; ///< If true will attempt atlasing, otherwise create unique texture
 };
index 799962f..35a48fa 100644 (file)
@@ -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