From cf09ba5abd2206058e17b068f9350a8ab99cc43c Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 17 Jul 2023 16:46:30 +0900 Subject: [PATCH] common sw_engine: code refactoring Even though this enlarges the binary size by 300bytes, use the array instead of individual implementations for better maintenance. --- src/lib/sw_engine/tvgSwCommon.h | 14 ++- src/lib/sw_engine/tvgSwImage.cpp | 31 +++---- src/lib/sw_engine/tvgSwMath.cpp | 8 +- src/lib/sw_engine/tvgSwMemPool.cpp | 51 ++++------- src/lib/sw_engine/tvgSwRle.cpp | 14 +-- src/lib/sw_engine/tvgSwShape.cpp | 140 ++++++++--------------------- src/lib/sw_engine/tvgSwStroke.cpp | 45 ++++------ 7 files changed, 98 insertions(+), 205 deletions(-) diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index a39d4798..0eb86636 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -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 pts; //the outline's points + Array cntrs; //the contour end points + Array types; //curve type + Array closed; //opened or closed path? + FillRule fillRule; }; struct SwSpan diff --git a/src/lib/sw_engine/tvgSwImage.cpp b/src/lib/sw_engine/tvgSwImage.cpp index 9e215dbe..4829a8c8 100644 --- a/src/lib/sw_engine/tvgSwImage.cpp +++ b/src/lib/sw_engine/tvgSwImage.cpp @@ -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(realloc(outline->pts, outline->reservedPtsCnt * sizeof(SwPoint))); - outline->types = static_cast(realloc(outline->types, outline->reservedPtsCnt * sizeof(uint8_t))); - } - - if (outline->reservedCntrsCnt < 1) { - outline->reservedCntrsCnt = 1; - outline->cntrs = static_cast(realloc(outline->cntrs, outline->reservedCntrsCnt * sizeof(uint32_t))); - outline->closed = static_cast(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; diff --git a/src/lib/sw_engine/tvgSwMath.cpp b/src/lib/sw_engine/tvgSwMath.cpp index 5a4f58d9..bd7d0215 100644 --- a/src/lib/sw_engine/tvgSwMath.cpp +++ b/src/lib/sw_engine/tvgSwMath.cpp @@ -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; diff --git a/src/lib/sw_engine/tvgSwMemPool.cpp b/src/lib/sw_engine/tvgSwMemPool.cpp index 05ff9ddf..936d9cbd 100644 --- a/src/lib/sw_engine/tvgSwMemPool.cpp +++ b/src/lib/sw_engine/tvgSwMemPool.cpp @@ -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; diff --git a/src/lib/sw_engine/tvgSwRle.cpp b/src/lib/sw_engine/tvgSwRle.cpp index a0c36b1c..a3982622 100644 --- a/src/lib/sw_engine/tvgSwRle.cpp +++ b/src/lib/sw_engine/tvgSwRle.cpp @@ -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; diff --git a/src/lib/sw_engine/tvgSwShape.cpp b/src/lib/sw_engine/tvgSwShape.cpp index ad7ae3a1..8568577c 100644 --- a/src/lib/sw_engine/tvgSwShape.cpp +++ b/src/lib/sw_engine/tvgSwShape.cpp @@ -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(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(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(realloc(outline.pts, outline.reservedPtsCnt * sizeof(SwPoint))); - outline.types = static_cast(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); diff --git a/src/lib/sw_engine/tvgSwStroke.cpp b/src/lib/sw_engine/tvgSwStroke.cpp index c1584b5e..0c4fd718 100644 --- a/src/lib/sw_engine/tvgSwStroke.cpp +++ b/src/lib/sw_engine/tvgSwStroke.cpp @@ -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(realloc(outline->pts, sizeof(SwPoint) * ptsCnt)); - outline->types = static_cast(realloc(outline->types, sizeof(uint8_t) * ptsCnt)); - outline->reservedPtsCnt = ptsCnt; - } - if (outline->reservedCntrsCnt < cntrsCnt) { - outline->cntrs = static_cast(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