From 7057dc594d0c40a3640e0eb7000202ebbd90a27f Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 11 Aug 2023 13:48:41 +0900 Subject: [PATCH] renderer: enhance stability introduce a paint reference count to prevent any duplicated resource removal. --- src/lib/tvgAnimation.cpp | 29 +++++++++++++++++++++-------- src/lib/tvgCanvasImpl.h | 2 +- src/lib/tvgPaint.h | 13 +++++++++++++ src/lib/tvgPictureImpl.h | 3 +-- src/lib/tvgRender.h | 6 +++--- src/lib/tvgSceneImpl.h | 2 +- 6 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/lib/tvgAnimation.cpp b/src/lib/tvgAnimation.cpp index f43cfe6c..4e8c8568 100644 --- a/src/lib/tvgAnimation.cpp +++ b/src/lib/tvgAnimation.cpp @@ -23,6 +23,7 @@ //#include "tvgAnimationImpl.h" #include "tvgCommon.h" #include "tvgFrameModule.h" +#include "tvgPaint.h" #include "tvgPictureImpl.h" /************************************************************************/ @@ -31,7 +32,20 @@ struct Animation::Impl { - Picture picture; + Picture* picture = nullptr; + + Impl() + { + picture = Picture::gen().release(); + static_cast(picture)->pImpl->ref(); + } + + ~Impl() + { + if (static_cast(picture)->pImpl->unref() == 0) { + delete(picture); + } + } }; /************************************************************************/ @@ -40,19 +54,18 @@ struct Animation::Impl Animation::~Animation() { - //FIXME: free pImpl + delete(pImpl); } Animation::Animation() : pImpl(new Impl) { - pImpl->picture.pImpl->animated = true; } Result Animation::frame(uint32_t no) noexcept { - auto loader = pImpl->picture.pImpl->loader.get(); + auto loader = pImpl->picture->pImpl->loader.get(); if (!loader) return Result::InsufficientCondition; if (!loader->animatable()) return Result::NonSupport; @@ -64,13 +77,13 @@ Result Animation::frame(uint32_t no) noexcept Picture* Animation::picture() const noexcept { - return &pImpl->picture; + return pImpl->picture; } uint32_t Animation::curFrame() const noexcept { - auto loader = pImpl->picture.pImpl->loader.get(); + auto loader = pImpl->picture->pImpl->loader.get(); if (!loader) return 0; if (!loader->animatable()) return 0; @@ -81,7 +94,7 @@ uint32_t Animation::curFrame() const noexcept uint32_t Animation::totalFrame() const noexcept { - auto loader = pImpl->picture.pImpl->loader.get(); + auto loader = pImpl->picture->pImpl->loader.get(); if (!loader) return 0; if (!loader->animatable()) return 0; @@ -92,7 +105,7 @@ uint32_t Animation::totalFrame() const noexcept float Animation::duration() const noexcept { - auto loader = pImpl->picture.pImpl->loader.get(); + auto loader = pImpl->picture->pImpl->loader.get(); if (!loader) return 0; if (!loader->animatable()) return 0; diff --git a/src/lib/tvgCanvasImpl.h b/src/lib/tvgCanvasImpl.h index 42a2976c..fe21858e 100644 --- a/src/lib/tvgCanvasImpl.h +++ b/src/lib/tvgCanvasImpl.h @@ -67,7 +67,7 @@ struct Canvas::Impl if (free) { for (auto paint : paints) { if (paint->pImpl->dispose(*renderer)) { - delete(paint); + if (paint->pImpl->unref() == 0) delete(paint); } } paints.clear(); diff --git a/src/lib/tvgPaint.h b/src/lib/tvgPaint.h index ba33e1b5..c0404c8b 100644 --- a/src/lib/tvgPaint.h +++ b/src/lib/tvgPaint.h @@ -68,6 +68,7 @@ namespace tvg uint8_t ctxFlag = ContextFlag::Invalid; uint8_t id; uint8_t opacity = 255; + uint8_t refCnt = 1; ~Impl() { @@ -79,6 +80,18 @@ namespace tvg delete(rTransform); } + uint8_t ref() + { + if (refCnt == 255) TVGERR("RENDERER", "Corrupted reference count!"); + return (++refCnt); + } + + uint8_t unref() + { + if (refCnt == 0) TVGERR("RENDERER", "Corrupted reference count!"); + return (--refCnt); + } + void method(StrategyMethod* method) { smethod = method; diff --git a/src/lib/tvgPictureImpl.h b/src/lib/tvgPictureImpl.h index 18dde649..a2b41ea9 100644 --- a/src/lib/tvgPictureImpl.h +++ b/src/lib/tvgPictureImpl.h @@ -70,7 +70,6 @@ struct Picture::Impl Picture* picture = nullptr; bool resizing = false; bool needComp = false; //need composition - bool animated = false; //picture is belonged to Animation Impl(Picture* p) : picture(p) { @@ -87,7 +86,7 @@ struct Picture::Impl if (paint) paint->pImpl->dispose(renderer); else if (surface) renderer.dispose(rd); rd = nullptr; - return !animated; + return true; } RenderTransform resizeTransform(const RenderTransform* pTransform) diff --git a/src/lib/tvgRender.h b/src/lib/tvgRender.h index 9d7bafb6..19d5eee1 100644 --- a/src/lib/tvgRender.h +++ b/src/lib/tvgRender.h @@ -267,7 +267,7 @@ static inline bool MASK_OPERATION(CompositeMethod method) case CompositeMethod::DifferenceMask: return true; default: - TVGERR("COMMON", "Unsupported Composite Size! = %d", (int)method); + TVGERR("RENDERER", "Unsupported Composite Size! = %d", (int)method); return false; } } @@ -284,7 +284,7 @@ static inline uint8_t CHANNEL_SIZE(ColorSpace cs) return sizeof(uint8_t); case ColorSpace::Unsupported: default: - TVGERR("SW_ENGINE", "Unsupported Channel Size! = %d", (int)cs); + TVGERR("RENDERER", "Unsupported Channel Size! = %d", (int)cs); return 0; } } @@ -303,7 +303,7 @@ static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod& renderer, Composi case CompositeMethod::DifferenceMask: return renderer.colorSpace(); default: - TVGERR("COMMON", "Unsupported Composite Size! = %d", (int)method); + TVGERR("RENDERER", "Unsupported Composite Size! = %d", (int)method); return ColorSpace::Unsupported; } } diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index 28890a6b..1d89e5a2 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -75,7 +75,7 @@ struct Scene::Impl ~Impl() { for (auto paint : paints) { - delete(paint); + if (paint->pImpl->unref() == 0) delete(paint); } }