mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-09 14:13:43 +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 "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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue