From 2c9610bf6abac5c6332abe34cfc8e843ba60c884 Mon Sep 17 00:00:00 2001 From: Michal Szczecinski Date: Tue, 11 Aug 2020 12:11:06 +0200 Subject: [PATCH 01/16] common_shape: fixed arc api to draw rectangles lower than 0. Absolute value is used to calculate number of bezier curves used to approximate arc. Change-Id: Idedd7fd73590d569417fc646fc7febdaaab65857 --- src/lib/tvgShape.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/tvgShape.cpp b/src/lib/tvgShape.cpp index 8b17186..c688ffc 100644 --- a/src/lib/tvgShape.cpp +++ b/src/lib/tvgShape.cpp @@ -167,7 +167,7 @@ Result Shape::appendArc(float cx, float cy, float radius, float startAngle, floa startAngle = (startAngle * M_PI) / 180; sweep = sweep * M_PI / 180; - auto nCurves = ceil(sweep / M_PI_HALF); + auto nCurves = ceil(abs(sweep / M_PI_HALF)); auto fract = fmod(sweep, M_PI_HALF); fract = (fract < std::numeric_limits::epsilon()) ? M_PI_HALF : fract; -- 2.7.4 From a12f346425774932f4fc18a4ad9dc75288ba17d5 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 13 Aug 2020 19:00:09 +0900 Subject: [PATCH 02/16] sw_engine: remove unnecessary assert() call Change-Id: I7c665bab4ef867f912ea738480e6d9b2b63e014e --- src/lib/sw_engine/tvgSwStroke.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/lib/sw_engine/tvgSwStroke.cpp b/src/lib/sw_engine/tvgSwStroke.cpp index d8902da..edba638 100644 --- a/src/lib/sw_engine/tvgSwStroke.cpp +++ b/src/lib/sw_engine/tvgSwStroke.cpp @@ -880,7 +880,6 @@ bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline) 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; - assert(limit); //Skip empty points if (last <= first) { @@ -889,12 +888,8 @@ bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline) } auto start = outline.pts[first]; - auto pt = outline.pts + first; - assert(pt); auto types = outline.types + first; - assert(types); - auto type = types[0]; //A contour cannot start with a cubic control point @@ -903,8 +898,8 @@ bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline) _beginSubPath(stroke, start, outline.opened); while (pt < limit) { - assert(++pt); - assert(++types); + ++pt; + ++types; //emit a signel line_to if (types[0] == SW_CURVE_TYPE_POINT) { -- 2.7.4 From 0b95e55e2ff01f0a41ac787c68dadc5889c42d28 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 13 Aug 2020 19:02:31 +0900 Subject: [PATCH 03/16] gl_engine renderer: initialize member data in default. static analizyer bothers us due to this. we'd rather initialize members for free of them. Change-Id: Ifa6ebffdfdcb31d2dd3a1d6b911226928f654e3f --- src/lib/gl_engine/tvgGlRenderer.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/gl_engine/tvgGlRenderer.h b/src/lib/gl_engine/tvgGlRenderer.h index 9c893b3..9a86bae 100644 --- a/src/lib/gl_engine/tvgGlRenderer.h +++ b/src/lib/gl_engine/tvgGlRenderer.h @@ -30,7 +30,7 @@ class GlRenderer : public RenderMethod { public: - Surface surface; + Surface surface = {nullptr, 0, 0, 0}; void* prepare(const Shape& shape, void* data, const RenderTransform* transform, RenderUpdateFlag flags) override; bool dispose(const Shape& shape, void *data) override; @@ -54,9 +54,9 @@ private: void initShaders(); void drawPrimitive(GlGeometry& geometry, float r, float g, float b, float a, uint32_t primitiveIndex, RenderUpdateFlag flag); - unique_ptr mColorProgram; - int32_t mColorUniformLoc; - uint32_t mVertexAttrLoc; + unique_ptr mColorProgram = nullptr; + int32_t mColorUniformLoc = 0; + uint32_t mVertexAttrLoc = 0; }; #endif /* _TVG_GL_RENDERER_H_ */ -- 2.7.4 From 9ce44de97010d3200e81c9e12da02b18028ea423 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 13 Aug 2020 19:08:34 +0900 Subject: [PATCH 04/16] svg_loader: initialize member data in default. static analizyer bothers us due to this. we'd rather initialize members for free of them. Change-Id: I6dd76427b0fe2f9ff09034fe3ab11080a8d72a2e --- src/loaders/svg_loader/tvgSvgSceneBuilder.cpp | 1 - src/loaders/svg_loader/tvgSvgSceneBuilder.h | 8 ++------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp index 091f78a..faea2ec 100644 --- a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp @@ -373,7 +373,6 @@ unique_ptr SvgSceneBuilder::build(SvgNode* node) viewBox.w = node->node.doc.vw; viewBox.h = node->node.doc.vh; preserveAspect = node->node.doc.preserveAspect; - staticViewBox = true; return _sceneBuildHelper(node, viewBox.x, viewBox.y, viewBox.w, viewBox.h, 255); } diff --git a/src/loaders/svg_loader/tvgSvgSceneBuilder.h b/src/loaders/svg_loader/tvgSvgSceneBuilder.h index 66f5047..0f93d96 100644 --- a/src/loaders/svg_loader/tvgSvgSceneBuilder.h +++ b/src/loaders/svg_loader/tvgSvgSceneBuilder.h @@ -32,12 +32,8 @@ private: struct { int x, y; uint32_t w, h; - } viewBox; - int ref; - uint32_t w, h; //Default size - bool staticViewBox; - bool preserveAspect; //Used in SVG - bool shareable; + } viewBox = {0, 0, 0, 0}; + bool preserveAspect = false; public: SvgSceneBuilder(); -- 2.7.4 From 199b54c5caf8dd8ef25b065d310bd08ae7fb661b Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 13 Aug 2020 19:13:17 +0900 Subject: [PATCH 05/16] common: code refactoring. we can return nullptr directly here. Change-Id: I35e04dc9850b3b3b75e1e02b4c81a61b79f2c43f --- src/lib/tvgGlCanvas.cpp | 2 +- src/lib/tvgSwCanvas.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/tvgGlCanvas.cpp b/src/lib/tvgGlCanvas.cpp index 755d8eb..7f2c04b 100644 --- a/src/lib/tvgGlCanvas.cpp +++ b/src/lib/tvgGlCanvas.cpp @@ -86,7 +86,7 @@ unique_ptr GlCanvas::gen() noexcept return canvas; #endif - return unique_ptr(nullptr); + return nullptr; } diff --git a/src/lib/tvgSwCanvas.cpp b/src/lib/tvgSwCanvas.cpp index bb50470..e958ea2 100644 --- a/src/lib/tvgSwCanvas.cpp +++ b/src/lib/tvgSwCanvas.cpp @@ -85,7 +85,7 @@ unique_ptr SwCanvas::gen() noexcept return canvas; #endif - return unique_ptr(nullptr); + return nullptr; } #endif /* _TVG_SWCANVAS_CPP_ */ -- 2.7.4 From 7b004363f9826faba339fee469e777423fa9c079 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 13 Aug 2020 19:15:33 +0900 Subject: [PATCH 06/16] sw_engine renderer: initialize member data in default. static analizyer bothers us due to this. we'd rather initialize members for free of them. Change-Id: I23b769b94be7514a8bf6e6d683ddb90b3cd613c4 --- src/lib/sw_engine/tvgSwRenderer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/sw_engine/tvgSwRenderer.h b/src/lib/sw_engine/tvgSwRenderer.h index b6c7a19..d34c83c 100644 --- a/src/lib/sw_engine/tvgSwRenderer.h +++ b/src/lib/sw_engine/tvgSwRenderer.h @@ -52,7 +52,7 @@ public: void doRender(); //Internally used for threading private: - Surface surface; + Surface surface = {nullptr, 0, 0, 0}; future progress; queue prepareTasks; queue renderTasks; -- 2.7.4 From 3dc3cfd8c0726ad2571a101747df724638cc8f14 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 13 Aug 2020 19:27:02 +0900 Subject: [PATCH 07/16] sw_engine: fix data overflow case. Change-Id: I01f90a8a6b3bca38142c8c16d1990b5b1a09d081 --- src/lib/sw_engine/tvgSwStroke.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/sw_engine/tvgSwStroke.cpp b/src/lib/sw_engine/tvgSwStroke.cpp index edba638..70eb1ca 100644 --- a/src/lib/sw_engine/tvgSwStroke.cpp +++ b/src/lib/sw_engine/tvgSwStroke.cpp @@ -35,7 +35,7 @@ static constexpr auto SW_STROKE_TAG_END = 8; static inline SwFixed SIDE_TO_ROTATE(const int32_t s) { - return (SW_ANGLE_PI2 - (s) * SW_ANGLE_PI); + return (SW_ANGLE_PI2 - static_cast(s) * SW_ANGLE_PI); } -- 2.7.4 From 8abef404cf026d7740c835c393ca516d7d17d849 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 13 Aug 2020 19:29:23 +0900 Subject: [PATCH 08/16] sw_engine: remove unnecessary assert() call Change-Id: I8cb249b6b7f32992f7ce9c86e408546c14856330 --- src/lib/sw_engine/tvgSwRle.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/lib/sw_engine/tvgSwRle.cpp b/src/lib/sw_engine/tvgSwRle.cpp index 191e59e..6f1f2f2 100644 --- a/src/lib/sw_engine/tvgSwRle.cpp +++ b/src/lib/sw_engine/tvgSwRle.cpp @@ -571,21 +571,14 @@ static void _cubicTo(RleWorker& rw, const SwPoint& ctrl1, const SwPoint& ctrl2, static bool _decomposeOutline(RleWorker& rw) { auto outline = rw.outline; - assert(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; - assert(limit); - auto start = UPSCALE(outline->pts[first]); - auto pt = outline->pts + first; - assert(pt); auto types = outline->types + first; - assert(types); /* A contour cannot start with a cubic control point! */ if (types[0] == SW_CURVE_TYPE_CUBIC) goto invalid_outline; @@ -593,8 +586,8 @@ static bool _decomposeOutline(RleWorker& rw) _moveTo(rw, UPSCALE(outline->pts[first])); while (pt < limit) { - assert(++pt); - assert(++types); + ++pt; + ++types; //emit a single line_to if (types[0] == SW_CURVE_TYPE_POINT) { -- 2.7.4 From 3b9bb51321bb9b6aa5aba78ac984915a8eb9d854 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 13 Aug 2020 19:41:34 +0900 Subject: [PATCH 09/16] svg_loader: free allocated data properly. also renamed internal function for consistency. createNode() cloneNode() freeSVGNode() ? Change-Id: Ie9b22e92d5e918e947f8476ad0d4682fc7a3be65 --- src/loaders/svg_loader/tvgSvgLoader.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/loaders/svg_loader/tvgSvgLoader.cpp b/src/loaders/svg_loader/tvgSvgLoader.cpp index 0529ec8..205e8cb 100644 --- a/src/loaders/svg_loader/tvgSvgLoader.cpp +++ b/src/loaders/svg_loader/tvgSvgLoader.cpp @@ -33,7 +33,7 @@ typedef SvgNode* (*FactoryMethod)(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength); typedef SvgStyleGradient* (*GradientFactoryMethod)(SvgLoaderData* loader, const char* buf, unsigned bufLength); - +static void _freeNode(SvgNode* node); static char* _skipSpace(const char* str, const char* end) { @@ -1459,6 +1459,8 @@ static void _cloneNode(SvgNode* from, SvgNode* parent) for (vector::iterator itrChild = from->child.begin(); itrChild != from->child.end(); itrChild++) { _cloneNode(*itrChild, newNode); } + + _freeNode(newNode); } @@ -2161,12 +2163,12 @@ static void _freeNodeStyle(SvgStyleProperty* style) free(style); } -static void _freeSvgNode(SvgNode* node) +static void _freeNode(SvgNode* node) { if (!node) return; for(vector::iterator itrChild = node->child.begin(); itrChild != node->child.end(); itrChild++) { - _freeSvgNode(*itrChild); + _freeNode(*itrChild); } node->child.clear(); @@ -2187,7 +2189,7 @@ static void _freeSvgNode(SvgNode* node) break; } case SvgNodeType::Doc: { - _freeSvgNode(node->node.doc.defs); + _freeNode(node->node.doc.defs); break; } case SvgNodeType::Defs: { @@ -2360,7 +2362,7 @@ bool SvgLoader::close() free(loaderData.svgParse); loaderData.svgParse = nullptr; } - _freeSvgNode(loaderData.doc); + _freeNode(loaderData.doc); loaderData.doc = nullptr; return true; -- 2.7.4 From ac4405a4ec29ce5c7a324117c9b45c1f7d62fa09 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 13 Aug 2020 19:50:46 +0900 Subject: [PATCH 10/16] sw_engine: fix potential data overflow. Change-Id: Ie800fda74d44ad3741f7a92f12681f7f753ee50c --- src/lib/sw_engine/tvgSwMath.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/sw_engine/tvgSwMath.cpp b/src/lib/sw_engine/tvgSwMath.cpp index 3676048..5ac3912 100644 --- a/src/lib/sw_engine/tvgSwMath.cpp +++ b/src/lib/sw_engine/tvgSwMath.cpp @@ -377,7 +377,7 @@ SwFixed mathLength(SwPoint& pt) _polarize(v); v.x = _downscale(v.x); - if (shift > 0) return (v.x + (1 << (shift -1))) >> shift; + if (shift > 0) return (v.x + (static_cast(1) << (shift -1))) >> shift; return static_cast((uint32_t)v.x << -shift); } -- 2.7.4 From 3b22a25798167299c99119970676aa411186b7b4 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 13 Aug 2020 19:59:01 +0900 Subject: [PATCH 11/16] gl_engine: engine should return shape data for resuing it. Change-Id: I45f7ecbdb707b0751894e01d273b149402e089af --- src/lib/gl_engine/tvgGlRenderer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/gl_engine/tvgGlRenderer.cpp b/src/lib/gl_engine/tvgGlRenderer.cpp index 0276c8f..a295ed6 100644 --- a/src/lib/gl_engine/tvgGlRenderer.cpp +++ b/src/lib/gl_engine/tvgGlRenderer.cpp @@ -129,16 +129,16 @@ void* GlRenderer::prepare(const Shape& shape, void* data, TVG_UNUSED const Rende { //prepare shape data GlShape* sdata = static_cast(data); - if (!sdata) - { + if (!sdata) { sdata = new GlShape; - assert(sdata); + if (!sdata) return nullptr; } + sdata->viewWd = static_cast(surface.w); sdata->viewHt = static_cast(surface.h); sdata->updateFlag = flags; - if (sdata->updateFlag == RenderUpdateFlag::None) return nullptr; + if (sdata->updateFlag == RenderUpdateFlag::None) return sdata; initShaders(); -- 2.7.4 From 9dd3cc5edc8f43473cfa163b46e83a02a54eed00 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 13 Aug 2020 20:05:37 +0900 Subject: [PATCH 12/16] common: code refactoring. we can return nullptr directly here. Change-Id: Ic1d987f2701d20ff1b69af2854f9cfee7e2fe065 --- src/lib/tvgLoaderMgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/tvgLoaderMgr.cpp b/src/lib/tvgLoaderMgr.cpp index 208ba79..a35dcd5 100644 --- a/src/lib/tvgLoaderMgr.cpp +++ b/src/lib/tvgLoaderMgr.cpp @@ -56,7 +56,7 @@ unique_ptr LoaderMgr::loader(const char* path) return unique_ptr(new SvgLoader); #endif cout << "Non supported format: " << path << endl; - return unique_ptr(nullptr); + return nullptr; } #endif //_TVG_LOADER_MGR_CPP_ \ No newline at end of file -- 2.7.4 From 72891162274dba579be585034140663193fab897 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 13 Aug 2020 20:39:34 +0900 Subject: [PATCH 13/16] remove std async usage. we can't control any threads count that could drop the performance. remove async() and will come back with fine-tuned threading-pool. Change-Id: I17c39792234acfce6db334abc0ce12da23978a9a --- src/lib/sw_engine/tvgSwCommon.h | 38 +++---- src/lib/sw_engine/tvgSwRaster.cpp | 30 ++--- src/lib/sw_engine/tvgSwRenderer.cpp | 188 +++++++++----------------------- src/lib/sw_engine/tvgSwRenderer.h | 12 -- src/lib/sw_engine/tvgSwShape.cpp | 105 +++++++++--------- src/lib/sw_engine/tvgSwStroke.cpp | 48 ++++---- src/lib/tvgRender.h | 12 +- src/loaders/svg_loader/tvgSvgLoader.cpp | 54 +++++---- src/loaders/svg_loader/tvgSvgLoader.h | 3 +- 9 files changed, 197 insertions(+), 293 deletions(-) diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index e7566c1..295f11a 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -269,22 +269,22 @@ SwFixed mathLength(SwPoint& pt); bool mathSmallCubic(SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut); SwFixed mathMean(SwFixed angle1, SwFixed angle2); -void shapeReset(SwShape& shape); -bool shapeGenOutline(SwShape& shape, const Shape* sdata, 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 antiAlias); -void shapeDelOutline(SwShape& shape); -void shapeResetStroke(SwShape& shape, const Shape* sdata, const Matrix* transform); -bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transform, const SwSize& clip); -void shapeFree(SwShape& shape); -void shapeDelStroke(SwShape& shape); -bool shapeGenFillColors(SwShape& shape, const Fill* fill, const Matrix* transform, bool ctable); -void shapeResetFill(SwShape& shape); -void shapeDelFill(SwShape& shape); - -void strokeReset(SwStroke& stroke, const Shape* shape, const Matrix* transform); -bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline); -SwOutline* strokeExportOutline(SwStroke& stroke); +void shapeReset(SwShape* shape); +bool shapeGenOutline(SwShape* shape, const Shape* sdata, 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 antiAlias); +void shapeDelOutline(SwShape* shape); +void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform); +bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwSize& clip); +void shapeFree(SwShape* shape); +void shapeDelStroke(SwShape* shape); +bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, bool ctable); +void shapeResetFill(SwShape* shape); +void shapeDelFill(SwShape* shape); + +void strokeReset(SwStroke* stroke, const Shape* shape, const Matrix* transform); +bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline); +SwOutline* strokeExportOutline(SwStroke* stroke); void strokeFree(SwStroke* stroke); bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, bool ctable); @@ -296,9 +296,9 @@ void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias); void rleFree(SwRleData* rle); -bool rasterGradientShape(Surface& surface, SwShape& shape, unsigned id); -bool rasterSolidShape(Surface& surface, SwShape& shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); -bool rasterStroke(Surface& surface, SwShape& shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); +bool rasterGradientShape(Surface& surface, SwShape* shape, unsigned id); +bool rasterSolidShape(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); +bool rasterStroke(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); bool rasterClear(Surface& surface); diff --git a/src/lib/sw_engine/tvgSwRaster.cpp b/src/lib/sw_engine/tvgSwRaster.cpp index 98579c5..46ef4ac 100644 --- a/src/lib/sw_engine/tvgSwRaster.cpp +++ b/src/lib/sw_engine/tvgSwRaster.cpp @@ -273,48 +273,48 @@ static bool _rasterRadialGradientRle(Surface& surface, SwRleData* rle, const SwF /* External Class Implementation */ /************************************************************************/ -bool rasterGradientShape(Surface& surface, SwShape& shape, unsigned id) +bool rasterGradientShape(Surface& surface, SwShape* shape, unsigned id) { //Fast Track - if (shape.rect) { - auto region = _clipRegion(surface, shape.bbox); - if (id == FILL_ID_LINEAR) return _rasterLinearGradientRect(surface, region, shape.fill); - return _rasterRadialGradientRect(surface, region, shape.fill); + if (shape->rect) { + auto region = _clipRegion(surface, shape->bbox); + if (id == FILL_ID_LINEAR) return _rasterLinearGradientRect(surface, region, shape->fill); + return _rasterRadialGradientRect(surface, region, shape->fill); } else { - if (id == FILL_ID_LINEAR) return _rasterLinearGradientRle(surface, shape.rle, shape.fill); - return _rasterRadialGradientRle(surface, shape.rle, shape.fill); + if (id == FILL_ID_LINEAR) return _rasterLinearGradientRle(surface, shape->rle, shape->fill); + return _rasterRadialGradientRle(surface, shape->rle, shape->fill); } return false; } -bool rasterSolidShape(Surface& surface, SwShape& shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +bool rasterSolidShape(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { r = COLOR_ALPHA_MULTIPLY(r, a); g = COLOR_ALPHA_MULTIPLY(g, a); b = COLOR_ALPHA_MULTIPLY(b, a); //Fast Track - if (shape.rect) { - auto region = _clipRegion(surface, shape.bbox); + if (shape->rect) { + auto region = _clipRegion(surface, shape->bbox); if (a == 255) return _rasterSolidRect(surface, region, COLOR_ARGB_JOIN(r, g, b, a)); return _rasterTranslucentRect(surface, region, COLOR_ARGB_JOIN(r, g, b, a)); } else{ - if (a == 255) return _rasterSolidRle(surface, shape.rle, COLOR_ARGB_JOIN(r, g, b, a)); - return _rasterTranslucentRle(surface, shape.rle, COLOR_ARGB_JOIN(r, g, b, a)); + if (a == 255) return _rasterSolidRle(surface, shape->rle, COLOR_ARGB_JOIN(r, g, b, a)); + return _rasterTranslucentRle(surface, shape->rle, COLOR_ARGB_JOIN(r, g, b, a)); } return false; } -bool rasterStroke(Surface& surface, SwShape& shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +bool rasterStroke(Surface& surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { r = COLOR_ALPHA_MULTIPLY(r, a); g = COLOR_ALPHA_MULTIPLY(g, a); b = COLOR_ALPHA_MULTIPLY(b, a); - if (a == 255) return _rasterSolidRle(surface, shape.strokeRle, COLOR_ARGB_JOIN(r, g, b, a)); - return _rasterTranslucentRle(surface, shape.strokeRle, COLOR_ARGB_JOIN(r, g, b, a)); + if (a == 255) return _rasterSolidRle(surface, shape->strokeRle, COLOR_ARGB_JOIN(r, g, b, a)); + return _rasterTranslucentRle(surface, shape->strokeRle, COLOR_ARGB_JOIN(r, g, b, a)); } diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index 92fddfb..eb2f199 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -22,27 +22,12 @@ #ifndef _TVG_SW_RENDERER_CPP_ #define _TVG_SW_RENDERER_CPP_ -using namespace std; - #include "tvgSwCommon.h" #include "tvgSwRenderer.h" - /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ -namespace tvg { - struct SwTask - { - SwShape shape; - const Shape* sdata; - SwSize clip; - Matrix* transform; - RenderUpdateFlag flags; - future progress; - }; -} - static RenderInitializer renderInit; @@ -52,13 +37,6 @@ static RenderInitializer renderInit; SwRenderer::~SwRenderer() { - flush(); -} - - -bool SwRenderer::clear() -{ - return flush(); } @@ -77,66 +55,25 @@ bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t bool SwRenderer::preRender() { - //before we start rendering, we should finish all preparing tasks - while (prepareTasks.size() > 0) { - auto task = prepareTasks.front(); - if (task->progress.valid()) task->progress.get(); - prepareTasks.pop(); - renderTasks.push(task); - } - return true; -} - - -bool SwRenderer::postRender() -{ - auto asyncTask = [](SwRenderer* renderer) { - renderer->doRender(); - }; - - progress = async(launch::async, asyncTask, this); - - return true; + return rasterClear(surface); } -void SwRenderer::doRender() +bool SwRenderer::render(const Shape& sdata, TVG_UNUSED void *data) { - rasterClear(surface); - - while (renderTasks.size() > 0) { - auto task = renderTasks.front(); - uint8_t r, g, b, a; - if (auto fill = task->sdata->fill()) { - rasterGradientShape(surface, task->shape, fill->id()); - } else{ - task->sdata->fill(&r, &g, &b, &a); - if (a > 0) rasterSolidShape(surface, task->shape, r, g, b, a); - } - task->sdata->strokeColor(&r, &g, &b, &a); - if (a > 0) rasterStroke(surface, task->shape, r, g, b, a); - renderTasks.pop(); - } -} + auto shape = static_cast(data); + if (!shape) return false; + uint8_t r, g, b, a; -bool SwRenderer::flush() -{ - while (prepareTasks.size() > 0) { - auto task = prepareTasks.front(); - if (task->progress.valid()) task->progress.get(); - prepareTasks.pop(); + if (auto fill = sdata.fill()) { + rasterGradientShape(surface, shape, fill->id()); + } else{ + sdata.fill(&r, &g, &b, &a); + if (a > 0) rasterSolidShape(surface, shape, r, g, b, a); } - - if (progress.valid()) progress.get(); - - return true; -} - - -bool SwRenderer::render(TVG_UNUSED const Shape& sdata, TVG_UNUSED void *data) -{ - //Do Nothing + sdata.strokeColor(&r, &g, &b, &a); + if (a > 0) rasterStroke(surface, shape, r, g, b, a); return true; } @@ -144,91 +81,72 @@ bool SwRenderer::render(TVG_UNUSED const Shape& sdata, TVG_UNUSED void *data) bool SwRenderer::dispose(TVG_UNUSED const Shape& sdata, void *data) { - auto task = static_cast(data); - if (!task) return true; - if (task->progress.valid()) task->progress.get(); - shapeFree(task->shape); - if (task->transform) free(task->transform); - free(task); + auto shape = static_cast(data); + if (!shape) return false; + shapeFree(shape); return true; } void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* transform, RenderUpdateFlag flags) { - //prepare task - auto task = static_cast(data); - if (!task) { - task = static_cast(calloc(1, sizeof(SwTask))); - if (!task) return nullptr; + //prepare shape data + auto shape = static_cast(data); + if (!shape) { + shape = static_cast(calloc(1, sizeof(SwShape))); + assert(shape); } - if (flags == RenderUpdateFlag::None || task->progress.valid()) return task; + if (flags == RenderUpdateFlag::None) return shape; - task->sdata = &sdata; - task->clip = {static_cast(surface.w), static_cast(surface.h)}; + SwSize clip = {static_cast(surface.w), static_cast(surface.h)}; - if (transform) { - if (!task->transform) task->transform = static_cast(malloc(sizeof(Matrix))); - assert(task->transform); - *task->transform = transform->m; - } else { - if (task->transform) free(task->transform); - task->transform = nullptr; + //Valid Stroking? + uint8_t strokeAlpha = 0; + auto strokeWidth = sdata.strokeWidth(); + if (strokeWidth > FLT_EPSILON) { + sdata.strokeColor(nullptr, nullptr, nullptr, &strokeAlpha); } - task->flags = flags; - - auto asyncTask = [](SwTask* task) { - - //Valid Stroking? - uint8_t strokeAlpha = 0; - auto strokeWidth = task->sdata->strokeWidth(); - if (strokeWidth > FLT_EPSILON) { - task->sdata->strokeColor(nullptr, nullptr, nullptr, &strokeAlpha); - } - - //Shape - if (task->flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform)) { - shapeReset(task->shape); - uint8_t alpha = 0; - task->sdata->fill(nullptr, nullptr, nullptr, &alpha); - bool renderShape = (alpha > 0 || task->sdata->fill()); - if (renderShape || strokeAlpha) { - if (!shapePrepare(task->shape, task->sdata, task->clip, task->transform)) return; - if (renderShape) { - auto antiAlias = (strokeAlpha > 0 && strokeWidth >= 2) ? false : true; - if (!shapeGenRle(task->shape, task->sdata, task->clip, antiAlias)) return; - } + const Matrix* matrix = (transform ? &transform->m : nullptr); + + //Shape + if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform)) { + shapeReset(shape); + uint8_t alpha = 0; + sdata.fill(nullptr, nullptr, nullptr, &alpha); + bool renderShape = (alpha > 0 || sdata.fill()); + if (renderShape || strokeAlpha) { + if (!shapePrepare(shape, &sdata, clip, matrix)) return shape; + if (renderShape) { + auto antiAlias = (strokeAlpha > 0 && strokeWidth >= 2) ? false : true; + if (!shapeGenRle(shape, &sdata, clip, antiAlias)) return shape; } } //Fill - if (task->flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform)) { - auto fill = task->sdata->fill(); + if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform)) { + auto fill = sdata.fill(); if (fill) { - auto ctable = (task->flags & RenderUpdateFlag::Gradient) ? true : false; - if (ctable) shapeResetFill(task->shape); - if (!shapeGenFillColors(task->shape, fill, task->transform, ctable)) return; + auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false; + if (ctable) shapeResetFill(shape); + if (!shapeGenFillColors(shape, fill, matrix, ctable)) return shape; } else { - shapeDelFill(task->shape); + shapeDelFill(shape); } } //Stroke - if (task->flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { + if (flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { if (strokeAlpha > 0) { - shapeResetStroke(task->shape, task->sdata, task->transform); - if (!shapeGenStrokeRle(task->shape, task->sdata, task->transform, task->clip)) return; + shapeResetStroke(shape, &sdata, matrix); + if (!shapeGenStrokeRle(shape, &sdata, matrix, clip)) return shape; } else { - shapeDelStroke(task->shape); + shapeDelStroke(shape); } } - shapeDelOutline(task->shape); - }; - - prepareTasks.push(task); - task->progress = async((launch::async | launch::deferred), asyncTask, task); + shapeDelOutline(shape); + } - return task; + return shape; } diff --git a/src/lib/sw_engine/tvgSwRenderer.h b/src/lib/sw_engine/tvgSwRenderer.h index d34c83c..9a41902 100644 --- a/src/lib/sw_engine/tvgSwRenderer.h +++ b/src/lib/sw_engine/tvgSwRenderer.h @@ -22,10 +22,6 @@ #ifndef _TVG_SW_RENDERER_H_ #define _TVG_SW_RENDERER_H_ -#include -#include -#include - namespace tvg { @@ -38,10 +34,7 @@ public: bool dispose(const Shape& shape, void *data) override; bool preRender() override; bool render(const Shape& shape, void *data) override; - bool postRender() override; bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h); - bool clear() override; - bool flush() override; uint32_t ref() override; uint32_t unref() override; @@ -49,13 +42,8 @@ public: static int init(); static int term(); - void doRender(); //Internally used for threading - private: Surface surface = {nullptr, 0, 0, 0}; - future progress; - queue prepareTasks; - queue renderTasks; SwRenderer(){}; ~SwRenderer(); diff --git a/src/lib/sw_engine/tvgSwShape.cpp b/src/lib/sw_engine/tvgSwShape.cpp index ed7c1e4..f9537d1 100644 --- a/src/lib/sw_engine/tvgSwShape.cpp +++ b/src/lib/sw_engine/tvgSwShape.cpp @@ -463,52 +463,52 @@ bool _fastTrack(const SwOutline* outline) /* External Class Implementation */ /************************************************************************/ -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) { if (!shapeGenOutline(shape, sdata, transform)) return false; - if (!_updateBBox(shape.outline, shape.bbox)) return false; + if (!_updateBBox(shape->outline, shape->bbox)) return false; - if (!_checkValid(shape.outline, shape.bbox, clip)) return false; + if (!_checkValid(shape->outline, shape->bbox, clip)) return false; return true; } -bool shapeGenRle(SwShape& shape, TVG_UNUSED const Shape* sdata, const SwSize& clip, bool antiAlias) +bool shapeGenRle(SwShape* shape, TVG_UNUSED const Shape* sdata, const SwSize& clip, bool antiAlias) { //FIXME: Should we draw it? //Case: Stroke Line //if (shape.outline->opened) return true; //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 - if ((shape.rle = rleRender(shape.outline, shape.bbox, clip, antiAlias))) return true; + if ((shape->rle = rleRender(shape->outline, shape->bbox, clip, antiAlias))) return true; return false; } -void shapeDelOutline(SwShape& shape) +void shapeDelOutline(SwShape* shape) { - auto outline = shape.outline; + auto outline = shape->outline; _delOutline(outline); - shape.outline = nullptr; + shape->outline = nullptr; } -void shapeReset(SwShape& shape) +void shapeReset(SwShape* shape) { shapeDelOutline(shape); - rleFree(shape.rle); - shape.rle = nullptr; - shape.rect = false; - _initBBox(shape.bbox); + rleFree(shape->rle); + shape->rle = nullptr; + shape->rect = false; + _initBBox(shape->bbox); } -bool shapeGenOutline(SwShape& shape, const Shape* sdata, const Matrix* transform) +bool shapeGenOutline(SwShape* shape, const Shape* sdata, const Matrix* transform) { assert(sdata); @@ -550,7 +550,7 @@ bool shapeGenOutline(SwShape& shape, const Shape* sdata, const Matrix* transform ++outlinePtsCnt; //for close ++outlineCntrsCnt; //for end - auto outline = shape.outline; + auto outline = shape->outline; if (!outline) outline = static_cast(calloc(1, sizeof(SwOutline))); assert(outline); outline->opened = true; @@ -594,49 +594,49 @@ bool shapeGenOutline(SwShape& shape, const Shape* sdata, const Matrix* transform //FIXME: //outline->flags = SwOutline::FillRule::Winding; - shape.outline = outline; + shape->outline = outline; return true; } -void shapeFree(SwShape& shape) +void shapeFree(SwShape* shape) { shapeDelOutline(shape); - rleFree(shape.rle); + rleFree(shape->rle); shapeDelFill(shape); - if (shape.stroke) { - rleFree(shape.strokeRle); - strokeFree(shape.stroke); + if (shape->stroke) { + rleFree(shape->strokeRle); + strokeFree(shape->stroke); } } -void shapeDelStroke(SwShape& shape) +void shapeDelStroke(SwShape* shape) { - if (!shape.stroke) return; - rleFree(shape.strokeRle); - shape.strokeRle = nullptr; - strokeFree(shape.stroke); - shape.stroke = nullptr; + if (!shape->stroke) return; + rleFree(shape->strokeRle); + shape->strokeRle = nullptr; + strokeFree(shape->stroke); + shape->stroke = nullptr; } -void shapeResetStroke(SwShape& shape, const Shape* sdata, const Matrix* transform) +void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform) { - if (!shape.stroke) shape.stroke = static_cast(calloc(1, sizeof(SwStroke))); - auto stroke = shape.stroke; - assert(stroke); + if (!shape->stroke) shape->stroke = static_cast(calloc(1, sizeof(SwStroke))); + auto stroke = shape->stroke; + if (!stroke) return; - strokeReset(*stroke, sdata, transform); + strokeReset(stroke, sdata, transform); - rleFree(shape.strokeRle); - shape.strokeRle = nullptr; + rleFree(shape->strokeRle); + shape->strokeRle = nullptr; } -bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transform, const SwSize& clip) +bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwSize& clip) { assert(sdata); @@ -648,15 +648,15 @@ bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transfo if (!shapeOutline) return false; //Normal Style stroke } else { - if (!shape.outline) { + if (!shape->outline) { if (!shapeGenOutline(shape, sdata, transform)) return false; } - shapeOutline = shape.outline; + shapeOutline = shape->outline; } - if (!strokeParseOutline(*shape.stroke, *shapeOutline)) return false; + if (!strokeParseOutline(shape->stroke, *shapeOutline)) return false; - auto strokeOutline = strokeExportOutline(*shape.stroke); + auto strokeOutline = strokeExportOutline(shape->stroke); if (!strokeOutline) return false; SwBBox bbox; @@ -664,7 +664,7 @@ bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transfo if (!_checkValid(strokeOutline, bbox, clip)) return false; - shape.strokeRle = rleRender(strokeOutline, bbox, clip, true); + shape->strokeRle = rleRender(strokeOutline, bbox, clip, true); _delOutline(strokeOutline); @@ -672,26 +672,27 @@ bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transfo } -bool shapeGenFillColors(SwShape& shape, const Fill* fill, const Matrix* transform, bool ctable) +bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, bool ctable) { - return fillGenColorTable(shape.fill, fill, transform, ctable); + return fillGenColorTable(shape->fill, fill, transform, ctable); } -void shapeResetFill(SwShape& shape) +void shapeResetFill(SwShape* shape) { - if (!shape.fill) shape.fill = static_cast(calloc(1, sizeof(SwFill))); - assert(shape.fill); - - fillReset(shape.fill); + if (!shape->fill) { + shape->fill = static_cast(calloc(1, sizeof(SwFill))); + if (!shape->fill) return; + } + fillReset(shape->fill); } -void shapeDelFill(SwShape& shape) +void shapeDelFill(SwShape* shape) { - if (!shape.fill) return; - fillFree(shape.fill); - shape.fill = nullptr; + if (!shape->fill) return; + fillFree(shape->fill); + shape->fill = nullptr; } diff --git a/src/lib/sw_engine/tvgSwStroke.cpp b/src/lib/sw_engine/tvgSwStroke.cpp index 70eb1ca..fbe28c1 100644 --- a/src/lib/sw_engine/tvgSwStroke.cpp +++ b/src/lib/sw_engine/tvgSwStroke.cpp @@ -846,34 +846,34 @@ void strokeFree(SwStroke* stroke) } -void strokeReset(SwStroke& stroke, const Shape* sdata, const Matrix* transform) +void strokeReset(SwStroke* stroke, const Shape* sdata, const Matrix* transform) { assert(sdata); if (transform) { - stroke.sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2)); - stroke.sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2)); + stroke->sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2)); + stroke->sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2)); } else { - stroke.sx = stroke.sy = 1.0f; + stroke->sx = stroke->sy = 1.0f; } - stroke.width = TO_SWCOORD(sdata->strokeWidth() * 0.5); - stroke.cap = sdata->strokeCap(); + stroke->width = TO_SWCOORD(sdata->strokeWidth() * 0.5); + stroke->cap = sdata->strokeCap(); //Save line join: it can be temporarily changed when stroking curves... - stroke.joinSaved = stroke.join = sdata->strokeJoin(); + stroke->joinSaved = stroke->join = sdata->strokeJoin(); - stroke.borders[0].ptsCnt = 0; - stroke.borders[0].start = -1; - stroke.borders[0].valid = false; + stroke->borders[0].ptsCnt = 0; + stroke->borders[0].start = -1; + stroke->borders[0].valid = false; - stroke.borders[1].ptsCnt = 0; - stroke.borders[1].start = -1; - stroke.borders[1].valid = false; + stroke->borders[1].ptsCnt = 0; + stroke->borders[1].start = -1; + stroke->borders[1].valid = false; } -bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline) +bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline) { uint32_t first = 0; @@ -895,7 +895,7 @@ bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline) //A contour cannot start with a cubic control point if (type == SW_CURVE_TYPE_CUBIC) return false; - _beginSubPath(stroke, start, outline.opened); + _beginSubPath(*stroke, start, outline.opened); while (pt < limit) { ++pt; @@ -903,7 +903,7 @@ bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline) //emit a signel line_to if (types[0] == SW_CURVE_TYPE_POINT) { - _lineTo(stroke, *pt); + _lineTo(*stroke, *pt); //types cubic } else { if (pt + 1 > limit || types[1] != SW_CURVE_TYPE_CUBIC) return false; @@ -912,28 +912,28 @@ bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline) types += 2; if (pt <= limit) { - _cubicTo(stroke, pt[-2], pt[-1], pt[0]); + _cubicTo(*stroke, pt[-2], pt[-1], pt[0]); continue; } - _cubicTo(stroke, pt[-2], pt[-1], start); + _cubicTo(*stroke, pt[-2], pt[-1], start); goto close; } } close: - if (!stroke.firstPt) _endSubPath(stroke); + if (!stroke->firstPt) _endSubPath(*stroke); first = last + 1; } return true; } -SwOutline* strokeExportOutline(SwStroke& stroke) +SwOutline* strokeExportOutline(SwStroke* stroke) { uint32_t count1, count2, count3, count4; - _getCounts(stroke.borders + 0, count1, count2); - _getCounts(stroke.borders + 1, count3, count4); + _getCounts(stroke->borders + 0, count1, count2); + _getCounts(stroke->borders + 1, count3, count4); auto ptsCnt = count1 + count3; auto cntrsCnt = count2 + count4; @@ -950,8 +950,8 @@ SwOutline* strokeExportOutline(SwStroke& stroke) outline->cntrs = static_cast(malloc(sizeof(uint32_t) * cntrsCnt)); assert(outline->cntrs); - _exportBorderOutline(stroke, outline, 0); //left - _exportBorderOutline(stroke, outline, 1); //right + _exportBorderOutline(*stroke, outline, 0); //left + _exportBorderOutline(*stroke, outline, 1); //right return outline; } diff --git a/src/lib/tvgRender.h b/src/lib/tvgRender.h index 85292d2..60c76d5 100644 --- a/src/lib/tvgRender.h +++ b/src/lib/tvgRender.h @@ -57,12 +57,12 @@ class RenderMethod public: virtual ~RenderMethod() {} virtual void* prepare(TVG_UNUSED const Shape& shape, TVG_UNUSED void* data, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED RenderUpdateFlag flags) { return nullptr; } - virtual bool dispose(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return false; } - virtual bool preRender() { return false; } - virtual bool render(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return false; } - virtual bool postRender() { return false; } - virtual bool clear() { return false; } - virtual bool flush() { return false; } + virtual bool dispose(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return true; } + virtual bool preRender() { return true; } + virtual bool render(TVG_UNUSED const Shape& shape, TVG_UNUSED void *data) { return true; } + virtual bool postRender() { return true; } + virtual bool clear() { return true; } + virtual bool flush() { return true; } virtual uint32_t ref() { return 0; } virtual uint32_t unref() { return 0; } }; diff --git a/src/loaders/svg_loader/tvgSvgLoader.cpp b/src/loaders/svg_loader/tvgSvgLoader.cpp index 205e8cb..442d3b7 100644 --- a/src/loaders/svg_loader/tvgSvgLoader.cpp +++ b/src/loaders/svg_loader/tvgSvgLoader.cpp @@ -2324,31 +2324,34 @@ bool SvgLoader::read() { if (content.empty()) return false; - auto asyncTask = [](SvgLoader *loader) { - bool res = simpleXmlParse(loader->content.c_str(), loader->content.size(), true, _svgLoaderParser, &(loader->loaderData)); - - if (!res) return unique_ptr(nullptr); - - if (loader->loaderData.doc) { - SvgNode *defs; - _updateStyle(loader->loaderData.doc, nullptr); - defs = loader->loaderData.doc->node.doc.defs; - if (defs) _updateGradient(loader->loaderData.doc, defs->node.defs.gradients); - else { - if (!loader->loaderData.gradients.empty()) { - vector gradientList; - for (auto gradient : loader->loaderData.gradients) { - gradientList.push_back(gradient); - } - _updateGradient(loader->loaderData.doc, gradientList); - gradientList.clear(); - } + loaderData = {vector(), + nullptr, + nullptr, + vector(), + nullptr, + nullptr, + 0, + false}; + + loaderData.svgParse = (SvgParser*)malloc(sizeof(SvgParser)); + + if (!simpleXmlParse(content.c_str(), content.size(), true, _svgLoaderParser, &loaderData)) return false; + + if (loaderData.doc) { + _updateStyle(loaderData.doc, nullptr); + auto defs = loaderData.doc->node.doc.defs; + if (defs) _updateGradient(loaderData.doc, defs->node.defs.gradients); + else { + if (!loaderData.gradients.empty()) { + vector gradientList; + std::copy(loaderData.gradients.begin(), loaderData.gradients.end(), gradientList.begin()); + _updateGradient(loaderData.doc, gradientList); + gradientList.clear(); } } - return loader->builder.build(loader->loaderData.doc); - }; + } - rootProgress = async((launch::async | launch::deferred), asyncTask, this); + root = builder.build(loaderData.doc); return true; } @@ -2356,8 +2359,6 @@ bool SvgLoader::read() bool SvgLoader::close() { - if (rootProgress.valid()) root = rootProgress.get(); - if (loaderData.svgParse) { free(loaderData.svgParse); loaderData.svgParse = nullptr; @@ -2371,10 +2372,7 @@ bool SvgLoader::close() unique_ptr SvgLoader::data() { - if (rootProgress.valid()) root = rootProgress.get(); - - if (root) return move(root); - else return unique_ptr(nullptr); + return move(root); } #endif //_TVG_SVG_LOADER_CPP_ diff --git a/src/loaders/svg_loader/tvgSvgLoader.h b/src/loaders/svg_loader/tvgSvgLoader.h index 7f0ce3c..3ef981d 100644 --- a/src/loaders/svg_loader/tvgSvgLoader.h +++ b/src/loaders/svg_loader/tvgSvgLoader.h @@ -24,7 +24,7 @@ #include "tvgSvgLoaderCommon.h" #include "tvgSvgSceneBuilder.h" -#include + class SvgLoader : public Loader { @@ -32,7 +32,6 @@ private: string content; SvgLoaderData loaderData; SvgSceneBuilder builder; - future> rootProgress; unique_ptr root; public: -- 2.7.4 From 93b517df062a42c511d93770558ade9293996362 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 14 Aug 2020 17:44:17 +0900 Subject: [PATCH 14/16] disable gl_engine in default. We don't include gl compile before it works properly. For development & test please turn it on in meson_option.txt locally. Change-Id: I2ff8b06f8e1b496922f70ec580662e8886a9b93d --- meson_options.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson_options.txt b/meson_options.txt index 59d0130..3990b17 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,7 +1,7 @@ option('engines', type: 'array', choices: ['sw', 'gl'], - value: ['sw', 'gl'], + value: ['sw'], description: 'Enable Rasterizer Engine in thorvg') option('loaders', -- 2.7.4 From 709548701a7dc1c2ae61e6a473ccc0a072482b23 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 14 Aug 2020 18:47:03 +0900 Subject: [PATCH 15/16] loader svg: code refactoring. renamed svg loader path. Change-Id: I0219721540ea981d15d17b9571c1ee9b37651fb8 --- src/loaders/meson.build | 2 +- src/loaders/{svg_loader => svg}/meson.build | 0 src/loaders/{svg_loader => svg}/tvgSimpleXmlParser.cpp | 0 src/loaders/{svg_loader => svg}/tvgSimpleXmlParser.h | 0 src/loaders/{svg_loader => svg}/tvgSvgLoader.cpp | 0 src/loaders/{svg_loader => svg}/tvgSvgLoader.h | 0 src/loaders/{svg_loader => svg}/tvgSvgLoaderCommon.h | 0 src/loaders/{svg_loader => svg}/tvgSvgPath.cpp | 0 src/loaders/{svg_loader => svg}/tvgSvgPath.h | 0 src/loaders/{svg_loader => svg}/tvgSvgSceneBuilder.cpp | 0 src/loaders/{svg_loader => svg}/tvgSvgSceneBuilder.h | 0 11 files changed, 1 insertion(+), 1 deletion(-) rename src/loaders/{svg_loader => svg}/meson.build (100%) rename src/loaders/{svg_loader => svg}/tvgSimpleXmlParser.cpp (100%) rename src/loaders/{svg_loader => svg}/tvgSimpleXmlParser.h (100%) rename src/loaders/{svg_loader => svg}/tvgSvgLoader.cpp (100%) rename src/loaders/{svg_loader => svg}/tvgSvgLoader.h (100%) rename src/loaders/{svg_loader => svg}/tvgSvgLoaderCommon.h (100%) rename src/loaders/{svg_loader => svg}/tvgSvgPath.cpp (100%) rename src/loaders/{svg_loader => svg}/tvgSvgPath.h (100%) rename src/loaders/{svg_loader => svg}/tvgSvgSceneBuilder.cpp (100%) rename src/loaders/{svg_loader => svg}/tvgSvgSceneBuilder.h (100%) diff --git a/src/loaders/meson.build b/src/loaders/meson.build index 873cfa7..bc67b53 100644 --- a/src/loaders/meson.build +++ b/src/loaders/meson.build @@ -1,7 +1,7 @@ subloader_dep = [] if get_option('loaders').contains('svg') == true - subdir('svg_loader') + subdir('svg') message('Enable SVG Loader') endif diff --git a/src/loaders/svg_loader/meson.build b/src/loaders/svg/meson.build similarity index 100% rename from src/loaders/svg_loader/meson.build rename to src/loaders/svg/meson.build diff --git a/src/loaders/svg_loader/tvgSimpleXmlParser.cpp b/src/loaders/svg/tvgSimpleXmlParser.cpp similarity index 100% rename from src/loaders/svg_loader/tvgSimpleXmlParser.cpp rename to src/loaders/svg/tvgSimpleXmlParser.cpp diff --git a/src/loaders/svg_loader/tvgSimpleXmlParser.h b/src/loaders/svg/tvgSimpleXmlParser.h similarity index 100% rename from src/loaders/svg_loader/tvgSimpleXmlParser.h rename to src/loaders/svg/tvgSimpleXmlParser.h diff --git a/src/loaders/svg_loader/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp similarity index 100% rename from src/loaders/svg_loader/tvgSvgLoader.cpp rename to src/loaders/svg/tvgSvgLoader.cpp diff --git a/src/loaders/svg_loader/tvgSvgLoader.h b/src/loaders/svg/tvgSvgLoader.h similarity index 100% rename from src/loaders/svg_loader/tvgSvgLoader.h rename to src/loaders/svg/tvgSvgLoader.h diff --git a/src/loaders/svg_loader/tvgSvgLoaderCommon.h b/src/loaders/svg/tvgSvgLoaderCommon.h similarity index 100% rename from src/loaders/svg_loader/tvgSvgLoaderCommon.h rename to src/loaders/svg/tvgSvgLoaderCommon.h diff --git a/src/loaders/svg_loader/tvgSvgPath.cpp b/src/loaders/svg/tvgSvgPath.cpp similarity index 100% rename from src/loaders/svg_loader/tvgSvgPath.cpp rename to src/loaders/svg/tvgSvgPath.cpp diff --git a/src/loaders/svg_loader/tvgSvgPath.h b/src/loaders/svg/tvgSvgPath.h similarity index 100% rename from src/loaders/svg_loader/tvgSvgPath.h rename to src/loaders/svg/tvgSvgPath.h diff --git a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp similarity index 100% rename from src/loaders/svg_loader/tvgSvgSceneBuilder.cpp rename to src/loaders/svg/tvgSvgSceneBuilder.cpp diff --git a/src/loaders/svg_loader/tvgSvgSceneBuilder.h b/src/loaders/svg/tvgSvgSceneBuilder.h similarity index 100% rename from src/loaders/svg_loader/tvgSvgSceneBuilder.h rename to src/loaders/svg/tvgSvgSceneBuilder.h -- 2.7.4 From 1eb11f249ef62217e6f47fcc90b459764d0685b1 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 14 Aug 2020 18:51:38 +0900 Subject: [PATCH 16/16] common initializer: introduce thread count api. this interface controls the number of threads working behind. default is 0 == only syncrhonous. Change-Id: I8404f33359e6213acc5e578061568fede50cd9a6 --- inc/thorvg.h | 2 ++ src/lib/tvgInitializer.cpp | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/inc/thorvg.h b/inc/thorvg.h index 9759245..452234d 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -365,6 +365,8 @@ public: */ static Result init(CanvasEngine engine) noexcept; static Result term(CanvasEngine engine) noexcept; + static Result threads(uint32_t cnt) noexcept; + static uint32_t threads() noexcept; _TVG_DISABLE_CTOR(Initializer); }; diff --git a/src/lib/tvgInitializer.cpp b/src/lib/tvgInitializer.cpp index 2009299..3367603 100644 --- a/src/lib/tvgInitializer.cpp +++ b/src/lib/tvgInitializer.cpp @@ -38,6 +38,8 @@ /* Internal Class Implementation */ /************************************************************************/ +static uint32_t threadCnt = 0; + /************************************************************************/ /* External Class Implementation */ /************************************************************************/ @@ -93,4 +95,18 @@ Result Initializer::term(CanvasEngine engine) noexcept return Result::Success; } + +Result Initializer::threads(uint32_t cnt) noexcept +{ + threadCnt = cnt; + + return Result::Success; +} + + +uint32_t Initializer::threads() noexcept +{ + return threadCnt; +} + #endif /* _TVG_INITIALIZER_CPP_ */ -- 2.7.4