From c633999048c1baf7edf54b2ab6341713fdbe0366 Mon Sep 17 00:00:00 2001 From: Mira Grudzinska Date: Sun, 7 Mar 2021 16:02:04 +0100 Subject: [PATCH 01/16] svg_loader: limiting the ploted area of svg to viewBox The 'viewBox' element given in the svg file determines the coordinates of the plotted area. ClipPath used in Svg loader. Change-Id: Idddcbce7cddfe46e2049d6741379c747e76482ed --- src/loaders/svg/tvgSvgSceneBuilder.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index 38b3b6e..25f85ea 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -363,7 +363,14 @@ unique_ptr _sceneBuildHelper(const SvgNode* node, float vx, float vy, flo scene->push(_sceneBuildHelper(*child, vx, vy, vw, vh)); } else { auto shape = _shapeBuildHelper(*child, vx, vy, vw, vh); - if (shape) scene->push(move(shape)); + // clipping the viewBox + if (shape) { + auto viewBoxClip = Shape::gen(); + viewBoxClip->appendRect(vx, vy, vw, vh, 0, 0); + viewBoxClip->fill(0, 0, 0, 255); + shape->composite(move(viewBoxClip), tvg::CompositeMethod::ClipPath); + scene->push(move(shape)); + } } } //Apply composite node -- 2.7.4 From e98ef8365b9baed3e16b8e6b7105f7f35f6b952b Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 12 Mar 2021 11:50:46 +0900 Subject: [PATCH 02/16] common canvas: initialize member variable. to shutdown the static code analizer report. Change-Id: Id32127ab3caf64f1b8e34e5f3abf6780ac0d3b71 --- src/lib/tvgCanvasImpl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/tvgCanvasImpl.h b/src/lib/tvgCanvasImpl.h index 98dd4b9..0f417bc 100644 --- a/src/lib/tvgCanvasImpl.h +++ b/src/lib/tvgCanvasImpl.h @@ -32,7 +32,7 @@ struct Canvas::Impl { Array paints; RenderMethod* renderer; - bool refresh; //if all paints should be updated by force. + bool refresh = false; //if all paints should be updated by force. Impl(RenderMethod* pRenderer):renderer(pRenderer) { -- 2.7.4 From 74712522de6151e9f96b4877fa2f0aa322feed05 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 12 Mar 2021 18:09:19 +0900 Subject: [PATCH 03/16] This is too untable.... Stress in example is crashed by this. Revert "svg_loader: limiting the ploted area of svg to viewBox" This reverts commit 2bb108b2f13432ac140d9be08daae189fe9c61c5. Change-Id: Iec82290d6ca080d868471275bc83663adbaf4b56 --- src/loaders/svg/tvgSvgSceneBuilder.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index 25f85ea..38b3b6e 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -363,14 +363,7 @@ unique_ptr _sceneBuildHelper(const SvgNode* node, float vx, float vy, flo scene->push(_sceneBuildHelper(*child, vx, vy, vw, vh)); } else { auto shape = _shapeBuildHelper(*child, vx, vy, vw, vh); - // clipping the viewBox - if (shape) { - auto viewBoxClip = Shape::gen(); - viewBoxClip->appendRect(vx, vy, vw, vh, 0, 0); - viewBoxClip->fill(0, 0, 0, 255); - shape->composite(move(viewBoxClip), tvg::CompositeMethod::ClipPath); - scene->push(move(shape)); - } + if (shape) scene->push(move(shape)); } } //Apply composite node -- 2.7.4 From 9ac4590059d243638628656a588381ef5be728e3 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 12 Mar 2021 18:00:47 +0900 Subject: [PATCH 04/16] common shape: revise Shape::reset() api. reset Path is useful rather than reset all properties. Change-Id: Ic62eaecf9e4129f2ada790ebef6745e7be85db4c --- src/lib/tvgShape.cpp | 3 ++- src/lib/tvgShapeImpl.h | 18 ------------------ 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/src/lib/tvgShape.cpp b/src/lib/tvgShape.cpp index e4cfb9e..40b80ee 100644 --- a/src/lib/tvgShape.cpp +++ b/src/lib/tvgShape.cpp @@ -52,7 +52,8 @@ unique_ptr Shape::gen() noexcept Result Shape::reset() noexcept { - pImpl->reset(); + pImpl->path.reset(); + pImpl->flag = RenderUpdateFlag::Path; return Result::Success; } diff --git a/src/lib/tvgShapeImpl.h b/src/lib/tvgShapeImpl.h index 2281ea0..4bc5f61 100644 --- a/src/lib/tvgShapeImpl.h +++ b/src/lib/tvgShapeImpl.h @@ -352,24 +352,6 @@ struct Shape::Impl return true; } - void reset() - { - path.reset(); - - if (fill) { - delete(fill); - fill = nullptr; - } - if (stroke) { - delete(stroke); - stroke = nullptr; - } - - color[0] = color[1] = color[2] = color[3] = 0; - - flag = RenderUpdateFlag::All; - } - Paint* duplicate() { auto ret = Shape::gen(); -- 2.7.4 From 32ad795f1bd224bb7f5fab923eb72d9420d358dd Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 15 Mar 2021 14:50:29 +0900 Subject: [PATCH 05/16] bump up version. Change-Id: I33545ca3d2e437d43471b080cc60a39e52a28bf6 --- packaging/thorvg.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/thorvg.spec b/packaging/thorvg.spec index c3e7652..59dfb16 100644 --- a/packaging/thorvg.spec +++ b/packaging/thorvg.spec @@ -1,6 +1,6 @@ Name: thorvg Summary: Thor Vector Graphics Library -Version: 0.0.2 +Version: 0.0.3 Release: 1 Group: Graphics System/Rendering Engine License: MIT -- 2.7.4 From 7b34c3d033eb4f0de046c82511ff8baf32469a5a Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Mon, 15 Mar 2021 14:56:36 +0900 Subject: [PATCH 06/16] loader SvgSceneBuilder: Add root node to clipping viewBox. If the boundary of scene created through the scenebuilder is larger than the viewbox, scene(SVG's root) should be clipped to the size of the viewbox. So, if scene need a clip, add a parent root and add clippath composition to that root. --- src/loaders/svg/tvgSvgSceneBuilder.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index 38b3b6e..0bbc023 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -386,6 +386,32 @@ unique_ptr _sceneBuildHelper(const SvgNode* node, float vx, float vy, flo return nullptr; } +unique_ptr _buildRoot(const SvgNode* node, float vx, float vy, float vw, float vh) +{ + unique_ptr root; + auto docNode = move(_sceneBuildHelper(node, vx, vy, vw, vh)); + float x, y, w, h; + + if (docNode->bounds(&x, &y, &w, &h) != Result::Success) return nullptr; + + if (x < vx || y < vy || w > vh || h > vh) { + auto viewBoxClip = Shape::gen(); + viewBoxClip->appendRect(vx, vy ,vw, vh, 0, 0); + viewBoxClip->fill(0, 0, 0, 255); + + auto compositeLayer = Scene::gen(); + compositeLayer->composite(move(viewBoxClip), tvg::CompositeMethod::ClipPath); + compositeLayer->push(move(docNode)); + + root = Scene::gen(); + root->push(move(compositeLayer)); + } + else + { + root = move(docNode); + } + return root; +} SvgSceneBuilder::SvgSceneBuilder() { @@ -401,5 +427,5 @@ unique_ptr SvgSceneBuilder::build(SvgNode* node) { if (!node || (node->type != SvgNodeType::Doc)) return nullptr; - return _sceneBuildHelper(node, node->node.doc.vx, node->node.doc.vy, node->node.doc.vw, node->node.doc.vh); + return _buildRoot(node, node->node.doc.vx, node->node.doc.vy, node->node.doc.vw, node->node.doc.vh); } -- 2.7.4 From 9686547f3d3dbb1e6fe05fe254a83b3dae820acf Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Mon, 15 Mar 2021 15:05:24 +0900 Subject: [PATCH 07/16] sw_engine rleClipPath: Modify clippath spans creation size. When updating rle for clipped area, realloc size should be larger than spans size. so this patch prevents the problem while realloc. --- src/lib/sw_engine/tvgSwRle.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/sw_engine/tvgSwRle.cpp b/src/lib/sw_engine/tvgSwRle.cpp index e89590b..846bca4 100644 --- a/src/lib/sw_engine/tvgSwRle.cpp +++ b/src/lib/sw_engine/tvgSwRle.cpp @@ -923,8 +923,9 @@ void updateRleSpans(SwRleData *rle, const SwSpan* curSpans, uint32_t size) } if (!rle->spans || !curSpans) return; + rle->alloc = size * 2; + rle->spans = static_cast(realloc(rle->spans, rle->alloc * sizeof(SwSpan))); rle->size = size; - rle->spans = static_cast(realloc(rle->spans, rle->size * sizeof(SwSpan))); if (!rle->spans) return; -- 2.7.4 From 3b123777820a2f106609b8f4d3cdfb11bb80d60e Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 15 Mar 2021 19:19:54 +0900 Subject: [PATCH 08/16] examples: clean up mask resources. These are not proper for our svg examples. --- src/examples/Svg.cpp | 4 ++-- src/examples/images/mask-gradient.svg | 13 ------------- src/examples/images/mask.svg | 8 -------- 3 files changed, 2 insertions(+), 23 deletions(-) delete mode 100644 src/examples/images/mask-gradient.svg delete mode 100644 src/examples/images/mask.svg diff --git a/src/examples/Svg.cpp b/src/examples/Svg.cpp index 392e5c7..4c07420 100644 --- a/src/examples/Svg.cpp +++ b/src/examples/Svg.cpp @@ -5,8 +5,8 @@ /* Drawing Commands */ /************************************************************************/ -#define NUM_PER_LINE 5 -#define SIZE 160 +#define NUM_PER_LINE 4 +#define SIZE 200 static int count = 0; diff --git a/src/examples/images/mask-gradient.svg b/src/examples/images/mask-gradient.svg deleted file mode 100644 index 1063ae0..0000000 --- a/src/examples/images/mask-gradient.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/examples/images/mask.svg b/src/examples/images/mask.svg deleted file mode 100644 index 7f6d065..0000000 --- a/src/examples/images/mask.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - -- 2.7.4 From 2a5107da7e37e723816aef0998ce6e8e9e567313 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 16 Mar 2021 10:23:11 +0900 Subject: [PATCH 09/16] sw_engine: optimize rle clipping We don't need to copy the rle data unecessarily, we can just replace the completed clip rle. Change-Id: I099a071bdc83937d3a942fc5d08ff2c2d72f96ac --- src/lib/sw_engine/tvgSwRle.cpp | 47 ++++++++++++------------------------------ 1 file changed, 13 insertions(+), 34 deletions(-) diff --git a/src/lib/sw_engine/tvgSwRle.cpp b/src/lib/sw_engine/tvgSwRle.cpp index 846bca4..810bfa0 100644 --- a/src/lib/sw_engine/tvgSwRle.cpp +++ b/src/lib/sw_engine/tvgSwRle.cpp @@ -772,6 +772,15 @@ SwSpan* _intersectSpansRect(const SwBBox *bbox, const SwRleData *targetRle, SwSp return out; } + +void _replaceClipSpan(SwRleData *rle, SwSpan* clippedSpans, uint32_t size) +{ + free(rle->spans); + rle->spans = clippedSpans; + rle->size = rle->alloc = size; +} + + /************************************************************************/ /* External Class Implementation */ /************************************************************************/ @@ -915,28 +924,6 @@ void rleFree(SwRleData* rle) free(rle); } -void updateRleSpans(SwRleData *rle, const SwSpan* curSpans, uint32_t size) -{ - if (size == 0) { - rle->size = 0; - return; - } - - if (!rle->spans || !curSpans) return; - rle->alloc = size * 2; - rle->spans = static_cast(realloc(rle->spans, rle->alloc * sizeof(SwSpan))); - rle->size = size; - - if (!rle->spans) return; - - for (int i = 0; i < (int)rle->size ; i++) - { - rle->spans[i].x = curSpans[i].x; - rle->spans[i].y = curSpans[i].y; - rle->spans[i].len = curSpans[i].len; - rle->spans[i].coverage = curSpans[i].coverage; - } -} void rleClipPath(SwRleData *rle, const SwRleData *clip) { @@ -946,16 +933,14 @@ void rleClipPath(SwRleData *rle, const SwRleData *clip) if (!spans) return; auto spansEnd = _intersectSpansRegion(clip, rle, spans, spanCnt); - //Update Spans - updateRleSpans(rle, spans, spansEnd - spans); - - if (spans) free(spans); + _replaceClipSpan(rle, spans, spansEnd - spans); #ifdef THORVG_LOG_ENABLED cout << "SW_ENGINE: Using ClipPath!" << endl; #endif } + void rleClipRect(SwRleData *rle, const SwBBox* clip) { if (rle->size == 0) return; @@ -963,10 +948,7 @@ void rleClipRect(SwRleData *rle, const SwBBox* clip) if (!spans) return; auto spansEnd = _intersectSpansRect(clip, rle, spans, rle->size); - //Update Spans - updateRleSpans(rle, spans, spansEnd - spans); - - if (spans) free(spans); + _replaceClipSpan(rle, spans, spansEnd - spans); #ifdef THORVG_LOG_ENABLED cout <<"SW_ENGINE: Using ClipRect!" << endl; @@ -984,9 +966,6 @@ void rleAlphaMask(SwRleData *rle, const SwRleData *clip) if (!spans) return; auto spansEnd = _intersectMaskRegion(clip, rle, spans, spanCnt); - //Update Spans - updateRleSpans(rle, spans, spansEnd - spans); - - if (spans) free(spans); + _replaceClipSpan(rle, spans, spansEnd - spans); } -- 2.7.4 From baf29d4aef7efc99ab3e4fbc051f8212d5ad0645 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 16 Mar 2021 13:29:16 +0900 Subject: [PATCH 10/16] loaders svg: remove unnecessary move call, move is guaranteed at the return value. warning: moving a temporary object prevents copy elision [-Wpessimizing-move] --- src/loaders/svg/tvgSvgSceneBuilder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index 0bbc023..af8952a 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -389,7 +389,7 @@ unique_ptr _sceneBuildHelper(const SvgNode* node, float vx, float vy, flo unique_ptr _buildRoot(const SvgNode* node, float vx, float vy, float vw, float vh) { unique_ptr root; - auto docNode = move(_sceneBuildHelper(node, vx, vy, vw, vh)); + auto docNode = _sceneBuildHelper(node, vx, vy, vw, vh); float x, y, w, h; if (docNode->bounds(&x, &y, &w, &h) != Result::Success) return nullptr; -- 2.7.4 From 128ba640b5a69dcdb3c4cd193f6d3e1f21a75594 Mon Sep 17 00:00:00 2001 From: Michal Szczecinski Date: Tue, 16 Mar 2021 12:00:00 +0100 Subject: [PATCH 11/16] common shape: Fixed appendArc for negative values. Description: Fixed appendArc API for -90 angles. In that case it was drawn in wrong direction. @Examples ```cpp float x = 40.0, y = 40.0; auto shape1 = tvg::Shape::gen(); //OK shape1->appendArc(x + 50, y, 25, 0, -91, false); //NOK shape1->appendArc(x + 100, y, 25, 0, -90, false); //OK shape1->appendArc(x + 150, y, 25, 0, -89, false); ``` Change-Id: Ic9cba89b44e170b3a1411e7d126c912a9fb135d5 --- 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 40b80ee..efd1fdf 100644 --- a/src/lib/tvgShape.cpp +++ b/src/lib/tvgShape.cpp @@ -163,7 +163,7 @@ Result Shape::appendArc(float cx, float cy, float radius, float startAngle, floa auto nCurves = ceil(abs(sweep / M_PI_HALF)); auto sweepSign = (sweep < 0 ? -1 : 1); auto fract = fmodf(sweep, M_PI_HALF); - fract = (fabsf(fract) < std::numeric_limits::epsilon()) ? M_PI_HALF : fract; + fract = (fabsf(fract) < std::numeric_limits::epsilon()) ? M_PI_HALF * sweepSign : fract; //Start from here Point start = {radius * cos(startAngle), radius * sin(startAngle)}; -- 2.7.4 From 34116f1eec8c8a8d29e6cc68497d26bef454621e Mon Sep 17 00:00:00 2001 From: Mira Grudzinska Date: Sun, 14 Mar 2021 21:50:00 +0100 Subject: [PATCH 12/16] paint: clip was substracted from the array for any composite method Only ClipPath composite method should cause clips subtraction. --- src/lib/tvgPaint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/tvgPaint.h b/src/lib/tvgPaint.h index 8345e53..3cdbacc 100644 --- a/src/lib/tvgPaint.h +++ b/src/lib/tvgPaint.h @@ -170,7 +170,7 @@ namespace tvg edata = smethod->update(renderer, outTransform, opacity, clips, newFlag); } - if (cmpData) clips.pop(); + if (cmpData && cmpMethod == CompositeMethod::ClipPath) clips.pop(); return edata; } -- 2.7.4 From 314d381801eadf1f7f14aa4386a18a47635439f8 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 19 Mar 2021 19:41:18 +0900 Subject: [PATCH 13/16] common picture: fix crash at picture duplication. A duplicated picture needs to access internal picture loader data to get its properties while rasterizing. But it missed the loader since it's not copied from origin. Thus, we fix this by sharing the internal loader among the duplications and origin. @Examples: Duplicate --- src/examples/Duplicate.cpp | 2 ++ src/examples/PixelImage.cpp | 4 ++-- src/lib/tvgLoaderMgr.cpp | 12 ++++++------ src/lib/tvgLoaderMgr.h | 6 +++--- src/lib/tvgPictureImpl.h | 13 ++++++++++--- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/examples/Duplicate.cpp b/src/examples/Duplicate.cpp index 5c6a397..44780e4 100644 --- a/src/examples/Duplicate.cpp +++ b/src/examples/Duplicate.cpp @@ -113,6 +113,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) canvas->push(move(picture1)); canvas->push(move(picture2)); + + free(data); } } diff --git a/src/examples/PixelImage.cpp b/src/examples/PixelImage.cpp index 61d1300..8e42e14 100644 --- a/src/examples/PixelImage.cpp +++ b/src/examples/PixelImage.cpp @@ -46,6 +46,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) picture2->composite(move(circle), tvg::CompositeMethod::ClipPath); canvas->push(move(picture2)); + + free(data); } @@ -148,8 +150,6 @@ int main(int argc, char **argv) //Terminate ThorVG Engine tvg::Initializer::term(tvg::CanvasEngine::Sw); - if (data) free(data); - } else { cout << "engine is not supported" << endl; } diff --git a/src/lib/tvgLoaderMgr.cpp b/src/lib/tvgLoaderMgr.cpp index d41671c..0e5eb1c 100644 --- a/src/lib/tvgLoaderMgr.cpp +++ b/src/lib/tvgLoaderMgr.cpp @@ -89,22 +89,22 @@ bool LoaderMgr::term() } -unique_ptr LoaderMgr::loader(const string& path) +shared_ptr LoaderMgr::loader(const string& path) { if (auto loader = _find(path)) { - if (loader->open(path)) return unique_ptr(loader); + if (loader->open(path)) return shared_ptr(loader); else delete(loader); } return nullptr; } -unique_ptr LoaderMgr::loader(const char* data, uint32_t size) +shared_ptr LoaderMgr::loader(const char* data, uint32_t size) { for (int i = 0; i < static_cast(FileType::Unknown); i++) { auto loader = _find(static_cast(i)); if (loader) { - if (loader->open(data, size)) return unique_ptr(loader); + if (loader->open(data, size)) return shared_ptr(loader); else delete(loader); } } @@ -112,12 +112,12 @@ unique_ptr LoaderMgr::loader(const char* data, uint32_t size) } -unique_ptr LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy) +shared_ptr LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy) { for (int i = 0; i < static_cast(FileType::Unknown); i++) { auto loader = _find(static_cast(i)); if (loader) { - if (loader->open(data, w, h, copy)) return unique_ptr(loader); + if (loader->open(data, w, h, copy)) return shared_ptr(loader); else delete(loader); } } diff --git a/src/lib/tvgLoaderMgr.h b/src/lib/tvgLoaderMgr.h index 5d2056b..06d7259 100644 --- a/src/lib/tvgLoaderMgr.h +++ b/src/lib/tvgLoaderMgr.h @@ -30,9 +30,9 @@ struct LoaderMgr { static bool init(); static bool term(); - static unique_ptr loader(const string& path); - static unique_ptr loader(const char* data, uint32_t size); - static unique_ptr loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy); + static shared_ptr loader(const string& path); + static shared_ptr loader(const char* data, uint32_t size); + static shared_ptr loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy); }; #endif //_TVG_LOADER_MGR_H_ diff --git a/src/lib/tvgPictureImpl.h b/src/lib/tvgPictureImpl.h index e3b0c5d..2fc2267 100644 --- a/src/lib/tvgPictureImpl.h +++ b/src/lib/tvgPictureImpl.h @@ -32,7 +32,7 @@ struct Picture::Impl { - unique_ptr loader = nullptr; + shared_ptr loader = nullptr; Paint* paint = nullptr; uint32_t *pixels = nullptr; Picture *picture = nullptr; @@ -105,6 +105,7 @@ struct Picture::Impl } if (!pixels) { pixels = const_cast(loader->pixels()); + loader->close(); if (pixels) return RenderUpdateFlag::Image; } } @@ -195,11 +196,17 @@ struct Picture::Impl { reload(); - if (!paint) return nullptr; auto ret = Picture::gen(); if (!ret) return nullptr; + auto dup = ret.get()->pImpl; - dup->paint = paint->duplicate(); + if (paint) dup->paint = paint->duplicate(); + + dup->loader = loader; + dup->pixels = pixels; + dup->w = w; + dup->h = h; + dup->resizing = resizing; return ret.release(); } -- 2.7.4 From aaee16191e732641a6658ff986d39e5f530ffcc7 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 19 Mar 2021 16:30:45 +0900 Subject: [PATCH 14/16] initializer: add reference counting for the engines initialization. Introduced the reference counting for the backend engines so that tvg prevents unpaired engine initialization/termination calls by user mistake. @Issues: 296 --- src/lib/gl_engine/tvgGlRenderer.cpp | 35 +++++++++++++++-------------------- src/lib/sw_engine/tvgSwRenderer.cpp | 16 +++++++--------- src/lib/tvgInitializer.cpp | 10 +--------- 3 files changed, 23 insertions(+), 38 deletions(-) diff --git a/src/lib/gl_engine/tvgGlRenderer.cpp b/src/lib/gl_engine/tvgGlRenderer.cpp index 8df62dd..9434628 100644 --- a/src/lib/gl_engine/tvgGlRenderer.cpp +++ b/src/lib/gl_engine/tvgGlRenderer.cpp @@ -28,8 +28,8 @@ /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ -static bool initEngine = false; -static uint32_t rendererCnt = 0; +static int32_t initEngineCnt = false; +static int32_t rendererCnt = 0; static void _termEngine() @@ -236,22 +236,19 @@ RenderData GlRenderer::prepare(const Shape& shape, RenderData data, const Render int GlRenderer::init(uint32_t threads) { - if (rendererCnt > 0) return false; - if (initEngine) return true; + if ((initEngineCnt++) > 0) return true; //TODO: - initEngine = true; - return true; } int GlRenderer::term() { - if (!initEngine) return true; + if ((--initEngineCnt) > 0) return true; - initEngine = false; + initEngineCnt = 0; _termEngine(); @@ -270,7 +267,8 @@ GlRenderer::~GlRenderer() mRenderTasks.clear(); --rendererCnt; - if (!initEngine) _termEngine(); + + if (rendererCnt == 0 && initEngineCnt == 0) _termEngine(); } @@ -308,13 +306,11 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, uint32_t primit { const Fill::ColorStop* stops = nullptr; auto stopCnt = fill->colorStops(&stops); - if (stopCnt < 2) - { - return; - } + if (stopCnt < 2) return; + GlGradientRenderTask* rTask = nullptr; - GlSize size = sdata.geometry->getPrimitiveSize(primitiveIndex); - float* matrix = sdata.geometry->getTransforMatrix(); + auto size = sdata.geometry->getPrimitiveSize(primitiveIndex); + auto matrix = sdata.geometry->getTransforMatrix(); switch (fill->id()) { case FILL_ID_LINEAR: { @@ -344,16 +340,15 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, uint32_t primit break; } } - if (rTask) - { - int32_t vertexLoc = rTask->getLocationPropertyId(); + if (rTask) { + auto vertexLoc = rTask->getLocationPropertyId(); rTask->setPrimitveSize(size.x, size.y); rTask->setCanvasSize(sdata.viewWd, sdata.viewHt); rTask->setNoise(NOISE_LEVEL); rTask->setStopCount((int)stopCnt); rTask->setTransform(FORMAT_SIZE_MAT_4x4, matrix); - for (uint32_t i = 0; i < stopCnt; ++i) - { + + for (uint32_t i = 0; i < stopCnt; ++i) { rTask->setStopColor(i, stops[i].offset, stops[i].r, stops[i].g, stops[i].b, stops[i].a); } diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index 9638597..1e0e28c 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -27,8 +27,8 @@ /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ -static bool initEngine = false; -static uint32_t rendererCnt = 0; +static int32_t initEngineCnt = false; +static int32_t rendererCnt = 0; struct SwTask : Task @@ -229,7 +229,8 @@ SwRenderer::~SwRenderer() if (surface) delete(surface); --rendererCnt; - if (!initEngine) _termEngine(); + + if (rendererCnt == 0 && initEngineCnt == 0) _termEngine(); } @@ -546,22 +547,19 @@ RenderData SwRenderer::prepare(const Shape& sdata, RenderData data, const Render bool SwRenderer::init(uint32_t threads) { - if (rendererCnt > 0) return false; - if (initEngine) return true; + if ((initEngineCnt++) > 0) return true; if (!mpoolInit(threads)) return false; - initEngine = true; - return true; } bool SwRenderer::term() { - if (!initEngine) return true; + if ((--initEngineCnt) > 0) return true; - initEngine = false; + initEngineCnt = 0; _termEngine(); diff --git a/src/lib/tvgInitializer.cpp b/src/lib/tvgInitializer.cpp index a32cb5d..b7decb1 100644 --- a/src/lib/tvgInitializer.cpp +++ b/src/lib/tvgInitializer.cpp @@ -35,7 +35,7 @@ /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ -static bool initialized = false; + /************************************************************************/ /* External Class Implementation */ @@ -43,8 +43,6 @@ static bool initialized = false; Result Initializer::init(CanvasEngine engine, uint32_t threads) noexcept { - if (initialized) return Result::InsufficientCondition; - auto nonSupport = true; if (static_cast(engine) & static_cast(CanvasEngine::Sw)) { @@ -67,16 +65,12 @@ Result Initializer::init(CanvasEngine engine, uint32_t threads) noexcept TaskScheduler::init(threads); - initialized = true; - return Result::Success; } Result Initializer::term(CanvasEngine engine) noexcept { - if (!initialized) return Result::InsufficientCondition; - auto nonSupport = true; if (static_cast(engine) & static_cast(CanvasEngine::Sw)) { @@ -99,7 +93,5 @@ Result Initializer::term(CanvasEngine engine) noexcept if (!LoaderMgr::term()) return Result::Unknown; - initialized = false; - return Result::Success; } \ No newline at end of file -- 2.7.4 From 55d41a258e39cdaa37cca852b663551f788be7aa Mon Sep 17 00:00:00 2001 From: Mira Grudzinska Date: Thu, 11 Mar 2021 17:20:41 +0100 Subject: [PATCH 15/16] svg_loader: applying AlphaMask during scene building The AlphaMask composition case was omitted in the _sceneBuilderHelper(). --- src/loaders/svg/tvgSvgSceneBuilder.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index af8952a..a32df10 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -378,6 +378,16 @@ unique_ptr _sceneBuildHelper(const SvgNode* node, float vx, float vy, flo scene->composite(move(comp), CompositeMethod::ClipPath); } } + //Composite AlphaMask + if (((int)node->style->comp.flags & (int)SvgCompositeFlags::AlphaMask)) { + auto compNode = node->style->comp.node; + if (compNode->child.count > 0) { + auto comp = Shape::gen(); + auto child = compNode->child.data; + for (uint32_t i = 0; i < compNode->child.count; ++i, ++child) _appendChildShape(*child, comp.get(), vx, vy, vw, vh); + scene->composite(move(comp), CompositeMethod::AlphaMask); + } + } } scene->opacity(node->style->opacity); } -- 2.7.4 From 9e23fc5420f5fff123d83acd6f80745121cca0bd Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 22 Mar 2021 13:19:49 +0900 Subject: [PATCH 16/16] bump up version Change-Id: I0026c758712b068949d61556ca202786627a9fe5 --- packaging/thorvg.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/thorvg.spec b/packaging/thorvg.spec index 59dfb16..c4f5203 100644 --- a/packaging/thorvg.spec +++ b/packaging/thorvg.spec @@ -1,6 +1,6 @@ Name: thorvg Summary: Thor Vector Graphics Library -Version: 0.0.3 +Version: 0.0.4 Release: 1 Group: Graphics System/Rendering Engine License: MIT -- 2.7.4