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 "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<Paint*>(picture)->pImpl->ref();
}
~Impl()
{
if (static_cast<Paint*>(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;

View file

@ -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();

View file

@ -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;

View file

@ -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)

View file

@ -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;
}
}

View file

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