From 9f4a8de2538be6d5a204dad3312eca3ea7e5d9a4 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 1 Feb 2024 17:15:13 +0900 Subject: [PATCH] renderer: destroy engines safely. Introduced a reference count to destroy it safely. --- src/renderer/tvgCanvas.h | 7 +++---- src/renderer/tvgPaint.cpp | 2 +- src/renderer/tvgPaint.h | 9 +++++---- src/renderer/tvgRender.h | 16 ++++++++++++++++ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/renderer/tvgCanvas.h b/src/renderer/tvgCanvas.h index 6754c0a9..2d87a7e0 100644 --- a/src/renderer/tvgCanvas.h +++ b/src/renderer/tvgCanvas.h @@ -33,8 +33,9 @@ struct Canvas::Impl bool refresh = false; //if all paints should be updated by force. bool drawing = false; //on drawing condition? - Impl(RenderMethod* pRenderer):renderer(pRenderer) + Impl(RenderMethod* pRenderer) : renderer(pRenderer) { + renderer->ref(); } ~Impl() @@ -47,9 +48,7 @@ struct Canvas::Impl clearPaints(); - if (renderer) { - if ((--renderer->refCnt) == 0) delete(renderer); - } + if (renderer && (renderer->unref() == 0)) delete(renderer); } void clearPaints() diff --git a/src/renderer/tvgPaint.cpp b/src/renderer/tvgPaint.cpp index 6d0bc9d5..ca8bf592 100644 --- a/src/renderer/tvgPaint.cpp +++ b/src/renderer/tvgPaint.cpp @@ -223,7 +223,7 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pT { if (this->renderer != renderer) { if (this->renderer) TVGERR("RENDERER", "paint's renderer has been changed!"); - ++renderer->refCnt; + renderer->ref(); this->renderer = renderer; } diff --git a/src/renderer/tvgPaint.h b/src/renderer/tvgPaint.h index 351f9e91..39bc2491 100644 --- a/src/renderer/tvgPaint.h +++ b/src/renderer/tvgPaint.h @@ -51,12 +51,12 @@ namespace tvg RenderTransform* rTransform = nullptr; Composite* compData = nullptr; RenderMethod* renderer = nullptr; - BlendMethod blendMethod = BlendMethod::Normal; //uint8_t + BlendMethod blendMethod = BlendMethod::Normal; //uint8_t uint8_t renderFlag = RenderUpdateFlag::None; uint8_t ctxFlag = ContextFlag::Invalid; uint8_t id; uint8_t opacity = 255; - uint8_t refCnt = 0; + uint8_t refCnt = 0; //reference count Impl(Paint* pnt) : paint(pnt) {} @@ -67,18 +67,19 @@ namespace tvg free(compData); } delete(rTransform); + if (renderer && (renderer->unref() == 0)) delete(renderer); } uint8_t ref() { if (refCnt == 255) TVGERR("RENDERER", "Corrupted reference count!"); - return (++refCnt); + return ++refCnt; } uint8_t unref() { if (refCnt == 0) TVGERR("RENDERER", "Corrupted reference count!"); - return (--refCnt); + return --refCnt; } bool transform(const Matrix& m) diff --git a/src/renderer/tvgRender.h b/src/renderer/tvgRender.h index 490818d3..fc573496 100644 --- a/src/renderer/tvgRender.h +++ b/src/renderer/tvgRender.h @@ -261,7 +261,23 @@ struct RenderShape class RenderMethod { +private: + uint32_t refCnt = 0; //reference count + Key key; + public: + uint32_t ref() + { + ScopedLock lock(key); + return (++refCnt); + } + + uint32_t unref() + { + ScopedLock lock(key); + return (--refCnt); + } + virtual ~RenderMethod() {} virtual RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0; virtual RenderData prepare(const Array& scene, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) = 0;