CanvasRenderer: Separates Commit() method 76/260876/18
authorJunsuChoi <jsuya.choi@samsung.com>
Tue, 6 Jul 2021 07:10:34 +0000 (16:10 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Mon, 26 Jul 2021 07:30:24 +0000 (16:30 +0900)
Separates the check whether changed, Make object tree, and drawing,
which were worked together in Commit, into individual functions.
These are each called in the appropriate thread from toolkit.

Change-Id: Iafe4e94d7b2eb6a73e7db52b204a7476c5e563a4

dali/devel-api/adaptor-framework/canvas-renderer.cpp
dali/devel-api/adaptor-framework/canvas-renderer.h
dali/internal/canvas-renderer/common/canvas-renderer-impl.cpp
dali/internal/canvas-renderer/common/canvas-renderer-impl.h
dali/internal/canvas-renderer/generic/canvas-renderer-impl-generic.cpp
dali/internal/canvas-renderer/generic/canvas-renderer-impl-generic.h
dali/internal/canvas-renderer/tizen/canvas-renderer-impl-tizen.cpp
dali/internal/canvas-renderer/tizen/canvas-renderer-impl-tizen.h
dali/internal/canvas-renderer/ubuntu/canvas-renderer-impl-ubuntu.cpp
dali/internal/canvas-renderer/ubuntu/canvas-renderer-impl-ubuntu.h

index 329afa2..e0fb777 100644 (file)
@@ -58,6 +58,16 @@ bool CanvasRenderer::AddDrawable(Drawable& drawable)
   return GetImplementation(*this).AddDrawable(drawable);
 }
 
