[dali_2.3.22] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / svg / svg-visual.cpp
index 733141a..49d62ab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 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.
  */
 
 // CLASS HEADER
-#include "svg-visual.h"
+#include <dali-toolkit/internal/visuals/svg/svg-visual.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
+#include <dali-toolkit/internal/visuals/image-visual-shader-feature-builder.h>
 #include <dali-toolkit/internal/visuals/svg/svg-task.h>
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
@@ -70,7 +71,7 @@ SvgVisual::SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory&
   mDefaultWidth(0),
   mDefaultHeight(0),
   mPlacementActor(),
-  mRasterizedSize(Vector2::ZERO),
+  mRasterizedSize(-Vector2::ONE), ///< Let we don't use zero since visual size could be zero after trasnform
   mDesiredSize(size),
   mLoadFailed(false),
   mAttemptAtlasing(false)
@@ -81,6 +82,23 @@ SvgVisual::SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory&
 
 SvgVisual::~SvgVisual()
 {
+  if(Stage::IsInstalled())
+  {
+    if(mLoadingTask)
+    {
+      Dali::AsyncTaskManager::Get().RemoveTask(mLoadingTask);
+    }
+    if(mRasterizingTask)
+    {
+      Dali::AsyncTaskManager::Get().RemoveTask(mRasterizingTask);
+    }
+
+    if(mImageUrl.IsBufferResource())
+    {
+      TextureManager& textureManager = mFactoryCache.GetTextureManager();
+      textureManager.RemoveEncodedImageBuffer(mImageUrl.GetUrl());
+    }
+  }
 }
 
 void SvgVisual::OnInitialize()
@@ -93,11 +111,29 @@ void SvgVisual::OnInitialize()
   Vector2 dpi     = Stage::GetCurrent().GetDpi();
   float   meanDpi = (dpi.height + dpi.width) * 0.5f;
 
-  mLoadingTask = new SvgLoadingTask(mVectorRenderer, mImageUrl, meanDpi, MakeCallback(this, &SvgVisual::ApplyRasterizedImage));
+  EncodedImageBuffer encodedImageBuffer;
 
-  if(IsSynchronousLoadingRequired() && mImageUrl.IsLocalResource())
+  if(mImageUrl.IsBufferResource())
+  {
+    // Increase reference count of External Resources :
+    // EncodedImageBuffer.
+    // Reference count will be decreased at destructor of the visual.
+    TextureManager& textureManager = mFactoryCache.GetTextureManager();
+    textureManager.UseExternalResource(mImageUrl.GetUrl());
+
+    encodedImageBuffer = textureManager.GetEncodedImageBuffer(mImageUrl.GetUrl());
+  }
+
+  mLoadingTask = new SvgLoadingTask(mVectorRenderer, mImageUrl, encodedImageBuffer, meanDpi, MakeCallback(this, &SvgVisual::ApplyRasterizedImage));
+
+  if(IsSynchronousLoadingRequired() && (mImageUrl.IsLocalResource() || mImageUrl.IsBufferResource()))
   {
     mLoadingTask->Process();
+    if(!mLoadingTask->HasSucceeded())
+    {
+      mLoadFailed = true;
+    }
+    mLoadingTask.Reset(); // We don't need it anymore.
   }
   else
   {
@@ -218,11 +254,12 @@ void SvgVisual::DoSetOnScene(Actor& actor)
 
 void SvgVisual::DoSetOffScene(Actor& actor)
 {
-  // Remove loading & rasterizing task
-  Dali::AsyncTaskManager::Get().RemoveTask(mLoadingTask);
-  Dali::AsyncTaskManager::Get().RemoveTask(mRasterizingTask);
-  mLoadingTask.Reset();
-  mRasterizingTask.Reset();
+  // Remove rasterizing task
+  if(mRasterizingTask)
+  {
+    Dali::AsyncTaskManager::Get().RemoveTask(mRasterizingTask);
+    mRasterizingTask.Reset();
+  }
 
   actor.RemoveRenderer(mImpl->mRenderer);
   mPlacementActor.Reset();
@@ -292,15 +329,27 @@ void SvgVisual::AddRasterizationTask(const Vector2& size)
 {
   if(mImpl->mRenderer)
   {
+    // Remove previous task
+    if(mRasterizingTask)
+    {
+      Dali::AsyncTaskManager::Get().RemoveTask(mRasterizingTask);
+      mRasterizingTask.Reset();
+    }
+
     unsigned int width  = static_cast<unsigned int>(size.width);
     unsigned int height = static_cast<unsigned int>(size.height);
 
     mRasterizingTask = new SvgRasterizingTask(mVectorRenderer, width, height, MakeCallback(this, &SvgVisual::ApplyRasterizedImage));
 
+#ifdef TRACE_ENABLED
+    reinterpret_cast<SvgRasterizingTask*>(mRasterizingTask.Get())->SetUrl(mImageUrl);
+#endif
+
     if(IsSynchronousLoadingRequired() && mImageUrl.IsLocalResource())
     {
       mRasterizingTask->Process();
       ApplyRasterizedImage(mRasterizingTask);
+      mRasterizingTask.Reset(); // We don't need it anymore.
     }
     else
     {
@@ -311,6 +360,8 @@ void SvgVisual::AddRasterizationTask(const Vector2& size)
 
 void SvgVisual::ApplyRasterizedImage(SvgTaskPtr task)
 {
+  SvgVisualPtr self = this; // Keep reference until this API finished
+
   if(task->HasSucceeded())
   {
     PixelData rasterizedPixelData = task->GetPixelData();
@@ -319,6 +370,16 @@ void SvgVisual::ApplyRasterizedImage(SvgTaskPtr task)
       task->GetRenderer().GetDefaultSize(mDefaultWidth, mDefaultHeight);
     }
 
+    // We don't need to keep tasks anymore. reset now.
+    if(task == mLoadingTask)
+    {
+      mLoadingTask.Reset();
+    }
+    if(task == mRasterizingTask)
+    {
+      mRasterizingTask.Reset();
+    }
+
     // Rasterization success
     if(rasterizedPixelData && IsOnScene())
     {
@@ -391,6 +452,19 @@ void SvgVisual::ApplyRasterizedImage(SvgTaskPtr task)
   {
     mLoadFailed = true;
 
+    // Remove rasterizing task if we requested before.
+    if(mRasterizingTask)
+    {
+      Dali::AsyncTaskManager::Get().RemoveTask(mRasterizingTask);
+      mRasterizingTask.Reset();
+    }
+
+    // We don't need to keep tasks anymore. reset now.
+    if(task == mLoadingTask)
+    {
+      mLoadingTask.Reset();
+    }
+
     Actor actor = mPlacementActor.GetHandle();
     if(actor)
     {
@@ -449,7 +523,7 @@ Shader SvgVisual::GenerateShader() const
   {
     shader = mImageVisualShaderFactory.GetShader(
       mFactoryCache,
-      ImageVisualShaderFeature::FeatureBuilder()
+      ImageVisualShaderFeatureBuilder()
         .EnableTextureAtlas(mAttemptAtlasing)
         .EnableRoundedCorner(IsRoundedCornerRequired())
         .EnableBorderline(IsBorderlineRequired()));