renderer: revise the internal logic.

dispose of the resources at the end of the paint deletion.
This will help retain the resources of the retained paints
and reuse them after reconstructing the next scene.
This commit is contained in:
Hermet Park 2024-02-01 17:04:53 +09:00
parent 636890e20b
commit a8fc3a6e50
8 changed files with 43 additions and 66 deletions

View file

@ -39,8 +39,25 @@ struct Canvas::Impl
~Impl()
{
clear(true);
delete(renderer);
//make it sure any deffered jobs
if (renderer) {
renderer->sync();
renderer->clear();
}
clearPaints();
if (renderer) {
if ((--renderer->refCnt) == 0) delete(renderer);
}
}
void clearPaints()
{
for (auto paint : paints) {
if (P(paint)->unref() == 0) delete(paint);
}
paints.clear();
}
Result push(unique_ptr<Paint> paint)
@ -62,15 +79,8 @@ struct Canvas::Impl
if (!renderer || !renderer->clear()) return Result::InsufficientCondition;
//Free paints
if (free) {
for (auto paint : paints) {
P(paint)->unref();
if (paint->pImpl->dispose(renderer) && P(paint)->refCnt == 0) {
delete(paint);
}
}
paints.clear();
}
if (free) clearPaints();
drawing = false;
return Result::Success;

View file

@ -114,16 +114,6 @@ RenderRegion Paint::Impl::bounds(RenderMethod* renderer) const
}
bool Paint::Impl::dispose(RenderMethod* renderer)
{
if (compData) compData->target->pImpl->dispose(renderer);
bool ret;
PAINT_METHOD(ret, dispose(renderer));
return ret;
}
Iterator* Paint::Impl::iterator()
{
Iterator* ret;
@ -231,6 +221,12 @@ bool Paint::Impl::render(RenderMethod* renderer)
RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pTransform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper)
{
if (this->renderer != renderer) {
if (this->renderer) TVGERR("RENDERER", "paint's renderer has been changed!");
++renderer->refCnt;
this->renderer = renderer;
}
if (renderFlag & RenderUpdateFlag::Transform) {
if (!rTransform) return nullptr;
rTransform->update();

View file

@ -50,6 +50,7 @@ namespace tvg
Paint* paint = nullptr;
RenderTransform* rTransform = nullptr;
Composite* compData = nullptr;
RenderMethod* renderer = nullptr;
BlendMethod blendMethod = BlendMethod::Normal; //uint8_t
uint8_t renderFlag = RenderUpdateFlag::None;
uint8_t ctxFlag = ContextFlag::Invalid;
@ -57,9 +58,7 @@ namespace tvg
uint8_t opacity = 255;
uint8_t refCnt = 0;
Impl(Paint* pnt) : paint(pnt)
{
}
Impl(Paint* pnt) : paint(pnt) {}
~Impl()
{
@ -132,7 +131,6 @@ namespace tvg
}
RenderRegion bounds(RenderMethod* renderer) const;
bool dispose(RenderMethod* renderer);
Iterator* iterator();
bool rotate(float degree);
bool scale(float factor);

View file

@ -82,17 +82,14 @@ struct Picture::Impl
~Impl()
{
LoaderMgr::retrieve(loader);
if (surface) {
if (auto renderer = PP(picture)->renderer) {
renderer->dispose(rd);
}
}
delete(paint);
}
bool dispose(RenderMethod* renderer)
{
if (paint) paint->pImpl->dispose(renderer);
else if (surface) renderer->dispose(rd);
rd = nullptr;
return true;
}
RenderData update(RenderMethod* renderer, const RenderTransform* pTransform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper)
{
auto flag = load();

View file

@ -59,7 +59,6 @@ struct SceneIterator : Iterator
struct Scene::Impl
{
list<Paint*> paints;
RenderMethod* renderer = nullptr; //keep it for explicit clear
RenderData rd = nullptr;
Scene* scene = nullptr;
uint8_t opacity; //for composition
@ -74,19 +73,10 @@ struct Scene::Impl
for (auto paint : paints) {
if (P(paint)->unref() == 0) delete(paint);
}
}
bool dispose(RenderMethod* renderer)
{
for (auto paint : paints) {
paint->pImpl->dispose(renderer);
if (auto renderer = PP(scene)->renderer) {
renderer->dispose(rd);
}
renderer->dispose(rd);
this->renderer = nullptr;
this->rd = nullptr;
return true;
}
bool needComposition(uint8_t opacity)
@ -120,8 +110,6 @@ struct Scene::Impl
opacity = 255;
}
this->renderer = renderer;
if (clipper) {
Array<RenderData> rds(paints.size());
for (auto paint : paints) {
@ -226,14 +214,10 @@ struct Scene::Impl
void clear(bool free)
{
auto dispose = renderer ? true : false;
for (auto paint : paints) {
if (dispose) free &= P(paint)->dispose(renderer);
if (P(paint)->unref() == 0 && free) delete(paint);
}
paints.clear();
renderer = nullptr;
}
Iterator* iterator()

View file

@ -41,11 +41,11 @@ struct Shape::Impl
{
}
bool dispose(RenderMethod* renderer)
~Impl()
{
renderer->dispose(rd);
rd = nullptr;
return true;
if (auto renderer = PP(shape)->renderer) {
renderer->dispose(rd);
}
}
bool render(RenderMethod* renderer)

View file

@ -35,7 +35,6 @@
struct Text::Impl
{
RenderData rd = nullptr;
FontLoader* loader = nullptr;
Shape* paint = nullptr;
char* utf8 = nullptr;
@ -94,7 +93,8 @@ struct Text::Impl
RenderRegion bounds(RenderMethod* renderer)
{
return renderer->region(rd);
if (paint) return P(paint)->bounds(renderer);
else return {0, 0, 0, 0};
}
bool render(RenderMethod* renderer)
@ -142,8 +142,7 @@ struct Text::Impl
P(static_cast<RadialGradient*>(fill))->fr *= scale;
}
}
rd = PP(paint)->update(renderer, transform, clips, opacity, pFlag, clipper);
return rd;
return PP(paint)->update(renderer, transform, clips, opacity, pFlag, clipper);
}
bool bounds(float* x, float* y, float* w, float* h, TVG_UNUSED bool stroking)
@ -153,13 +152,6 @@ struct Text::Impl
return true;
}
bool dispose(RenderMethod* renderer)
{
renderer->dispose(rd);
this->rd = nullptr;
return true;
}
Paint* duplicate()
{
load();

Binary file not shown.