+bool CanvasRenderer::IsCanvasChanged() const
+{
+  return GetImplementation(*this).IsCanvasChanged();
+}
+
+bool CanvasRenderer::Rasterize()
+{
+  return GetImplementation(*this).Rasterize();
+}
+
 bool CanvasRenderer::SetSize(const Vector2& size)
 {
   return GetImplementation(*this).SetSize(size);
index 3d866b8..cae69df 100644 (file)
@@ -88,7 +88,8 @@ public:
 
 public:
   /**
-   * @brief Draw inner canvas the contexts added to the CanvasRenderer.
+   * @brief Prepare for drawing drawables added to CanvasRenderer on inner canvas.
+   * @return Returns True when it's successful. False otherwise.
    */
   bool Commit();
 
@@ -108,6 +109,18 @@ public:
   Devel::PixelBuffer GetPixelBuffer();
 
   /**
+   * @brief Draw drawables added to CanvasRenderer to inner buffer.
+   * @return Returns True when it's successful. False otherwise.
+   */
+  bool Rasterize();
+
+  /**
+   * @brief Returns whether the drawables added to the Canvas are changed.
+   * @return Returns True when drawables added to the Canvas are changed, False otherwise.
+   */
+  bool IsCanvasChanged() const;
+
+  /**
    * @brief This is the size of the buffer in the Canvas.
    * @param[in] size The size of canvas buffer.
    * @return Returns True when it's successful. False otherwise.
index 47e37b3..6ebeb90 100644 (file)
@@ -49,6 +49,16 @@ bool CanvasRenderer::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
   return false;
 }
 
+bool CanvasRenderer::IsCanvasChanged() const
+{
+  return false;
+}
+
+bool CanvasRenderer::Rasterize()
+{
+  return false;
+}
+
 bool CanvasRenderer::SetSize(const Vector2& size)
 {
   return false;
index 84b49c0..222b9a3 100644 (file)
@@ -64,6 +64,16 @@ public:
   virtual bool AddDrawable(Dali::CanvasRenderer::Drawable& drawable);
 
   /**
+   * @copydoc Dali::CanvasRenderer::IsCanvasChanged()
+   */
+  virtual bool IsCanvasChanged() const;
+
+  /**
+   * @copydoc Dali::CanvasRenderer::Rasterize()
+   */
+  virtual bool Rasterize();
+
+  /**
    * @copydoc Dali::CanvasRenderer::SetSize()
    */
   virtual bool SetSize(const Vector2& size);
index 8caf21b..5119b39 100644 (file)
@@ -72,6 +72,16 @@ bool CanvasRendererGeneric::AddDrawable(Dali::CanvasRenderer::Drawable& drawable
   return false;
 }
 
+bool CanvasRendererGeneric::IsCanvasChanged() const
+{
+  return false;
+}
+
+bool CanvasRendererGeneric::Rasterize()
+{
+  return false;
+}
+
 bool CanvasRendererGeneric::SetSize(const Vector2& size)
 {
   return false;
index 9946149..dd290a4 100644 (file)
@@ -62,6 +62,16 @@ public:
   bool AddDrawable(Dali::CanvasRenderer::Drawable& drawable) override;
 
   /**
+   * @copydoc Dali::CanvasRenderer::IsCanvasChanged()
+   */
+  virtual bool IsCanvasChanged() const;
+
+  /**
+   * @copydoc Dali::CanvasRenderer::Rasterize()
+   */
+  virtual bool Rasterize();
+
+  /**
    * @copydoc Dali::CanvasRenderer::SetSize()
    */
   bool SetSize(const Vector2& size) override;
index 422ef2d..b38122e 100644 (file)
@@ -96,15 +96,22 @@ void CanvasRendererTizen::Initialize(const Vector2& viewBox)
 bool CanvasRendererTizen::Commit()
 {
 #ifdef THORVG_SUPPORT
+  Mutex::ScopedLock lock(mMutex);
+
+  if(mSize.width < 1.0f || mSize.height < 1.0f)
+  {
+    DALI_LOG_ERROR("Size is zero [%p]\n", this);
+    return false;
+  }
+
   bool changed = false;
 
   for(auto& it : mDrawables)
   {
-    Internal::Adaptor::Drawable& drawableImpl = GetImplementation(it);
-    if(drawableImpl.GetChanged())
+    if(HaveDrawablesChanged(it))
     {
+      UpdateDrawablesChanged(it, false);
       changed = true;
-      drawableImpl.SetChanged(false);
     }
   }
 
@@ -114,19 +121,13 @@ bool CanvasRendererTizen::Commit()
   }
   else
   {
-    if(!mPixelBuffer.GetBuffer())
+    if(!mPixelBuffer || !mPixelBuffer.GetBuffer())
     {
       MakeTargetBuffer(mSize);
       mChanged = false;
     }
   }
 
-  if(mSize.width < 1.0f || mSize.height < 1.0f)
-  {
-    DALI_LOG_ERROR("Size is zero [%p]\n", this);
-    return false;
-  }
-
   if(mTvgCanvas->clear() != tvg::Result::Success)
   {
     DALI_LOG_ERROR("ThorVG canvas clear fail [%p]\n", this);
@@ -140,29 +141,19 @@ bool CanvasRendererTizen::Commit()
     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)
+  if(mViewBox != mSize && mViewBox.width > 0 && mViewBox.height > 0)
   {
     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)
+  if(mTvgCanvas->push(move(scene)) != tvg::Result::Success)
   {
-    DALI_LOG_ERROR("ThorVG Draw fail [%p]\n", this);
+    DALI_LOG_ERROR("ThorVG canvas push fail [%p]\n", this);
     return false;
   }
 
-  mTvgCanvas->sync();
-
   return true;
 #else
   return false;
@@ -184,15 +175,91 @@ bool CanvasRendererTizen::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
     return false;
   }
 
-  if(mSize.width < 1.0f || mSize.height < 1.0f)
+  drawableImpl.SetAdded(true);
+  mDrawables.push_back(drawable);
+  mChanged = true;
+
+  return true;
+#else
+  return false;
+#endif
+}
+
+#ifdef THORVG_SUPPORT
+bool CanvasRendererTizen::HaveDrawablesChanged(const Dali::CanvasRenderer::Drawable& drawable) const
+{
+  const Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable);
+  if(drawableImpl.GetChanged())
   {
-    DALI_LOG_ERROR("Size is zero [%p]\n", this);
+    return true;
+  }
+
+  if(drawableImpl.GetType() == Drawable::Types::DRAWABLE_GROUP)
+  {
+    const Dali::CanvasRenderer::DrawableGroup& group             = static_cast<const Dali::CanvasRenderer::DrawableGroup&>(drawable);
+    const Internal::Adaptor::DrawableGroup&    drawableGroupImpl = Dali::GetImplementation(group);
+    DrawableGroup::DrawableVector              drawables         = drawableGroupImpl.GetDrawables();
+    for(auto& it : drawables)
+    {
+      if(HaveDrawablesChanged(it))
+      {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+void CanvasRendererTizen::UpdateDrawablesChanged(Dali::CanvasRenderer::Drawable& drawable, bool changed)
+{
+  Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable);
+  drawableImpl.SetChanged(changed);
+
+  if(drawableImpl.GetType() == 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)
+    {
+      UpdateDrawablesChanged(it, changed);
+    }
+  }
+}
+#endif
+
+bool CanvasRendererTizen::IsCanvasChanged() const
+{
+#ifdef THORVG_SUPPORT
+  if(mChanged)
+  {
+    return true;
+  }
+
+  for(auto& it : mDrawables)
+  {
+    if(HaveDrawablesChanged(it))
+    {
+      return true;
+    }
+  }
+#endif
+  return false;
+}
+
+bool CanvasRendererTizen::Rasterize()
+{
+#ifdef THORVG_SUPPORT
+  Mutex::ScopedLock lock(mMutex);
+
+  if(mTvgCanvas->draw() != tvg::Result::Success)
+  {
+    DALI_LOG_ERROR("ThorVG Draw fail [%p]\n", this);
     return false;
   }
 
-  drawableImpl.SetAdded(true);
-  mDrawables.push_back(drawable);
-  mChanged = true;
+  mTvgCanvas->sync();
 
   return true;
 #else
@@ -209,12 +276,10 @@ bool CanvasRendererTizen::SetSize(const Vector2& size)
 
   if(size != mSize)
   {
-    mSize = size;
-    MakeTargetBuffer(size);
+    mSize    = size;
+    mChanged = true;
   }
 
-  mChanged = true;
-
   return true;
 }
 
index 13edf48..5d136a7 100644 (file)
 #ifdef THORVG_SUPPORT
 #include <thorvg.h>
 #endif
+#include <dali/devel-api/threading/mutex.h>
 #include <dali/public-api/object/weak-handle.h>
 
 // INTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/canvas-renderer-drawable.h>
 #include <dali/devel-api/adaptor-framework/canvas-renderer.h>
 #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/canvas-renderer-impl.h>
+#include <dali/internal/canvas-renderer/common/drawable-group-impl.h>
 
 namespace Dali
 {
@@ -66,6 +67,16 @@ public:
   bool AddDrawable(Dali::CanvasRenderer::Drawable& drawable) override;
 
   /**
+   * @copydoc Dali::CanvasRenderer::IsCanvasChanged()
+   */
+  bool IsCanvasChanged() const override;
+
+  /**
+   * @copydoc Dali::CanvasRenderer::Rasterize()
+   */
+  bool Rasterize() override;
+
+  /**
    * @copydoc Dali::CanvasRenderer::SetSize()
    */
   bool SetSize(const Vector2& size) override;
@@ -106,6 +117,22 @@ private:
 
 #ifdef THORVG_SUPPORT
   /**
+   * @brief Get drawables changed status.
+   * If drawable is a type that can have child drawables, it is called recursively.
+   * @param[in] drawable The drawable object.
+   * @return Returns whether drawables have changed.
+   */
+  bool HaveDrawablesChanged(const Dali::CanvasRenderer::Drawable& drawable) const;
+
+  /**
+   * @brief Update drawables changed status.
+   * If drawable is a type that can have child drawables, it is called recursively.
+   * @param[in] drawable The drawable object.
+   * @param[in] changed The state of changed.
+   */
+  void UpdateDrawablesChanged(Dali::CanvasRenderer::Drawable& drawable, bool changed);
+
+  /**
    * @brief Push drawable object to parent.
    * If drawable is a type that can have child drawables, it is called recursively.
    * @param[in] drawable The drawable object.
@@ -116,6 +143,7 @@ private:
 
 private:
   Devel::PixelBuffer mPixelBuffer;
+  Dali::Mutex        mMutex;
 
 #ifdef THORVG_SUPPORT
   std::unique_ptr<tvg::SwCanvas> mTvgCanvas;
index f1d553d..96babe2 100644 (file)
@@ -96,15 +96,22 @@ void CanvasRendererUbuntu::Initialize(const Vector2& viewBox)
 bool CanvasRendererUbuntu::Commit()
 {
 #ifdef THORVG_SUPPORT
+  Mutex::ScopedLock lock(mMutex);
+
+  if(mSize.width < 1.0f || mSize.height < 1.0f)
+  {
+    DALI_LOG_ERROR("Size is zero [%p]\n", this);
+    return false;
+  }
+
   bool changed = false;
 
   for(auto& it : mDrawables)
   {
-    Internal::Adaptor::Drawable& drawableImpl = GetImplementation(it);
-    if(drawableImpl.GetChanged())
+    if(HaveDrawablesChanged(it))
     {
+      UpdateDrawablesChanged(it, false);
       changed = true;
-      drawableImpl.SetChanged(false);
     }
   }
 
@@ -114,19 +121,13 @@ bool CanvasRendererUbuntu::Commit()
   }
   else
   {
-    if(!mPixelBuffer.GetBuffer())
+    if(!mPixelBuffer || !mPixelBuffer.GetBuffer())
     {
       MakeTargetBuffer(mSize);
       mChanged = false;
     }
   }
 
-  if(mSize.width < 1.0f || mSize.height < 1.0f)
-  {
-    DALI_LOG_ERROR("Size is zero [%p]\n", this);
-    return false;
-  }
-
   if(mTvgCanvas->clear() != tvg::Result::Success)
   {
     DALI_LOG_ERROR("ThorVG canvas clear fail [%p]\n", this);
@@ -140,29 +141,19 @@ bool CanvasRendererUbuntu::Commit()
     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)
+  if(mViewBox != mSize && mViewBox.width != 0 && mViewBox.height != 0)
   {
     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)
+  if(mTvgCanvas->push(move(scene)) != tvg::Result::Success)
   {
-    DALI_LOG_ERROR("ThorVG Draw fail [%p]\n", this);
+    DALI_LOG_ERROR("ThorVG canvas push fail [%p]\n", this);
     return false;
   }
 
-  mTvgCanvas->sync();
-
   return true;
 #else
   return false;
@@ -184,15 +175,91 @@ bool CanvasRendererUbuntu::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
     return false;
   }
 
-  if(mSize.width < 1.0f || mSize.height < 1.0f)
+  drawableImpl.SetAdded(true);
+  mDrawables.push_back(drawable);
+  mChanged = true;
+
+  return true;
+#else
+  return false;
+#endif
+}
+
+#ifdef THORVG_SUPPORT
+bool CanvasRendererUbuntu::HaveDrawablesChanged(const Dali::CanvasRenderer::Drawable& drawable) const
+{
+  const Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable);
+  if(drawableImpl.GetChanged())
   {
-    DALI_LOG_ERROR("Size is zero [%p]\n", this);
+    return true;
+  }
+
+  if(drawableImpl.GetType() == Drawable::Types::DRAWABLE_GROUP)
+  {
+    const Dali::CanvasRenderer::DrawableGroup& group             = static_cast<const Dali::CanvasRenderer::DrawableGroup&>(drawable);
+    const Internal::Adaptor::DrawableGroup&    drawableGroupImpl = Dali::GetImplementation(group);
+    DrawableGroup::DrawableVector              drawables         = drawableGroupImpl.GetDrawables();
+    for(auto& it : drawables)
+    {
+      if(HaveDrawablesChanged(it))
+      {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+void CanvasRendererUbuntu::UpdateDrawablesChanged(Dali::CanvasRenderer::Drawable& drawable, bool changed)
+{
+  Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable);
+  drawableImpl.SetChanged(changed);
+
+  if(drawableImpl.GetType() == 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)
+    {
+      UpdateDrawablesChanged(it, changed);
+    }
+  }
+}
+#endif
+
+bool CanvasRendererUbuntu::IsCanvasChanged() const
+{
+#ifdef THORVG_SUPPORT
+  if(mChanged)
+  {
+    return true;
+  }
+
+  for(auto& it : mDrawables)
+  {
+    if(HaveDrawablesChanged(it))
+    {
+      return true;
+    }
+  }
+#endif
+  return false;
+}
+
+bool CanvasRendererUbuntu::Rasterize()
+{
+#ifdef THORVG_SUPPORT
+  Mutex::ScopedLock lock(mMutex);
+
+  if(mTvgCanvas->draw() != tvg::Result::Success)
+  {
+    DALI_LOG_ERROR("ThorVG Draw fail [%p]\n", this);
     return false;
   }
 
-  drawableImpl.SetAdded(true);
-  mDrawables.push_back(drawable);
-  mChanged = true;
+  mTvgCanvas->sync();
 
   return true;
 #else
@@ -209,12 +276,10 @@ bool CanvasRendererUbuntu::SetSize(const Vector2& size)
 
   if(size != mSize)
   {
-    mSize = size;
-    MakeTargetBuffer(size);
+    mSize    = size;
+    mChanged = true;
   }
 
-  mChanged = true;
-
   return true;
 }
 
index 2c91ab8..bfcd6a7 100644 (file)
 #ifdef THORVG_SUPPORT
 #include <thorvg.h>
 #endif
+#include <dali/devel-api/threading/mutex.h>
 #include <dali/public-api/object/weak-handle.h>
 
 // INTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/canvas-renderer-drawable.h>
 #include <dali/devel-api/adaptor-framework/canvas-renderer.h>
 #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/canvas-renderer-impl.h>
+#include <dali/internal/canvas-renderer/common/drawable-group-impl.h>
 
 namespace Dali
 {
@@ -66,6 +67,16 @@ public:
   bool AddDrawable(Dali::CanvasRenderer::Drawable& drawable) override;
 
   /**
+   * @copydoc Dali::CanvasRenderer::IsCanvasChanged()
+   */
+  bool IsCanvasChanged() const override;
+
+  /**
+   * @copydoc Dali::CanvasRenderer::Rasterize()
+   */
+  bool Rasterize() override;
+
+  /**
    * @copydoc Dali::CanvasRenderer::SetSize()
    */
   bool SetSize(const Vector2& size) override;
@@ -106,6 +117,22 @@ private:
 
 #ifdef THORVG_SUPPORT
   /**
+   * @brief Get drawables changed status.
+   * If drawable is a type that can have child drawables, it is called recursively.
+   * @param[in] drawable The drawable object.
+   * @return Returns whether drawables have changed.
+   */
+  bool HaveDrawablesChanged(const Dali::CanvasRenderer::Drawable& drawable) const;
+
+  /**
+   * @brief Update drawables changed status.
+   * If drawable is a type that can have child drawables, it is called recursively.
+   * @param[in] drawable The drawable object.
+   * @param[in] changed The state of changed.
+   */
+  void UpdateDrawablesChanged(Dali::CanvasRenderer::Drawable& drawable, bool changed);
+
+  /**
    * @brief Push drawable object to parent.
    * If drawable is a type that can have child drawables, it is called recursively.
    * @param[in] drawable The drawable object.
@@ -116,6 +143,7 @@ private:
 
 private:
   Devel::PixelBuffer mPixelBuffer;
+  Dali::Mutex        mMutex;
 
 #ifdef THORVG_SUPPORT
   std::unique_ptr<tvg::SwCanvas> mTvgCanvas;