mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-27 00:26:51 +00:00
sw_engine: optimize rle rendering.
we don't need to apply anti-aliasing if stroke is there. here turns off anti-alias if stroke width is more than 2. magic number 2 is experimentally confirmed. Change-Id: I09031dc2a0a84f31c5904651ed1e62004645ba9a
This commit is contained in:
parent
add79b07cd
commit
2929fa5c57
5 changed files with 19 additions and 20 deletions
|
@ -265,7 +265,7 @@ SwFixed mathMean(SwFixed angle1, SwFixed angle2);
|
||||||
void shapeReset(SwShape& shape);
|
void shapeReset(SwShape& shape);
|
||||||
bool shapeGenOutline(SwShape& shape, const Shape* sdata);
|
bool shapeGenOutline(SwShape& shape, const Shape* sdata);
|
||||||
bool shapePrepare(SwShape& shape, const Shape* sdata, const SwSize& clip, const Matrix* transform);
|
bool shapePrepare(SwShape& shape, const Shape* sdata, const SwSize& clip, const Matrix* transform);
|
||||||
bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip);
|
bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip, bool antiAlias);
|
||||||
void shapeDelOutline(SwShape& shape);
|
void shapeDelOutline(SwShape& shape);
|
||||||
void shapeResetStroke(SwShape& shape, const Shape* sdata);
|
void shapeResetStroke(SwShape& shape, const Shape* sdata);
|
||||||
bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const SwSize& clip);
|
bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const SwSize& clip);
|
||||||
|
@ -286,7 +286,7 @@ void fillFree(SwFill* fill);
|
||||||
void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
|
void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
|
||||||
void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
|
void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
|
||||||
|
|
||||||
SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip);
|
SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias);
|
||||||
void rleFree(SwRleData* rle);
|
void rleFree(SwRleData* rle);
|
||||||
|
|
||||||
bool rasterGradientShape(Surface& surface, SwShape& shape, unsigned id);
|
bool rasterGradientShape(Surface& surface, SwShape& shape, unsigned id);
|
||||||
|
|
|
@ -109,7 +109,7 @@ void SwRenderer::doRender()
|
||||||
if (a > 0) rasterSolidShape(surface, task->shape, r, g, b, a);
|
if (a > 0) rasterSolidShape(surface, task->shape, r, g, b, a);
|
||||||
}
|
}
|
||||||
task->sdata->strokeColor(&r, &g, &b, &a);
|
task->sdata->strokeColor(&r, &g, &b, &a);
|
||||||
if (a > 0) rasterStroke(surface, task->shape, r, g, b, a);
|
if (a > 0) rasterStroke(surface, task->shape, r, g, b, a);
|
||||||
renderTasks.pop();
|
renderTasks.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,8 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform*
|
||||||
|
|
||||||
//Valid Stroking?
|
//Valid Stroking?
|
||||||
uint8_t strokeAlpha = 0;
|
uint8_t strokeAlpha = 0;
|
||||||
if (task->sdata->strokeWidth() > FLT_EPSILON) {
|
auto strokeWidth = task->sdata->strokeWidth();
|
||||||
|
if (strokeWidth > FLT_EPSILON) {
|
||||||
task->sdata->strokeColor(nullptr, nullptr, nullptr, &strokeAlpha);
|
task->sdata->strokeColor(nullptr, nullptr, nullptr, &strokeAlpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,10 +189,11 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform*
|
||||||
uint8_t alpha = 0;
|
uint8_t alpha = 0;
|
||||||
task->sdata->fill(nullptr, nullptr, nullptr, &alpha);
|
task->sdata->fill(nullptr, nullptr, nullptr, &alpha);
|
||||||
bool renderShape = (alpha > 0 || task->sdata->fill());
|
bool renderShape = (alpha > 0 || task->sdata->fill());
|
||||||
if (renderShape || strokeAlpha > 0) {
|
if (renderShape || strokeAlpha) {
|
||||||
if (!shapePrepare(task->shape, task->sdata, task->clip, task->transform)) return;
|
if (!shapePrepare(task->shape, task->sdata, task->clip, task->transform)) return;
|
||||||
if (renderShape) {
|
if (renderShape) {
|
||||||
if (!shapeGenRle(task->shape, task->sdata, task->clip)) return;
|
auto antiAlias = (strokeAlpha > 0 && strokeWidth >= 2) ? false : true;
|
||||||
|
if (!shapeGenRle(task->shape, task->sdata, task->clip, antiAlias)) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,7 @@ struct RleWorker
|
||||||
SwSize clip;
|
SwSize clip;
|
||||||
|
|
||||||
bool invalid;
|
bool invalid;
|
||||||
|
bool antiAlias;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -196,6 +197,7 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coverage > 0) {
|
if (coverage > 0) {
|
||||||
|
if (!rw.antiAlias) coverage = 255;
|
||||||
auto count = rw.spansCnt;
|
auto count = rw.spansCnt;
|
||||||
auto span = rw.spans + count - 1;
|
auto span = rw.spans + count - 1;
|
||||||
assert(span);
|
assert(span);
|
||||||
|
@ -261,22 +263,16 @@ static void _sweep(RleWorker& rw)
|
||||||
|
|
||||||
while (cell) {
|
while (cell) {
|
||||||
|
|
||||||
if (cell->x > x && cover != 0)
|
if (cell->x > x && cover != 0) _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), cell->x - x);
|
||||||
_horizLine(rw, x, y, cover * (ONE_PIXEL * 2), cell->x - x);
|
|
||||||
|
|
||||||
cover += cell->cover;
|
cover += cell->cover;
|
||||||
auto area = cover * (ONE_PIXEL * 2) - cell->area;
|
auto area = cover * (ONE_PIXEL * 2) - cell->area;
|
||||||
|
if (area != 0 && cell->x >= 0) _horizLine(rw, cell->x, y, area, 1);
|
||||||
//OPTIMIZE ME: This occurs 1 length span data.
|
|
||||||
if (area != 0 && cell->x >= 0)
|
|
||||||
_horizLine(rw, cell->x, y, area, 1);
|
|
||||||
|
|
||||||
x = cell->x + 1;
|
x = cell->x + 1;
|
||||||
cell = cell->next;
|
cell = cell->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cover != 0)
|
if (cover != 0) _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), rw.cellXCnt - x);
|
||||||
_horizLine(rw, x, y, cover * (ONE_PIXEL * 2), rw.cellXCnt - x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rw.spansCnt > 0) _genSpan(rw.rle, rw.spans, rw.spansCnt);
|
if (rw.spansCnt > 0) _genSpan(rw.rle, rw.spans, rw.spansCnt);
|
||||||
|
@ -648,7 +644,7 @@ static bool _genRle(RleWorker& rw)
|
||||||
/* External Class Implementation */
|
/* External Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip)
|
SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias)
|
||||||
{
|
{
|
||||||
//Please adjust when you out of cell memory (default: 16384L)
|
//Please adjust when you out of cell memory (default: 16384L)
|
||||||
constexpr auto RENDER_POOL_SIZE = 163840L * 2;
|
constexpr auto RENDER_POOL_SIZE = 163840L * 2;
|
||||||
|
@ -681,6 +677,7 @@ SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize&
|
||||||
rw.bandSize = rw.bufferSize / (sizeof(Cell) * 8); //bandSize: 64
|
rw.bandSize = rw.bufferSize / (sizeof(Cell) * 8); //bandSize: 64
|
||||||
rw.bandShoot = 0;
|
rw.bandShoot = 0;
|
||||||
rw.clip = clip;
|
rw.clip = clip;
|
||||||
|
rw.antiAlias = antiAlias;
|
||||||
rw.rle = reinterpret_cast<SwRleData*>(calloc(1, sizeof(SwRleData)));
|
rw.rle = reinterpret_cast<SwRleData*>(calloc(1, sizeof(SwRleData)));
|
||||||
assert(rw.rle);
|
assert(rw.rle);
|
||||||
|
|
||||||
|
|
|
@ -477,7 +477,7 @@ bool shapePrepare(SwShape& shape, const Shape* sdata, const SwSize& clip, const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip)
|
bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip, bool antiAlias)
|
||||||
{
|
{
|
||||||
//FIXME: Should we draw it?
|
//FIXME: Should we draw it?
|
||||||
//Case: Stroke Line
|
//Case: Stroke Line
|
||||||
|
@ -486,7 +486,7 @@ bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip)
|
||||||
//Case A: Fast Track Rectangle Drawing
|
//Case A: Fast Track Rectangle Drawing
|
||||||
if ((shape.rect = _fastTrack(shape.outline))) return true;
|
if ((shape.rect = _fastTrack(shape.outline))) return true;
|
||||||
//Case B: Normale Shape RLE Drawing
|
//Case B: Normale Shape RLE Drawing
|
||||||
if ((shape.rle = rleRender(shape.outline, shape.bbox, clip))) return true;
|
if ((shape.rle = rleRender(shape.outline, shape.bbox, clip, antiAlias))) return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -667,7 +667,7 @@ bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const SwSize& clip)
|
||||||
|
|
||||||
if (!_checkValid(strokeOutline, bbox, clip)) return false;
|
if (!_checkValid(strokeOutline, bbox, clip)) return false;
|
||||||
|
|
||||||
shape.strokeRle = rleRender(strokeOutline, bbox, clip);
|
shape.strokeRle = rleRender(strokeOutline, bbox, clip, true);
|
||||||
|
|
||||||
_delOutline(strokeOutline);
|
_delOutline(strokeOutline);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue