CanvasRenderer: Refactoring tvgObject management
[platform/core/uifw/dali-adaptor.git] / dali / internal / canvas-renderer / ubuntu / canvas-renderer-impl-ubuntu.cpp
index 43705e6..8efe447 100644 (file)
@@ -24,6 +24,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#include <dali/internal/canvas-renderer/common/drawable-group-impl.h>
 #include <dali/internal/canvas-renderer/common/drawable-impl.h>
 #include <dali/internal/imaging/common/pixel-buffer-impl.h>
 
@@ -66,16 +67,8 @@ CanvasRendererUbuntu::CanvasRendererUbuntu(const Vector2& viewBox)
 CanvasRendererUbuntu::~CanvasRendererUbuntu()
 {
 #ifdef THORVG_SUPPORT
-  for(auto& it : mDrawables)
-  {
-    Dali::CanvasRenderer::Drawable drawable = it.GetHandle();
-    if(DALI_UNLIKELY(!drawable))
-    {
-      continue;
-    }
-    Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable);
-    drawableImpl.SetObject(nullptr);
-  }
+  mDrawables.clear();
+
   //Terminate ThorVG Engine
   tvg::Initializer::term(tvg::CanvasEngine::Sw);
 #endif
@@ -97,10 +90,6 @@ void CanvasRendererUbuntu::Initialize(const Vector2& viewBox)
   }
 
   MakeTargetBuffer(mSize);
-
-  auto scene = tvg::Scene::gen();
-  mTvgRoot   = scene.get();
-  mTvgCanvas->push(move(scene));
 #endif
 }
 
@@ -111,12 +100,7 @@ bool CanvasRendererUbuntu::Commit()
 
   for(auto& it : mDrawables)
   {
-    Dali::CanvasRenderer::Drawable drawable = it.GetHandle();
-    if(DALI_UNLIKELY(!drawable))
-    {
-      continue;
-    }
-    Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable);
+    Internal::Adaptor::Drawable& drawableImpl = GetImplementation(it);
     if(drawableImpl.GetChanged())
     {
       changed = true;
@@ -143,12 +127,32 @@ bool CanvasRendererUbuntu::Commit()
     return false;
   }
 
+  if(mTvgCanvas->clear() != tvg::Result::Success)
+  {
+    DALI_LOG_ERROR("ThorVG canvas clear fail [%p]\n", this);
+    return false;
+  }
+
+  auto scene = tvg::Scene::gen();
+  mTvgRoot   = scene.get();
+  for(auto& it : mDrawables)
+  {
+    PushDrawableToGroup(it, mTvgRoot);
+  }
+
+  if(mTvgCanvas->push(move(scene)) != tvg::Result::Success)
+  {
+    DALI_LOG_ERROR("ThorVG canvas push fail [%p]\n", this);
+    return false;
+  }
+
   if(mViewBox != mSize)
   {
     auto scaleX = mSize.width / mViewBox.width;
     auto scaleY = mSize.height / mViewBox.height;
     mTvgRoot->scale(scaleX < scaleY ? scaleX : scaleY);
   }
+
   mTvgCanvas->update(mTvgRoot);
 
   if(mTvgCanvas->draw() != tvg::Result::Success)
@@ -173,34 +177,19 @@ Devel::PixelBuffer CanvasRendererUbuntu::GetPixelBuffer()
 bool CanvasRendererUbuntu::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
 {
 #ifdef THORVG_SUPPORT
-  for(auto& it : mDrawables)
-  {
-    if(it.GetHandle() == drawable)
-    {
-      DALI_LOG_ERROR("Already added [%p]\n", this);
-      return false;
-    }
-  }
-
   Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable);
-  tvg::Paint*                  pDrawable    = static_cast<tvg::Paint*>(drawableImpl.GetObject());
-  if(!pDrawable)
+  if(drawableImpl.IsAdded())
   {
-    DALI_LOG_ERROR("Invalid drawable object [%p]\n", this);
+    DALI_LOG_ERROR("Already added [%p][%p]\n", this, &drawable);
     return false;
   }
+
   if(mSize.width < 1.0f || mSize.height < 1.0f)
   {
     DALI_LOG_ERROR("Size is zero [%p]\n", this);
     return false;
   }
 
-  if(mTvgRoot->push(std::unique_ptr<tvg::Paint>(pDrawable)) != tvg::Result::Success)
-  {
-    DALI_LOG_ERROR("Tvg push fail [%p]\n", this);
-    return false;
-  }
-
   drawableImpl.SetAdded(true);
   mDrawables.push_back(drawable);
   mChanged = true;
@@ -252,6 +241,37 @@ void CanvasRendererUbuntu::MakeTargetBuffer(const Vector2& size)
 #endif
 }
 
+#ifdef THORVG_SUPPORT
+void CanvasRendererUbuntu::PushDrawableToGroup(Dali::CanvasRenderer::Drawable& drawable, tvg::Scene* group)
+{
+  Internal::Adaptor::Drawable& drawableImpl        = Dali::GetImplementation(drawable);
+  tvg::Paint*                  tvgDuplicatedObject = static_cast<tvg::Paint*>(drawableImpl.GetObject())->duplicate();
+  if(!tvgDuplicatedObject)
+  {
+    DALI_LOG_ERROR("Invalid drawable object [%p]\n", this);
+    return;
+  }
+  Drawable::Types type = drawableImpl.GetType();
+
+  if(type == Drawable::Types::DRAWABLE_GROUP)
+  {
+    Dali::CanvasRenderer::DrawableGroup& group             = static_cast<Dali::CanvasRenderer::DrawableGroup&>(drawable);
+    Internal::Adaptor::DrawableGroup&    drawableGroupImpl = Dali::GetImplementation(group);
+    DrawableGroup::DrawableVector        drawables         = drawableGroupImpl.GetDrawables();
+    for(auto& it : drawables)
+    {
+      PushDrawableToGroup(it, static_cast<tvg::Scene*>(tvgDuplicatedObject));
+    }
+  }
+
+  if(group->push(std::move(std::unique_ptr<tvg::Paint>(tvgDuplicatedObject))) != tvg::Result::Success)
+  {
+    DALI_LOG_ERROR("Tvg push fail [%p]\n", this);
+    return;
+  }
+}
+#endif
+
 } // namespace Adaptor
 
 } // namespace Internal