From 386888bd1156238c1a399db6142d20fb6f45781f Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 28 Jul 2021 17:14:34 +0900 Subject: [PATCH] sw_engine: flush memory pool after drawing. if many canvas instances own private memory pool, the memory usage can be increased linearly. To prevent memory usage, flush out memory pool from the clear() if the canvas uses private memory pool. --- src/lib/sw_engine/tvgSwMemPool.cpp | 44 +++++++++++++---------------- src/lib/sw_engine/tvgSwRenderer.cpp | 3 +- src/lib/sw_engine/tvgSwRle.cpp | 5 ++-- src/lib/sw_engine/tvgSwStroke.cpp | 2 +- 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/lib/sw_engine/tvgSwMemPool.cpp b/src/lib/sw_engine/tvgSwMemPool.cpp index 1b61fd29..ae051d81 100644 --- a/src/lib/sw_engine/tvgSwMemPool.cpp +++ b/src/lib/sw_engine/tvgSwMemPool.cpp @@ -95,37 +95,33 @@ bool mpoolClear(SwMpool* mpool) for (unsigned i = 0; i < mpool->allocSize; ++i) { + //Outline p = &mpool->outline[i]; - if (p->cntrs) { - free(p->cntrs); - p->cntrs = nullptr; - } - if (p->pts) { - free(p->pts); - p->pts = nullptr; - } - if (p->types) { - free(p->types); - p->types = nullptr; - } + free(p->cntrs); + p->cntrs = nullptr; + + free(p->pts); + p->pts = nullptr; + + free(p->types); + p->types = nullptr; + p->cntrsCnt = p->reservedCntrsCnt = 0; p->ptsCnt = p->reservedPtsCnt = 0; + //StrokeOutline p = &mpool->strokeOutline[i]; - if (p->cntrs) { - free(p->cntrs); - p->cntrs = nullptr; - } - if (p->pts) { - free(p->pts); - p->pts = nullptr; - } - if (p->types) { - free(p->types); - p->types = nullptr; - } + free(p->cntrs); + p->cntrs = nullptr; + + free(p->pts); + p->pts = nullptr; + + free(p->types); + p->types = nullptr; + p->cntrsCnt = p->reservedCntrsCnt = 0; p->ptsCnt = p->reservedPtsCnt = 0; } diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index a4814bd4..817f5472 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -223,7 +223,6 @@ static void _termEngine() SwRenderer::~SwRenderer() { - clear(); clearCompositors(); if (surface) delete(surface); @@ -241,6 +240,8 @@ bool SwRenderer::clear() for (auto task = tasks.data; task < (tasks.data + tasks.count); ++task) (*task)->done(); tasks.clear(); + if (!sharedMpool) mpoolClear(mpool); + if (surface) { vport.x = vport.y = 0; vport.w = surface->w; diff --git a/src/lib/sw_engine/tvgSwRle.cpp b/src/lib/sw_engine/tvgSwRle.cpp index 42ae67aa..d6bc7f6e 100644 --- a/src/lib/sw_engine/tvgSwRle.cpp +++ b/src/lib/sw_engine/tvgSwRle.cpp @@ -141,6 +141,7 @@ static void _genSpan(SwRleData* rle, const SwSpan* spans, uint32_t count) /* when the rle needs to be regenerated because of attribute change. */ if (rle->alloc < newSize) { rle->alloc = (newSize * 2); + //OPTIMIZE: use mempool! rle->spans = static_cast(realloc(rle->spans, rle->alloc * sizeof(SwSpan))); } @@ -162,7 +163,7 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor /* compute the coverage line's coverage, depending on the outline fill rule */ /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */ - auto coverage = static_cast(area >> (PIXEL_BITS * 2 + 1 - 8)); //range 0 - 256 + auto coverage = static_cast(area >> (PIXEL_BITS * 2 + 1 - 8)); //range 0 - 255 if (coverage < 0) coverage = -coverage; @@ -247,12 +248,10 @@ static void _sweep(RleWorker& rw) auto cell = rw.yCells[y]; while (cell) { - if (cell->x > x && cover != 0) _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), cell->x - x); cover += cell->cover; auto area = cover * (ONE_PIXEL * 2) - cell->area; if (area != 0 && cell->x >= 0) _horizLine(rw, cell->x, y, area, 1); - x = cell->x + 1; cell = cell->next; } diff --git a/src/lib/sw_engine/tvgSwStroke.cpp b/src/lib/sw_engine/tvgSwStroke.cpp index 6b375529..a39d0053 100644 --- a/src/lib/sw_engine/tvgSwStroke.cpp +++ b/src/lib/sw_engine/tvgSwStroke.cpp @@ -56,7 +56,7 @@ static void _growBorder(SwStrokeBorder* border, uint32_t newPts) while (maxCur < maxNew) maxCur += (maxCur >> 1) + 16; - + //OPTIMIZE: use mempool! border->pts = static_cast(realloc(border->pts, maxCur * sizeof(SwPoint))); border->tags = static_cast(realloc(border->tags, maxCur * sizeof(uint8_t))); border->maxPts = maxCur;