CanvasRenderer: Add Drawable::SetClipPath() Api
[platform/core/uifw/dali-adaptor.git] / dali / internal / canvas-renderer / tizen / canvas-renderer-impl-tizen.cpp
index 95135bf..422ef2d 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>
 
@@ -52,8 +53,10 @@ CanvasRendererTizen* CanvasRendererTizen::New(const Vector2& viewBox)
 
 CanvasRendererTizen::CanvasRendererTizen(const Vector2& viewBox)
 : mPixelBuffer(nullptr),
+#ifdef THORVG_SUPPORT
   mTvgCanvas(nullptr),
   mTvgRoot(nullptr),
+#endif
   mSize(0, 0),
   mViewBox(0, 0),
   mChanged(false)
@@ -63,25 +66,17 @@ CanvasRendererTizen::CanvasRendererTizen(const Vector2& viewBox)
 
 CanvasRendererTizen::~CanvasRendererTizen()
 {
-  for(DrawableVectorIterator it    = mDrawables.begin(),
-                             endIt = mDrawables.end();
-      it != endIt;
-      ++it)
-  {
-    Dali::CanvasRenderer::Drawable drawable = (*it).GetHandle();
-    if(DALI_UNLIKELY(!drawable))
-    {
-      continue;
-    }
-    Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable);
-    drawableImpl.SetObject(nullptr);
-  }
+#ifdef THORVG_SUPPORT
+  mDrawables.clear();
+
   //Terminate ThorVG Engine
   tvg::Initializer::term(tvg::CanvasEngine::Sw);
+#endif
 }
 
 void CanvasRendererTizen::Initialize(const Vector2& viewBox)
 {
+#ifdef THORVG_SUPPORT
   if(tvg::Initializer::init(tvg::CanvasEngine::Sw, 0 /*threads*/) != tvg::Result::Success)
   {
     DALI_LOG_ERROR("ThorVG engine initialize failed\n");
@@ -95,32 +90,21 @@ void CanvasRendererTizen::Initialize(const Vector2& viewBox)
   }
 
   MakeTargetBuffer(mSize);
-
-  auto scene = tvg::Scene::gen();
-  mTvgRoot   = scene.get();
-  mTvgCanvas->push(move(scene));
+#endif
 }
 
 bool CanvasRendererTizen::Commit()
 {
+#ifdef THORVG_SUPPORT
   bool changed = false;
 
-  for(DrawableVectorIterator it    = mDrawables.begin(),
-                             endIt = mDrawables.end();
-      it != endIt;
-      ++it)
+  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;
       drawableImpl.SetChanged(false);
-      break;
     }
   }
 
@@ -143,12 +127,32 @@ bool CanvasRendererTizen::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)
@@ -156,7 +160,13 @@ bool CanvasRendererTizen::Commit()
     DALI_LOG_ERROR("ThorVG Draw fail [%p]\n", this);
     return false;
   }
+
+  mTvgCanvas->sync();
+
   return true;
+#else
+  return false;
+#endif
 }
 
 Devel::PixelBuffer CanvasRendererTizen::GetPixelBuffer()
@@ -166,48 +176,28 @@ Devel::PixelBuffer CanvasRendererTizen::GetPixelBuffer()
 
 bool CanvasRendererTizen::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
 {
-  bool exist = false;
-  for(DrawableVectorIterator it    = mDrawables.begin(),
-                             endIt = mDrawables.end();
-      it != endIt;
-      ++it)
-  {
-    if((*it) == drawable)
-    {
-      exist = true;
-      break;
-    }
-  }
-  if(exist)
-  {
-    DALI_LOG_ERROR("Already added [%p]\n", this);
-    return false;
-  }
-
+#ifdef THORVG_SUPPORT
   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.SetDrawableAdded(true);
+  drawableImpl.SetAdded(true);
   mDrawables.push_back(drawable);
   mChanged = true;
 
   return true;
+#else
+  return false;
+#endif
 }
 
 bool CanvasRendererTizen::SetSize(const Vector2& size)
@@ -235,6 +225,7 @@ const Vector2& CanvasRendererTizen::GetSize()
 
 void CanvasRendererTizen::MakeTargetBuffer(const Vector2& size)
 {
+#ifdef THORVG_SUPPORT
   mPixelBuffer = Devel::PixelBuffer::New(size.width, size.height, Dali::Pixel::RGBA8888);
 
   unsigned char* pBuffer;
@@ -246,10 +237,69 @@ void CanvasRendererTizen::MakeTargetBuffer(const Vector2& size)
     return;
   }
 
-  mTvgCanvas->sync();
-
   mTvgCanvas->target(reinterpret_cast<uint32_t*>(pBuffer), size.width, size.width, size.height, tvg::SwCanvas::ABGR8888);
+#endif
+}
+
+#ifdef THORVG_SUPPORT
+void CanvasRendererTizen::PushDrawableToGroup(Dali::CanvasRenderer::Drawable& drawable, tvg::Scene* parent)
+{
+  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));
+    }
+  }
+
+  Dali::CanvasRenderer::Drawable compositeDrawable = drawableImpl.GetCompositionDrawable();
+  if(DALI_UNLIKELY(compositeDrawable))
+  {
+    Internal::Adaptor::Drawable& compositeDrawableImpl = Dali::GetImplementation(compositeDrawable);
+    tvg::Paint*                  tvgCompositeObject    = static_cast<tvg::Paint*>(compositeDrawableImpl.GetObject());
+    if(tvgCompositeObject)
+    {
+      tvg::Paint*     tvgDuplicatedCompositeObject = tvgCompositeObject->duplicate();
+      Drawable::Types type                         = compositeDrawableImpl.GetType();
+
+      if(type == Drawable::Types::DRAWABLE_GROUP)
+      {
+        Dali::CanvasRenderer::DrawableGroup& compositeGroup             = static_cast<Dali::CanvasRenderer::DrawableGroup&>(compositeDrawable);
+        Internal::Adaptor::DrawableGroup&    compositeDrawableGroupImpl = Dali::GetImplementation(compositeGroup);
+        DrawableGroup::DrawableVector        compositeDrawables         = compositeDrawableGroupImpl.GetDrawables();
+        for(auto& it : compositeDrawables)
+        {
+          PushDrawableToGroup(it, static_cast<tvg::Scene*>(tvgDuplicatedCompositeObject));
+        }
+      }
+
+      if(tvgDuplicatedObject->composite(std::move(std::unique_ptr<tvg::Paint>(tvgDuplicatedCompositeObject)), static_cast<tvg::CompositeMethod>(drawableImpl.GetCompositionType())) != tvg::Result::Success)
+      {
+        DALI_LOG_ERROR("Tvg composite fail [%p]\n", this);
+        return;
+      }
+    }
+  }
+
+  if(parent->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