mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-09 06:04:03 +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 */
|
/* Internal Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
constexpr auto MAX_SPANS = 256;
|
|
||||||
constexpr auto PIXEL_BITS = 8; //must be at least 6 bits!
|
constexpr auto PIXEL_BITS = 8; //must be at least 6 bits!
|
||||||
constexpr auto ONE_PIXEL = (1L << PIXEL_BITS);
|
constexpr auto ONE_PIXEL = (1L << PIXEL_BITS);
|
||||||
|
|
||||||
|
@ -240,10 +239,6 @@ struct RleWorker
|
||||||
|
|
||||||
SwOutline* outline;
|
SwOutline* outline;
|
||||||
|
|
||||||
SwSpan spans[MAX_SPANS];
|
|
||||||
int spansCnt;
|
|
||||||
int ySpan;
|
|
||||||
|
|
||||||
int bandSize;
|
int bandSize;
|
||||||
int bandShoot;
|
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)));
|
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)
|
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 > 255) coverage = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (coverage == 0) return;
|
||||||
|
|
||||||
//span has ushort coordinates. check limit overflow
|
//span has ushort coordinates. check limit overflow
|
||||||
if (x >= SHRT_MAX) {
|
if (x >= SHRT_MAX) {
|
||||||
TVGERR("SW_ENGINE", "X-coordinate overflow!");
|
TVGERR("SW_ENGINE", "X-coordinate overflow!");
|
||||||
x = SHRT_MAX;
|
return;
|
||||||
}
|
}
|
||||||
if (y >= SHRT_MAX) {
|
if (y >= SHRT_MAX) {
|
||||||
TVGERR("SW_ENGINE", "Y-coordinate overflow!");
|
TVGERR("SW_ENGINE", "Y-coordinate overflow!");
|
||||||
y = SHRT_MAX;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coverage > 0) {
|
auto rle = rw.rle;
|
||||||
|
|
||||||
if (!rw.antiAlias) coverage = 255;
|
if (!rw.antiAlias) coverage = 255;
|
||||||
auto count = rw.spansCnt;
|
|
||||||
auto span = rw.spans + count - 1;
|
|
||||||
|
|
||||||
//see whether we can add this span to the current list
|
//see whether we can add this span to the current list
|
||||||
if ((count > 0) && (rw.ySpan == y) &&
|
if (rle->size > 0) {
|
||||||
(span->x + span->len == x) && (span->coverage == coverage)) {
|
auto span = rle->spans + rle->size - 1;
|
||||||
|
if ((span->coverage == coverage) && (span->y == y) && (span->x + span->len == x)) {
|
||||||
//Clip x range
|
//Clip x range
|
||||||
SwCoord xOver = 0;
|
SwCoord xOver = 0;
|
||||||
if (x + aCount >= rw.cellMax.x) xOver -= (x + aCount - rw.cellMax.x);
|
if (x + aCount >= rw.cellMax.x) xOver -= (x + aCount - rw.cellMax.x);
|
||||||
|
@ -372,14 +348,15 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor
|
||||||
span->len += (aCount + xOver);
|
span->len += (aCount + xOver);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (count >= MAX_SPANS) {
|
//span pool is full, grow it.
|
||||||
_genSpan(rw.rle, rw.spans, count);
|
if (rle->size >= rle->alloc) {
|
||||||
rw.spansCnt = 0;
|
auto newSize = (rle->size > 0) ? (rle->size * 2) : 256;
|
||||||
rw.ySpan = 0;
|
if (rle->alloc < newSize) {
|
||||||
span = rw.spans;
|
rle->alloc = newSize;
|
||||||
} else {
|
rle->spans = static_cast<SwSpan*>(realloc(rle->spans, rle->alloc * sizeof(SwSpan)));
|
||||||
++span;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Clip x range
|
//Clip x range
|
||||||
|
@ -394,13 +371,12 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor
|
||||||
if (aCount + xOver <= 0) return;
|
if (aCount + xOver <= 0) return;
|
||||||
|
|
||||||
//add a span to the current list
|
//add a span to the current list
|
||||||
|
auto span = rle->spans + rle->size;
|
||||||
span->x = x;
|
span->x = x;
|
||||||
span->y = y;
|
span->y = y;
|
||||||
span->len = (aCount + xOver);
|
span->len = (aCount + xOver);
|
||||||
span->coverage = coverage;
|
span->coverage = coverage;
|
||||||
++rw.spansCnt;
|
rle->size++;
|
||||||
rw.ySpan = y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -408,9 +384,6 @@ static void _sweep(RleWorker& rw)
|
||||||
{
|
{
|
||||||
if (rw.cellsCnt == 0) return;
|
if (rw.cellsCnt == 0) return;
|
||||||
|
|
||||||
rw.spansCnt = 0;
|
|
||||||
rw.ySpan = 0;
|
|
||||||
|
|
||||||
for (int y = 0; y < rw.yCnt; ++y) {
|
for (int y = 0; y < rw.yCnt; ++y) {
|
||||||
auto cover = 0;
|
auto cover = 0;
|
||||||
auto x = 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 (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.cellMax = renderRegion.max;
|
||||||
rw.cellXCnt = rw.cellMax.x - rw.cellMin.x;
|
rw.cellXCnt = rw.cellMax.x - rw.cellMin.x;
|
||||||
rw.cellYCnt = rw.cellMax.y - rw.cellMin.y;
|
rw.cellYCnt = rw.cellMax.y - rw.cellMin.y;
|
||||||
rw.ySpan = 0;
|
|
||||||
rw.outline = const_cast<SwOutline*>(outline);
|
rw.outline = const_cast<SwOutline*>(outline);
|
||||||
rw.bandSize = rw.bufferSize / (sizeof(Cell) * 2); //bandSize: 256
|
rw.bandSize = rw.bufferSize / (sizeof(Cell) * 2); //bandSize: 256
|
||||||
rw.bandShoot = 0;
|
rw.bandShoot = 0;
|
||||||
|
@ -1019,7 +989,6 @@ SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& ren
|
||||||
|
|
||||||
error:
|
error:
|
||||||
free(rw.rle);
|
free(rw.rle);
|
||||||
rw.rle = nullptr;
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue