common sw_engine: code refactoring

Even though this enlarges the binary size by 300bytes,
use the array instead of individual implementations for better maintenance.
This commit is contained in:
Hermet Park 2023-07-17 16:46:30 +09:00 committed by Hermet Park
parent 5528eb9831
commit cf09ba5abd
7 changed files with 98 additions and 205 deletions

View file

@ -99,15 +99,11 @@ struct SwSize
struct SwOutline
{
SwPoint* pts; //the outline's points
uint32_t ptsCnt; //number of points in the glyph
uint32_t reservedPtsCnt;
uint32_t* cntrs; //the contour end points
uint16_t cntrsCnt; //number of contours in glyph
uint16_t reservedCntrsCnt;
uint8_t* types; //curve type
bool* closed; //opened or closed path?
FillRule fillRule;
Array<SwPoint> pts; //the outline's points
Array<uint32_t> cntrs; //the contour end points
Array<uint8_t> types; //curve type
Array<bool> closed; //opened or closed path?
FillRule fillRule;
};
struct SwSpan

View file

@ -39,18 +39,10 @@ static bool _genOutline(SwImage* image, const RenderMesh* mesh, const Matrix* tr
image->outline = mpoolReqOutline(mpool, tid);
auto outline = image->outline;
if (outline->reservedPtsCnt < 5) {
outline->reservedPtsCnt = 5;
outline->pts = static_cast<SwPoint*>(realloc(outline->pts, outline->reservedPtsCnt * sizeof(SwPoint)));
outline->types = static_cast<uint8_t*>(realloc(outline->types, outline->reservedPtsCnt * sizeof(uint8_t)));
}
if (outline->reservedCntrsCnt < 1) {
outline->reservedCntrsCnt = 1;
outline->cntrs = static_cast<uint32_t*>(realloc(outline->cntrs, outline->reservedCntrsCnt * sizeof(uint32_t)));
outline->closed = static_cast<bool*>(realloc(outline->closed, outline->reservedCntrsCnt * sizeof(bool)));
outline->closed[0] = true;
}
outline->pts.reserve(5);
outline->types.reserve(5);
outline->cntrs.reserve(1);
outline->closed.reserve(1);
Point to[4];
if (mesh->triangleCnt > 0) {
@ -97,17 +89,14 @@ static bool _genOutline(SwImage* image, const RenderMesh* mesh, const Matrix* tr
}
for (int i = 0; i < 4; i++) {
outline->pts[outline->ptsCnt] = mathTransform(&to[i], transform);
outline->types[outline->ptsCnt] = SW_CURVE_TYPE_POINT;
++outline->ptsCnt;
outline->pts.push(mathTransform(&to[i], transform));
outline->types.push(SW_CURVE_TYPE_POINT);
}
outline->pts[outline->ptsCnt] = outline->pts[0];
outline->types[outline->ptsCnt] = SW_CURVE_TYPE_POINT;
++outline->ptsCnt;
outline->cntrs[outline->cntrsCnt] = outline->ptsCnt - 1;
++outline->cntrsCnt;
outline->pts.push(outline->pts.data[0]);
outline->types.push(SW_CURVE_TYPE_POINT);
outline->cntrs.push(outline->pts.count - 1);
outline->closed.push(true);
image->outline = outline;

View file

@ -465,9 +465,9 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S
{
if (!outline) return false;
auto pt = outline->pts;
auto pt = outline->pts.data;
if (outline->ptsCnt == 0 || outline->cntrsCnt <= 0) {
if (outline->pts.count == 0 || outline->cntrs.count <= 0) {
renderRegion.reset();
return false;
}
@ -477,9 +477,7 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S
auto yMin = pt->y;
auto yMax = pt->y;
++pt;
for (uint32_t i = 1; i < outline->ptsCnt; ++i, ++pt) {
for (++pt; pt < outline->pts.end(); ++pt) {
if (xMin > pt->x) xMin = pt->x;
if (xMax < pt->x) xMax = pt->x;
if (yMin > pt->y) yMin = pt->y;

View file

@ -40,8 +40,10 @@ SwOutline* mpoolReqOutline(SwMpool* mpool, unsigned idx)
void mpoolRetOutline(SwMpool* mpool, unsigned idx)
{
mpool->outline[idx].cntrsCnt = 0;
mpool->outline[idx].ptsCnt = 0;
mpool->outline[idx].pts.clear();
mpool->outline[idx].cntrs.clear();
mpool->outline[idx].types.clear();
mpool->outline[idx].closed.clear();
}
@ -53,8 +55,10 @@ SwOutline* mpoolReqStrokeOutline(SwMpool* mpool, unsigned idx)
void mpoolRetStrokeOutline(SwMpool* mpool, unsigned idx)
{
mpool->strokeOutline[idx].cntrsCnt = 0;
mpool->strokeOutline[idx].ptsCnt = 0;
mpool->strokeOutline[idx].pts.clear();
mpool->strokeOutline[idx].cntrs.clear();
mpool->strokeOutline[idx].types.clear();
mpool->strokeOutline[idx].closed.clear();
}
@ -93,42 +97,19 @@ bool mpoolClear(SwMpool* mpool)
SwOutline* p;
for (unsigned i = 0; i < mpool->allocSize; ++i) {
//Outline
p = &mpool->outline[i];
free(p->cntrs);
p->cntrs = nullptr;
free(p->pts);
p->pts = nullptr;
free(p->types);
p->types = nullptr;
free(p->closed);
p->closed = nullptr;
p->cntrsCnt = p->reservedCntrsCnt = 0;
p->ptsCnt = p->reservedPtsCnt = 0;
p->pts.reset();
p->cntrs.reset();
p->types.reset();
p->closed.reset();
//StrokeOutline
p = &mpool->strokeOutline[i];
free(p->cntrs);
p->cntrs = nullptr;
free(p->pts);
p->pts = nullptr;
free(p->types);
p->types = nullptr;
free(p->closed);
p->closed = nullptr;
p->cntrsCnt = p->reservedCntrsCnt = 0;
p->ptsCnt = p->reservedPtsCnt = 0;
p->pts.reset();
p->cntrs.reset();
p->types.reset();
p->closed.reset();
}
return true;

View file

@ -713,17 +713,17 @@ static bool _decomposeOutline(RleWorker& rw)
auto outline = rw.outline;
auto first = 0; //index of first point in contour
for (uint32_t n = 0; n < outline->cntrsCnt; ++n) {
auto last = outline->cntrs[n];
auto limit = outline->pts + last;
auto start = UPSCALE(outline->pts[first]);
auto pt = outline->pts + first;
auto types = outline->types + first;
for (auto cntr = outline->cntrs.data; cntr < outline->cntrs.end(); ++cntr) {
auto last = *cntr;
auto limit = outline->pts.data + last;
auto start = UPSCALE(outline->pts.data[first]);
auto pt = outline->pts.data + first;
auto types = outline->types.data + first;
/* A contour cannot start with a cubic control point! */
if (types[0] == SW_CURVE_TYPE_CUBIC) goto invalid_outline;
_moveTo(rw, UPSCALE(outline->pts[first]));
_moveTo(rw, UPSCALE(outline->pts.data[first]));
while (pt < limit) {
++pt;

View file

@ -61,91 +61,39 @@ static void _lineSplitAt(const Line& cur, float at, Line& left, Line& right)
}
static bool _growOutlineContour(SwOutline& outline, uint32_t n)
{
if (outline.reservedCntrsCnt >= outline.cntrsCnt + n) return false;
outline.reservedCntrsCnt = outline.cntrsCnt + n;
outline.cntrs = static_cast<uint32_t*>(realloc(outline.cntrs, outline.reservedCntrsCnt * sizeof(uint32_t)));
return true;
}
static void _reserveOutlineClose(SwOutline& outline)
{
//Dash outlines are always opened.
//Only normal outlines use this information, it sholud be same to their contour counts.
if (outline.closed) free(outline.closed);
outline.closed = static_cast<bool*>(calloc(outline.reservedCntrsCnt, sizeof(bool)));
}
static void _resetOutlineClose(SwOutline& outline)
{
memset(outline.closed, 0x0, outline.reservedCntrsCnt * sizeof(bool));
}
static void _growOutlinePoint(SwOutline& outline, uint32_t n)
{
if (outline.reservedPtsCnt >= outline.ptsCnt + n) return;
outline.reservedPtsCnt = outline.ptsCnt + n;
outline.pts = static_cast<SwPoint*>(realloc(outline.pts, outline.reservedPtsCnt * sizeof(SwPoint)));
outline.types = static_cast<uint8_t*>(realloc(outline.types, outline.reservedPtsCnt * sizeof(uint8_t)));
}
static void _outlineEnd(SwOutline& outline)
{
if (outline.ptsCnt == 0) return;
_growOutlineContour(outline, 1);
outline.cntrs[outline.cntrsCnt] = outline.ptsCnt - 1;
++outline.cntrsCnt;
if (outline.pts.count == 0) return;
outline.cntrs.push(outline.pts.count - 1);
}
static void _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* transform)
{
_growOutlinePoint(outline, 1);
if (outline.pts.count > 0) outline.cntrs.push(outline.pts.count - 1);
outline.pts[outline.ptsCnt] = mathTransform(to, transform);
outline.types[outline.ptsCnt] = SW_CURVE_TYPE_POINT;
if (outline.ptsCnt > 0) {
_growOutlineContour(outline, 1);
outline.cntrs[outline.cntrsCnt] = outline.ptsCnt - 1;
++outline.cntrsCnt;
}
++outline.ptsCnt;
outline.pts.push(mathTransform(to, transform));
outline.types.push(SW_CURVE_TYPE_POINT);
}
static void _outlineLineTo(SwOutline& outline, const Point* to, const Matrix* transform)
{
_growOutlinePoint(outline, 1);
outline.pts[outline.ptsCnt] = mathTransform(to, transform);
outline.types[outline.ptsCnt] = SW_CURVE_TYPE_POINT;
++outline.ptsCnt;
outline.pts.push(mathTransform(to, transform));
outline.types.push(SW_CURVE_TYPE_POINT);
}
static void _outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix* transform)
{
_growOutlinePoint(outline, 3);
outline.pts.push(mathTransform(ctrl1, transform));
outline.types.push(SW_CURVE_TYPE_CUBIC);
outline.pts[outline.ptsCnt] = mathTransform(ctrl1, transform);
outline.types[outline.ptsCnt] = SW_CURVE_TYPE_CUBIC;
++outline.ptsCnt;
outline.pts.push(mathTransform(ctrl2, transform));
outline.types.push(SW_CURVE_TYPE_CUBIC);
outline.pts[outline.ptsCnt] = mathTransform(ctrl2, transform);
outline.types[outline.ptsCnt] = SW_CURVE_TYPE_CUBIC;
++outline.ptsCnt;
outline.pts[outline.ptsCnt] = mathTransform(to, transform);
outline.types[outline.ptsCnt] = SW_CURVE_TYPE_POINT;
++outline.ptsCnt;
outline.pts.push(mathTransform(to, transform));
outline.types.push(SW_CURVE_TYPE_POINT);
}
@ -153,30 +101,21 @@ static void _outlineClose(SwOutline& outline)
{
uint32_t i = 0;
if (outline.cntrsCnt > 0) {
i = outline.cntrs[outline.cntrsCnt - 1] + 1;
} else {
i = 0; //First Path
}
if (outline.cntrs.count > 0) i = outline.cntrs.last() + 1;
else i = 0; //First Path
//Make sure there is at least one point in the current path
if (outline.ptsCnt == i) return;
if (outline.pts.count == i) return;
//Close the path
_growOutlinePoint(outline, 1);
outline.pts[outline.ptsCnt] = outline.pts[i];
outline.types[outline.ptsCnt] = SW_CURVE_TYPE_POINT;
++outline.ptsCnt;
outline.closed[outline.cntrsCnt] = true;
outline.pts.push(outline.pts.data[i]);
outline.types.push(SW_CURVE_TYPE_POINT);
outline.closed.push(true);
}
static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* transform)
{
_growOutlinePoint(*dash.outline, dash.outline->ptsCnt >> 1);
_growOutlineContour(*dash.outline, dash.outline->cntrsCnt >> 1);
Line cur = {dash.ptCur, *to};
auto len = _lineLength(cur.pt1, cur.pt2);
@ -220,9 +159,6 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans
static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix* transform)
{
_growOutlinePoint(*dash.outline, dash.outline->ptsCnt >> 1);
_growOutlineContour(*dash.outline, dash.outline->cntrsCnt >> 1);
Bezier cur = {dash.ptCur, *ctrl1, *ctrl2, *to};
auto len = bezLength(cur);
@ -323,8 +259,9 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
++outlineCntrsCnt; //for end
//No idea exact count.... Reserve Approximitely 20x...
_growOutlinePoint(*dash.outline, outlinePtsCnt * 20);
_growOutlineContour(*dash.outline, outlineCntrsCnt * 20);
dash.outline->pts.grow(20 * outlinePtsCnt);
dash.outline->types.grow(20 * outlinePtsCnt);
dash.outline->cntrs.grow(20 * outlineCntrsCnt);
while (cmdCnt-- > 0) {
switch (*cmds) {
@ -364,12 +301,12 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans
static bool _axisAlignedRect(const SwOutline* outline)
{
//Fast Track: axis-aligned rectangle?
if (outline->ptsCnt != 5) return false;
if (outline->pts.count != 5) return false;
auto pt1 = outline->pts + 0;
auto pt2 = outline->pts + 1;
auto pt3 = outline->pts + 2;
auto pt4 = outline->pts + 3;
auto pt1 = outline->pts.data + 0;
auto pt2 = outline->pts.data + 1;
auto pt3 = outline->pts.data + 2;
auto pt4 = outline->pts.data + 3;
auto a = SwPoint{pt1->x, pt3->y};
auto b = SwPoint{pt3->x, pt1->y};
@ -380,7 +317,6 @@ static bool _axisAlignedRect(const SwOutline* outline)
}
static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix* transform, SwMpool* mpool, unsigned tid, bool hasComposite)
{
const PathCommand* cmds = rshape->path.cmds.data;
@ -431,13 +367,15 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix*
shape->outline = mpoolReqOutline(mpool, tid);
auto outline = shape->outline;
_growOutlinePoint(*outline, outlinePtsCnt);
outline->pts.grow(outlinePtsCnt);
outline->types.grow(outlinePtsCnt);
outline->cntrs.grow(outlineCntrsCnt);
if (_growOutlineContour(*outline, outlineCntrsCnt)) {
_reserveOutlineClose(*outline);
} else {
_resetOutlineClose(*outline);
}
//Dash outlines are always opened.
//Only normal outlines use this information, it sholud be same to their contour counts.
outline->closed.reserve(outline->cntrs.reserved);
memset(outline->closed.data, 0x0, sizeof(bool) * outline->closed.reserved);
//Generate Outlines
while (cmdCnt-- > 0) {
@ -605,10 +543,10 @@ bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix*
fail:
if (freeOutline) {
if (shapeOutline->cntrs) free(shapeOutline->cntrs);
if (shapeOutline->pts) free(shapeOutline->pts);
if (shapeOutline->types) free(shapeOutline->types);
if (shapeOutline->closed) free(shapeOutline->closed);
free(shapeOutline->cntrs.data);
free(shapeOutline->pts.data);
free(shapeOutline->types.data);
free(shapeOutline->closed.data);
free(shapeOutline);
}
mpoolRetStrokeOutline(mpool, tid);

View file

@ -780,33 +780,29 @@ static void _exportBorderOutline(const SwStroke& stroke, SwOutline* outline, uin
if (border->ptsCnt == 0) return; //invalid border
memcpy(outline->pts + outline->ptsCnt, border->pts, border->ptsCnt * sizeof(SwPoint));
memcpy(outline->pts.data + outline->pts.count, border->pts, border->ptsCnt * sizeof(SwPoint));
auto cnt = border->ptsCnt;
auto src = border->tags;
auto tags = outline->types + outline->ptsCnt;
auto cntrs = outline->cntrs + outline->cntrsCnt;
auto idx = outline->ptsCnt;
auto tags = outline->types.data + outline->types.count;
auto idx = outline->pts.count;
while (cnt > 0) {
if (*src & SW_STROKE_TAG_POINT) *tags = SW_CURVE_TYPE_POINT;
else if (*src & SW_STROKE_TAG_CUBIC) *tags = SW_CURVE_TYPE_CUBIC;
else {
//LOG: What type of stroke outline??
}
if (*src & SW_STROKE_TAG_END) {
*cntrs = idx;
++cntrs;
++outline->cntrsCnt;
}
if (*src & SW_STROKE_TAG_END) outline->cntrs.push(idx);
++src;
++tags;
++idx;
--cnt;
}
outline->ptsCnt = outline->ptsCnt + border->ptsCnt;
outline->pts.count += border->ptsCnt;
outline->types.count += border->ptsCnt;
}
@ -857,10 +853,11 @@ void strokeReset(SwStroke* stroke, const RenderShape* rshape, const Matrix* tran
bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline)
{
uint32_t first = 0;
uint32_t i = 0;
for (uint32_t i = 0; i < outline.cntrsCnt; ++i) {
auto last = outline.cntrs[i]; //index of last point in contour
auto limit = outline.pts + last;
for (auto cntr = outline.cntrs.data; cntr < outline.cntrs.end(); ++cntr, ++i) {
auto last = *cntr; //index of last point in contour
auto limit = outline.pts.data + last;
//Skip empty points
if (last <= first) {
@ -868,15 +865,15 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline)
continue;
}
auto start = outline.pts[first];
auto pt = outline.pts + first;
auto types = outline.types + first;
auto start = outline.pts.data[first];
auto pt = outline.pts.data + first;
auto types = outline.types.data + first;
auto type = types[0];
//A contour cannot start with a cubic control point
if (type == SW_CURVE_TYPE_CUBIC) return false;
auto closed = outline.closed ? outline.closed[i]: false;
auto closed = outline.closed.data ? outline.closed.data[i]: false;
_beginSubPath(*stroke, start, closed);
@ -922,15 +919,9 @@ SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid)
auto cntrsCnt = count2 + count4;
auto outline = mpoolReqStrokeOutline(mpool, tid);
if (outline->reservedPtsCnt < ptsCnt) {
outline->pts = static_cast<SwPoint*>(realloc(outline->pts, sizeof(SwPoint) * ptsCnt));
outline->types = static_cast<uint8_t*>(realloc(outline->types, sizeof(uint8_t) * ptsCnt));
outline->reservedPtsCnt = ptsCnt;
}
if (outline->reservedCntrsCnt < cntrsCnt) {
outline->cntrs = static_cast<uint32_t*>(realloc(outline->cntrs, sizeof(uint32_t) * cntrsCnt));
outline->reservedCntrsCnt = cntrsCnt;
}
outline->pts.reserve(ptsCnt);
outline->types.reserve(ptsCnt);
outline->cntrs.reserve(cntrsCnt);
_exportBorderOutline(*stroke, outline, 0); //left
_exportBorderOutline(*stroke, outline, 1); //right