From a8fc3a6e50d78c529dffb35826502fefd292dc2b Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 1 Feb 2024 17:04:53 +0900 Subject: [PATCH] renderer: revise the internal logic. dispose of the resources at the end of the paint deletion. This will help retain the resources of the retained paints and reuse them after reconstructing the next scene. --- src/renderer/tvgCanvas.h | 32 +++++++++++++++++++++----------- src/renderer/tvgPaint.cpp | 16 ++++++---------- src/renderer/tvgPaint.h | 6 ++---- src/renderer/tvgPicture.h | 13 +++++-------- src/renderer/tvgScene.h | 20 ++------------------ src/renderer/tvgShape.h | 8 ++++---- src/renderer/tvgText.h | 14 +++----------- test/resources/tag.tvg | Bin 3457 -> 3520 bytes 8 files changed, 43 insertions(+), 66 deletions(-) diff --git a/src/renderer/tvgCanvas.h b/src/renderer/tvgCanvas.h index b2234b5c..6754c0a9 100644 --- a/src/renderer/tvgCanvas.h +++ b/src/renderer/tvgCanvas.h @@ -39,8 +39,25 @@ struct Canvas::Impl ~Impl() { - clear(true); - delete(renderer); + //make it sure any deffered jobs + if (renderer) { + renderer->sync(); + renderer->clear(); + } + + clearPaints(); + + if (renderer) { + if ((--renderer->refCnt) == 0) delete(renderer); + } + } + + void clearPaints() + { + for (auto paint : paints) { + if (P(paint)->unref() == 0) delete(paint); + } + paints.clear(); } Result push(unique_ptr paint) @@ -62,15 +79,8 @@ struct Canvas::Impl if (!renderer || !renderer->clear()) return Result::InsufficientCondition; //Free paints - if (free) { - for (auto paint : paints) { - P(paint)->unref(); - if (paint->pImpl->dispose(renderer) && P(paint)->refCnt == 0) { - delete(paint); - } - } - paints.clear(); - } + if (free) clearPaints(); + drawing = false; return Result::Success; diff --git a/src/renderer/tvgPaint.cpp b/src/renderer/tvgPaint.cpp index aa82957d..6d0bc9d5 100644 --- a/src/renderer/tvgPaint.cpp +++ b/src/renderer/tvgPaint.cpp @@ -114,16 +114,6 @@ RenderRegion Paint::Impl::bounds(RenderMethod* renderer) const } -bool Paint::Impl::dispose(RenderMethod* renderer) -{ - if (compData) compData->target->pImpl->dispose(renderer); - - bool ret; - PAINT_METHOD(ret, dispose(renderer)); - return ret; -} - - Iterator* Paint::Impl::iterator() { Iterator* ret; @@ -231,6 +221,12 @@ bool Paint::Impl::render(RenderMethod* renderer) RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pTransform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) { + if (this->renderer != renderer) { + if (this->renderer) TVGERR("RENDERER", "paint's renderer has been changed!"); + ++renderer->refCnt; + this->renderer = renderer; + } + if (renderFlag & RenderUpdateFlag::Transform) { if (!rTransform) return nullptr; rTransform->update(); diff --git a/src/renderer/tvgPaint.h b/src/renderer/tvgPaint.h index fbe4de13..351f9e91 100644 --- a/src/renderer/tvgPaint.h +++ b/src/renderer/tvgPaint.h @@ -50,6 +50,7 @@ namespace tvg Paint* paint = nullptr; RenderTransform* rTransform = nullptr; Composite* compData = nullptr; + RenderMethod* renderer = nullptr; BlendMethod blendMethod = BlendMethod::Normal; //uint8_t uint8_t renderFlag = RenderUpdateFlag::None; uint8_t ctxFlag = ContextFlag::Invalid; @@ -57,9 +58,7 @@ namespace tvg uint8_t opacity = 255; uint8_t refCnt = 0; - Impl(Paint* pnt) : paint(pnt) - { - } + Impl(Paint* pnt) : paint(pnt) {} ~Impl() { @@ -132,7 +131,6 @@ namespace tvg } RenderRegion bounds(RenderMethod* renderer) const; - bool dispose(RenderMethod* renderer); Iterator* iterator(); bool rotate(float degree); bool scale(float factor); diff --git a/src/renderer/tvgPicture.h b/src/renderer/tvgPicture.h index d0a5cbad..91c16eb4 100644 --- a/src/renderer/tvgPicture.h +++ b/src/renderer/tvgPicture.h @@ -82,17 +82,14 @@ struct Picture::Impl ~Impl() { LoaderMgr::retrieve(loader); + if (surface) { + if (auto renderer = PP(picture)->renderer) { + renderer->dispose(rd); + } + } delete(paint); } - bool dispose(RenderMethod* renderer) - { - if (paint) paint->pImpl->dispose(renderer); - else if (surface) renderer->dispose(rd); - rd = nullptr; - return true; - } - RenderData update(RenderMethod* renderer, const RenderTransform* pTransform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) { auto flag = load(); diff --git a/src/renderer/tvgScene.h b/src/renderer/tvgScene.h index 2ee2839e..2267a2f7 100644 --- a/src/renderer/tvgScene.h +++ b/src/renderer/tvgScene.h @@ -59,7 +59,6 @@ struct SceneIterator : Iterator struct Scene::Impl { list paints; - RenderMethod* renderer = nullptr; //keep it for explicit clear RenderData rd = nullptr; Scene* scene = nullptr; uint8_t opacity; //for composition @@ -74,19 +73,10 @@ struct Scene::Impl for (auto paint : paints) { if (P(paint)->unref() == 0) delete(paint); } - } - bool dispose(RenderMethod* renderer) - { - for (auto paint : paints) { - paint->pImpl->dispose(renderer); + if (auto renderer = PP(scene)->renderer) { + renderer->dispose(rd); } - - renderer->dispose(rd); - this->renderer = nullptr; - this->rd = nullptr; - - return true; } bool needComposition(uint8_t opacity) @@ -120,8 +110,6 @@ struct Scene::Impl opacity = 255; } - this->renderer = renderer; - if (clipper) { Array rds(paints.size()); for (auto paint : paints) { @@ -226,14 +214,10 @@ struct Scene::Impl void clear(bool free) { - auto dispose = renderer ? true : false; - for (auto paint : paints) { - if (dispose) free &= P(paint)->dispose(renderer); if (P(paint)->unref() == 0 && free) delete(paint); } paints.clear(); - renderer = nullptr; } Iterator* iterator() diff --git a/src/renderer/tvgShape.h b/src/renderer/tvgShape.h index 97805072..1a7a29a9 100644 --- a/src/renderer/tvgShape.h +++ b/src/renderer/tvgShape.h @@ -41,11 +41,11 @@ struct Shape::Impl { } - bool dispose(RenderMethod* renderer) + ~Impl() { - renderer->dispose(rd); - rd = nullptr; - return true; + if (auto renderer = PP(shape)->renderer) { + renderer->dispose(rd); + } } bool render(RenderMethod* renderer) diff --git a/src/renderer/tvgText.h b/src/renderer/tvgText.h index 509c5d45..f4fb1225 100644 --- a/src/renderer/tvgText.h +++ b/src/renderer/tvgText.h @@ -35,7 +35,6 @@ struct Text::Impl { - RenderData rd = nullptr; FontLoader* loader = nullptr; Shape* paint = nullptr; char* utf8 = nullptr; @@ -94,7 +93,8 @@ struct Text::Impl RenderRegion bounds(RenderMethod* renderer) { - return renderer->region(rd); + if (paint) return P(paint)->bounds(renderer); + else return {0, 0, 0, 0}; } bool render(RenderMethod* renderer) @@ -142,8 +142,7 @@ struct Text::Impl P(static_cast(fill))->fr *= scale; } } - rd = PP(paint)->update(renderer, transform, clips, opacity, pFlag, clipper); - return rd; + return PP(paint)->update(renderer, transform, clips, opacity, pFlag, clipper); } bool bounds(float* x, float* y, float* w, float* h, TVG_UNUSED bool stroking) @@ -153,13 +152,6 @@ struct Text::Impl return true; } - bool dispose(RenderMethod* renderer) - { - renderer->dispose(rd); - this->rd = nullptr; - return true; - } - Paint* duplicate() { load(); diff --git a/test/resources/tag.tvg b/test/resources/tag.tvg index 5123f73ca920b7437d4fe6856537511c803c766e..cfdce3790ca6f7fb157419a0a96b37a0cdecb537 100644 GIT binary patch literal 3520 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 literal 3457 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 Zp9Cr44&7lE