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 5123f73c..cfdce379 100644 Binary files a/test/resources/tag.tvg and b/test/resources/tag.tvg differ