mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 21:53:41 +00:00
renderer: enhance stability
introduce a paint reference count to prevent any duplicated resource removal.
This commit is contained in:
parent
6a59e1b715
commit
7057dc594d
6 changed files with 40 additions and 15 deletions
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ struct Scene::Impl
|
|||
~Impl()
|
||||
{
|
||||
for (auto paint : paints) {
|
||||
delete(paint);
|
||||
if (paint->pImpl->unref() == 0) delete(paint);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue