renderer: destroy engines safely.

Introduced a reference count to destroy it safely.
This commit is contained in:
Hermet Park 2024-02-01 17:15:13 +09:00
parent a8fc3a6e50
commit 9f4a8de253
4 changed files with 25 additions and 9 deletions

View file

@ -33,8 +33,9 @@ struct Canvas::Impl
bool refresh = false; //if all paints should be updated by force. bool refresh = false; //if all paints should be updated by force.
bool drawing = false; //on drawing condition? bool drawing = false; //on drawing condition?
Impl(RenderMethod* pRenderer):renderer(pRenderer) Impl(RenderMethod* pRenderer) : renderer(pRenderer)
{ {
renderer->ref();
} }
~Impl() ~Impl()
@ -47,9 +48,7 @@ struct Canvas::Impl
clearPaints(); clearPaints();
if (renderer) { if (renderer && (renderer->unref() == 0)) delete(renderer);
if ((--renderer->refCnt) == 0) delete(renderer);
}
} }
void clearPaints() void clearPaints()

View file

@ -223,7 +223,7 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pT
{ {
if (this->renderer != renderer) { if (this->renderer != renderer) {
if (this->renderer) TVGERR("RENDERER", "paint's renderer has been changed!"); if (this->renderer) TVGERR("RENDERER", "paint's renderer has been changed!");
++renderer->refCnt; renderer->ref();
this->renderer = renderer; this->renderer = renderer;
} }

View file

@ -56,7 +56,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 = 0; uint8_t refCnt = 0; //reference count
Impl(Paint* pnt) : paint(pnt) {} Impl(Paint* pnt) : paint(pnt) {}
@ -67,18 +67,19 @@ namespace tvg
free(compData); free(compData);
} }
delete(rTransform); delete(rTransform);
if (renderer && (renderer->unref() == 0)) delete(renderer);
} }
uint8_t ref() uint8_t ref()
{ {
if (refCnt == 255) TVGERR("RENDERER", "Corrupted reference count!"); if (refCnt == 255) TVGERR("RENDERER", "Corrupted reference count!");
return (++refCnt); return ++refCnt;
} }
uint8_t unref() uint8_t unref()
{ {
if (refCnt == 0) TVGERR("RENDERER", "Corrupted reference count!"); if (refCnt == 0) TVGERR("RENDERER", "Corrupted reference count!");
return (--refCnt); return --refCnt;
} }
bool transform(const Matrix& m) bool transform(const Matrix& m)

View file

@ -261,7 +261,23 @@ struct RenderShape
class RenderMethod class RenderMethod
{ {
private:
uint32_t refCnt = 0; //reference count
Key key;
public: public:
uint32_t ref()
{
ScopedLock lock(key);
return (++refCnt);
}
uint32_t unref()
{
ScopedLock lock(key);
return (--refCnt);
}
virtual ~RenderMethod() {} virtual ~RenderMethod() {}
virtual RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0; virtual RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0;
virtual RenderData prepare(const Array<RenderData>& scene, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) = 0; virtual RenderData prepare(const Array<RenderData>& scene, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) = 0;