renderer: enhance stability

introduce a paint reference count
to prevent any duplicated resource removal.
This commit is contained in:
Hermet Park 2023-08-11 13:48:41 +09:00 committed by Hermet Park
parent 6a59e1b715
commit 7057dc594d
6 changed files with 40 additions and 15 deletions

View file

@ -23,6 +23,7 @@
//#include "tvgAnimationImpl.h" //#include "tvgAnimationImpl.h"
#include "tvgCommon.h" #include "tvgCommon.h"
#include "tvgFrameModule.h" #include "tvgFrameModule.h"
#include "tvgPaint.h"
#include "tvgPictureImpl.h" #include "tvgPictureImpl.h"
/************************************************************************/ /************************************************************************/
@ -31,7 +32,20 @@
struct Animation::Impl struct Animation::Impl
{ {
Picture picture; Picture* picture = nullptr;
Impl()
{
picture = Picture::gen().release();
static_cast<Paint*>(picture)->pImpl->ref();
}
~Impl()
{
if (static_cast<Paint*>(picture)->pImpl->unref() == 0) {
delete(picture);
}
}
}; };
/************************************************************************/ /************************************************************************/
@ -40,19 +54,18 @@ struct Animation::Impl
Animation::~Animation() Animation::~Animation()
{ {
//FIXME: free pImpl delete(pImpl);
} }
Animation::Animation() : pImpl(new Impl) Animation::Animation() : pImpl(new Impl)
{ {
pImpl->picture.pImpl->animated = true;
} }
Result Animation::frame(uint32_t no) noexcept 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) return Result::InsufficientCondition;
if (!loader->animatable()) return Result::NonSupport; if (!loader->animatable()) return Result::NonSupport;
@ -64,13 +77,13 @@ Result Animation::frame(uint32_t no) noexcept
Picture* Animation::picture() const noexcept Picture* Animation::picture() const noexcept
{ {
return &pImpl->picture; return pImpl->picture;
} }
uint32_t Animation::curFrame() const noexcept 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) return 0;
if (!loader->animatable()) return 0; if (!loader->animatable()) return 0;
@ -81,7 +94,7 @@ uint32_t Animation::curFrame() const noexcept
uint32_t Animation::totalFrame() 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) return 0;
if (!loader->animatable()) return 0; if (!loader->animatable()) return 0;
@ -92,7 +105,7 @@ uint32_t Animation::totalFrame() const noexcept
float Animation::duration() 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) return 0;
if (!loader->animatable()) return 0; if (!loader->animatable()) return 0;

View file

@ -67,7 +67,7 @@ struct Canvas::Impl
if (free) { if (free) {
for (auto paint : paints) { for (auto paint : paints) {
if (paint->pImpl->dispose(*renderer)) { if (paint->pImpl->dispose(*renderer)) {
delete(paint); if (paint->pImpl->unref() == 0) delete(paint);
} }
} }
paints.clear(); paints.clear();

View file

@ -68,6 +68,7 @@ namespace tvg
uint8_t ctxFlag = ContextFlag::Invalid; uint8_t ctxFlag = ContextFlag::Invalid;
uint8_t id; uint8_t id;
uint8_t opacity = 255; uint8_t opacity = 255;
uint8_t refCnt = 1;
~Impl() ~Impl()
{ {
@ -79,6 +80,18 @@ namespace tvg
delete(rTransform); 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) void method(StrategyMethod* method)
{ {
smethod = method; smethod = method;

View file

@ -70,7 +70,6 @@ struct Picture::Impl
Picture* picture = nullptr; Picture* picture = nullptr;
bool resizing = false; bool resizing = false;
bool needComp = false; //need composition bool needComp = false; //need composition
bool animated = false; //picture is belonged to Animation
Impl(Picture* p) : picture(p) Impl(Picture* p) : picture(p)
{ {
@ -87,7 +86,7 @@ struct Picture::Impl
if (paint) paint->pImpl->dispose(renderer); if (paint) paint->pImpl->dispose(renderer);
else if (surface) renderer.dispose(rd); else if (surface) renderer.dispose(rd);
rd = nullptr; rd = nullptr;
return !animated; return true;
} }
RenderTransform resizeTransform(const RenderTransform* pTransform) RenderTransform resizeTransform(const RenderTransform* pTransform)

View file

@ -267,7 +267,7 @@ static inline bool MASK_OPERATION(CompositeMethod method)
case CompositeMethod::DifferenceMask: case CompositeMethod::DifferenceMask:
return true; return true;
default: default:
TVGERR("COMMON", "Unsupported Composite Size! = %d", (int)method); TVGERR("RENDERER", "Unsupported Composite Size! = %d", (int)method);
return false; return false;
} }
} }
@ -284,7 +284,7 @@ static inline uint8_t CHANNEL_SIZE(ColorSpace cs)
return sizeof(uint8_t); return sizeof(uint8_t);
case ColorSpace::Unsupported: case ColorSpace::Unsupported:
default: default:
TVGERR("SW_ENGINE", "Unsupported Channel Size! = %d", (int)cs); TVGERR("RENDERER", "Unsupported Channel Size! = %d", (int)cs);
return 0; return 0;
} }
} }
@ -303,7 +303,7 @@ static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod& renderer, Composi
case CompositeMethod::DifferenceMask: case CompositeMethod::DifferenceMask:
return renderer.colorSpace(); return renderer.colorSpace();
default: default:
TVGERR("COMMON", "Unsupported Composite Size! = %d", (int)method); TVGERR("RENDERER", "Unsupported Composite Size! = %d", (int)method);
return ColorSpace::Unsupported; return ColorSpace::Unsupported;
} }
} }

View file

@ -75,7 +75,7 @@ struct Scene::Impl
~Impl() ~Impl()
{ {
for (auto paint : paints) { for (auto paint : paints) {
delete(paint); if (paint->pImpl->unref() == 0) delete(paint);
} }
} }