mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
sw_engine: ++rle optimization
Reduction memory copy by pushing span data into rle immediately.
This commit is contained in:
parent
e07ff127dd
commit
065a8f5eb3
1 changed files with 38 additions and 69 deletions
|
@ -197,7 +197,6 @@
|
|||
/* Internal Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
constexpr auto MAX_SPANS = 256;
|
||||
constexpr auto PIXEL_BITS = 8; //must be at least 6 bits!
|
||||
constexpr auto ONE_PIXEL = (1L << PIXEL_BITS);
|
||||
|
||||
|
@ -240,10 +239,6 @@ struct RleWorker
|
|||
|
||||
SwOutline* outline;
|
||||
|
||||
SwSpan spans[MAX_SPANS];
|
||||
int spansCnt;
|
||||
int ySpan;
|
||||
|
||||
int bandSize;
|
||||
int bandShoot;
|
||||
|
||||
|
@ -301,26 +296,6 @@ static inline SwCoord HYPOT(SwPoint pt)
|
|||
return ((pt.x > pt.y) ? (pt.x + (3 * pt.y >> 3)) : (pt.y + (3 * pt.x >> 3)));
|
||||
}
|
||||
|
||||
static void _genSpan(SwRleData* rle, const SwSpan* spans, uint32_t count)
|
||||
{
|
||||
auto newSize = rle->size + count;
|
||||
|
||||
/* allocate enough memory for new spans */
|
||||
/* alloc is required to prevent free and reallocation */
|
||||
/* 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<SwSpan*>(realloc(rle->spans, rle->alloc * sizeof(SwSpan)));
|
||||
}
|
||||
|
||||
//copy the new spans to the allocated memory
|
||||
SwSpan* lastSpan = rle->spans + rle->size;
|
||||
memcpy(lastSpan, spans, count * sizeof(SwSpan));
|
||||
|
||||
rle->size = newSize;
|
||||
}
|
||||
|
||||
|
||||
static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoord aCount)
|
||||
{
|
||||
|
@ -344,25 +319,26 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor
|
|||
if (coverage > 255) coverage = 255;
|
||||
}
|
||||
|
||||
if (coverage == 0) return;
|
||||
|
||||
//span has ushort coordinates. check limit overflow
|
||||
if (x >= SHRT_MAX) {
|
||||
TVGERR("SW_ENGINE", "X-coordinate overflow!");
|
||||
x = SHRT_MAX;
|
||||
return;
|
||||
}
|
||||
if (y >= SHRT_MAX) {
|
||||
TVGERR("SW_ENGINE", "Y-coordinate overflow!");
|
||||
y = SHRT_MAX;
|
||||
return;
|
||||
}
|
||||
|
||||
if (coverage > 0) {
|
||||
if (!rw.antiAlias) coverage = 255;
|
||||
auto count = rw.spansCnt;
|
||||
auto span = rw.spans + count - 1;
|
||||
auto rle = rw.rle;
|
||||
|
||||
//see whether we can add this span to the current list
|
||||
if ((count > 0) && (rw.ySpan == y) &&
|
||||
(span->x + span->len == x) && (span->coverage == coverage)) {
|
||||
if (!rw.antiAlias) coverage = 255;
|
||||
|
||||
//see whether we can add this span to the current list
|
||||
if (rle->size > 0) {
|
||||
auto span = rle->spans + rle->size - 1;
|
||||
if ((span->coverage == coverage) && (span->y == y) && (span->x + span->len == x)) {
|
||||
//Clip x range
|
||||
SwCoord xOver = 0;
|
||||
if (x + aCount >= rw.cellMax.x) xOver -= (x + aCount - rw.cellMax.x);
|
||||
|
@ -372,35 +348,35 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor
|
|||
span->len += (aCount + xOver);
|
||||
return;
|
||||
}
|
||||
|
||||
if (count >= MAX_SPANS) {
|
||||
_genSpan(rw.rle, rw.spans, count);
|
||||
rw.spansCnt = 0;
|
||||
rw.ySpan = 0;
|
||||
span = rw.spans;
|
||||
} else {
|
||||
++span;
|
||||
}
|
||||
|
||||
//Clip x range
|
||||
SwCoord xOver = 0;
|
||||
if (x + aCount >= rw.cellMax.x) xOver -= (x + aCount - rw.cellMax.x);
|
||||
if (x < rw.cellMin.x) {
|
||||
xOver -= (rw.cellMin.x - x);
|
||||
x = rw.cellMin.x;
|
||||
}
|
||||
|
||||
//Nothing to draw
|
||||
if (aCount + xOver <= 0) return;
|
||||
|
||||
//add a span to the current list
|
||||
span->x = x;
|
||||
span->y = y;
|
||||
span->len = (aCount + xOver);
|
||||
span->coverage = coverage;
|
||||
++rw.spansCnt;
|
||||
rw.ySpan = y;
|
||||
}
|
||||
|
||||
//span pool is full, grow it.
|
||||
if (rle->size >= rle->alloc) {
|
||||
auto newSize = (rle->size > 0) ? (rle->size * 2) : 256;
|
||||
if (rle->alloc < newSize) {
|
||||
rle->alloc = newSize;
|
||||
rle->spans = static_cast<SwSpan*>(realloc(rle->spans, rle->alloc * sizeof(SwSpan)));
|
||||
}
|
||||
}
|
||||
|
||||
//Clip x range
|
||||
SwCoord xOver = 0;
|
||||
if (x + aCount >= rw.cellMax.x) xOver -= (x + aCount - rw.cellMax.x);
|
||||
if (x < rw.cellMin.x) {
|
||||
xOver -= (rw.cellMin.x - x);
|
||||
x = rw.cellMin.x;
|
||||
}
|
||||
|
||||
//Nothing to draw
|
||||
if (aCount + xOver <= 0) return;
|
||||
|
||||
//add a span to the current list
|
||||
auto span = rle->spans + rle->size;
|
||||
span->x = x;
|
||||
span->y = y;
|
||||
span->len = (aCount + xOver);
|
||||
span->coverage = coverage;
|
||||
rle->size++;
|
||||
}
|
||||
|
||||
|
||||
|
@ -408,9 +384,6 @@ static void _sweep(RleWorker& rw)
|
|||
{
|
||||
if (rw.cellsCnt == 0) return;
|
||||
|
||||
rw.spansCnt = 0;
|
||||
rw.ySpan = 0;
|
||||
|
||||
for (int y = 0; y < rw.yCnt; ++y) {
|
||||
auto cover = 0;
|
||||
auto x = 0;
|
||||
|
@ -427,8 +400,6 @@ static void _sweep(RleWorker& rw)
|
|||
|
||||
if (cover != 0) _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), rw.cellXCnt - x);
|
||||
}
|
||||
|
||||
if (rw.spansCnt > 0) _genSpan(rw.rle, rw.spans, rw.spansCnt);
|
||||
}
|
||||
|
||||
|
||||
|
@ -926,7 +897,6 @@ SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& ren
|
|||
rw.cellMax = renderRegion.max;
|
||||
rw.cellXCnt = rw.cellMax.x - rw.cellMin.x;
|
||||
rw.cellYCnt = rw.cellMax.y - rw.cellMin.y;
|
||||
rw.ySpan = 0;
|
||||
rw.outline = const_cast<SwOutline*>(outline);
|
||||
rw.bandSize = rw.bufferSize / (sizeof(Cell) * 2); //bandSize: 256
|
||||
rw.bandShoot = 0;
|
||||
|
@ -1019,7 +989,6 @@ SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& ren
|
|||
|
||||
error:
|
||||
free(rw.rle);
|
||||
rw.rle = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue