diff --git a/src/lib/gl_engine/tvgGlRenderer.cpp b/src/lib/gl_engine/tvgGlRenderer.cpp index 133f20e5..d94da508 100644 --- a/src/lib/gl_engine/tvgGlRenderer.cpp +++ b/src/lib/gl_engine/tvgGlRenderer.cpp @@ -162,14 +162,14 @@ bool GlRenderer::dispose(void *data) } -void* GlRenderer::prepare(TVG_UNUSED const Picture& picture, TVG_UNUSED void* data, TVG_UNUSED uint32_t *buffer, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED uint32_t opacity, TVG_UNUSED vector& compList, TVG_UNUSED RenderUpdateFlag flags) +void* GlRenderer::prepare(TVG_UNUSED const Picture& picture, TVG_UNUSED void* data, TVG_UNUSED uint32_t *buffer, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED uint32_t opacity, TVG_UNUSED Array& compList, TVG_UNUSED RenderUpdateFlag flags) { //TODO: return nullptr; } -void* GlRenderer::prepare(const Shape& shape, void* data, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED uint32_t opacity, vector& compList, RenderUpdateFlag flags) +void* GlRenderer::prepare(const Shape& shape, void* data, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED uint32_t opacity, Array& compList, RenderUpdateFlag flags) { //prepare shape data GlShape* sdata = static_cast(data); diff --git a/src/lib/gl_engine/tvgGlRenderer.h b/src/lib/gl_engine/tvgGlRenderer.h index aa291a8e..9dd96948 100644 --- a/src/lib/gl_engine/tvgGlRenderer.h +++ b/src/lib/gl_engine/tvgGlRenderer.h @@ -30,8 +30,8 @@ class GlRenderer : public RenderMethod public: Surface surface = {nullptr, 0, 0, 0}; - void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, vector& compList, RenderUpdateFlag flags) override; - void* prepare(const Picture& picture, void* data, uint32_t *buffer, const RenderTransform* transform, uint32_t opacity, vector& compList, RenderUpdateFlag flags) override; + void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag flags) override; + void* prepare(const Picture& picture, void* data, uint32_t *buffer, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag flags) override; bool dispose(void *data) override; void* beginComposite(uint32_t x, uint32_t y, uint32_t w, uint32_t h) override; bool endComposite(void* ctx, uint32_t opacity) override; diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index cd91f66e..4cc9b03e 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -43,7 +43,7 @@ struct SwTask : Task Matrix* transform = nullptr; SwSurface* surface = nullptr; RenderUpdateFlag flags = RenderUpdateFlag::None; - vector compList; + Array compList; uint32_t opacity; virtual bool dispose() = 0; @@ -91,7 +91,7 @@ struct SwShapeTask : SwTask shape outline below stroke could be full covered by stroke drawing. Thus it turns off antialising in that condition. */ auto antiAlias = (strokeAlpha == 255 && strokeWidth > 2) ? false : true; - if (!shapeGenRle(&shape, sdata, clip, antiAlias, compList.size() > 0 ? true : false)) goto end; + if (!shapeGenRle(&shape, sdata, clip, antiAlias, compList.count > 0 ? true : false)) goto end; ++addStroking; } } @@ -121,9 +121,9 @@ struct SwShapeTask : SwTask } //Composition - for (auto comp : compList) { - if (comp.method == CompositeMethod::ClipPath) { - auto compShape = &static_cast(comp.edata)->shape; + for (auto comp = compList.data; comp < (compList.data + compList.count); ++comp) { + if ((*comp).method == CompositeMethod::ClipPath) { + auto compShape = &static_cast((*comp).edata)->shape; //Clip shape rle if (shape.rle) { if (compShape->rect) rleClipRect(shape.rle, &compShape->bbox); @@ -169,12 +169,12 @@ struct SwImageTask : SwTask if (!imagePrepare(&image, pdata, tid, clip, transform)) goto end; //Composition? - if (compList.size() > 0) { + if (compList.count > 0) { if (!imageGenRle(&image, pdata, clip, false, true)) goto end; if (image.rle) { - for (auto comp : compList) { - if (comp.method == CompositeMethod::ClipPath) { - auto compShape = &static_cast(comp.edata)->shape; + for (auto comp = compList.data; comp < (compList.data + compList.count); ++comp) { + if ((*comp).method == CompositeMethod::ClipPath) { + auto compShape = &static_cast((*comp).edata)->shape; if (compShape->rect) rleClipRect(image.rle, &compShape->bbox); else if (compShape->rle) rleClipPath(image.rle, compShape->rle); } @@ -220,7 +220,7 @@ SwRenderer::~SwRenderer() bool SwRenderer::clear() { - for (auto task : tasks) task->done(); + for (auto task = tasks.data; task < (tasks.data + tasks.count); ++task) (*task)->done(); tasks.clear(); return true; @@ -411,12 +411,14 @@ bool SwRenderer::dispose(void *data) } -void SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, uint32_t opacity, vector& compList, RenderUpdateFlag flags) +void SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag flags) { - if (compList.size() > 0) { + if (compList.count > 0) { //Guarantee composition targets get ready. - for (auto comp : compList) static_cast(comp.edata)->done(); - task->compList.assign(compList.begin(), compList.end()); + for (auto comp = compList.data; comp < (compList.data + compList.count); ++comp) { + static_cast((*comp).edata)->done(); + } + task->compList = compList; } if (transform) { @@ -431,12 +433,12 @@ void SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, u task->surface = surface; task->flags = flags; - tasks.push_back(task); + tasks.push(task); TaskScheduler::request(task); } -void* SwRenderer::prepare(const Picture& pdata, void* data, uint32_t *pixels, const RenderTransform* transform, uint32_t opacity, vector& compList, RenderUpdateFlag flags) +void* SwRenderer::prepare(const Picture& pdata, void* data, uint32_t *pixels, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag flags) { //prepare task auto task = static_cast(data); @@ -459,7 +461,7 @@ void* SwRenderer::prepare(const Picture& pdata, void* data, uint32_t *pixels, co } -void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* transform, uint32_t opacity, vector& compList, RenderUpdateFlag flags) +void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag flags) { //prepare task auto task = static_cast(data); diff --git a/src/lib/sw_engine/tvgSwRenderer.h b/src/lib/sw_engine/tvgSwRenderer.h index a7e50622..fdfa53e2 100644 --- a/src/lib/sw_engine/tvgSwRenderer.h +++ b/src/lib/sw_engine/tvgSwRenderer.h @@ -22,7 +22,6 @@ #ifndef _TVG_SW_RENDERER_H_ #define _TVG_SW_RENDERER_H_ -#include #include "tvgRender.h" struct SwSurface; @@ -36,8 +35,8 @@ namespace tvg class SwRenderer : public RenderMethod { public: - void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, vector& compList, RenderUpdateFlag flags) override; - void* prepare(const Picture& picture, void* data, uint32_t *buffer, const RenderTransform* transform, uint32_t opacity, vector& compList, RenderUpdateFlag flags) override; + void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag flags) override; + void* prepare(const Picture& picture, void* data, uint32_t *buffer, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag flags) override; void* beginComposite(uint32_t x, uint32_t y, uint32_t w, uint32_t h) override; bool endComposite(void* ctx, uint32_t opacity) override; bool dispose(void *data) override; @@ -54,13 +53,13 @@ public: static bool term(); private: - SwSurface* surface = nullptr; - vector tasks; + SwSurface* surface = nullptr; + Array tasks; SwRenderer(){}; ~SwRenderer(); - void prepareCommon(SwTask* task, const RenderTransform* transform, uint32_t opacity, vector& compList, RenderUpdateFlag flags); + void prepareCommon(SwTask* task, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag flags); }; } diff --git a/src/lib/sw_engine/tvgSwRle.cpp b/src/lib/sw_engine/tvgSwRle.cpp index 2afcc876..53468a53 100644 --- a/src/lib/sw_engine/tvgSwRle.cpp +++ b/src/lib/sw_engine/tvgSwRle.cpp @@ -621,7 +621,7 @@ SwSpan* _intersectSpansRegion(const SwRleData *clip, const SwRleData *targetRle, auto clipSpans = clip->spans; auto clipEnd = clip->spans + clip->size; - while (spanCnt && spans < end ) { + while (spanCnt > 0 && spans < end ) { if (clipSpans > clipEnd) { spans = end; break; diff --git a/src/lib/tvgArray.h b/src/lib/tvgArray.h index 7036cda8..a8ac2744 100644 --- a/src/lib/tvgArray.h +++ b/src/lib/tvgArray.h @@ -22,6 +22,7 @@ #ifndef _TVG_ARRAY_H_ #define _TVG_ARRAY_H_ +#include namespace tvg { @@ -42,12 +43,20 @@ struct Array data[count++] = element; } + void reserve(uint32_t size) + { + if (size > reserved) { + reserved = size; + data = static_cast(realloc(data, sizeof(T) * reserved)); + } + } + void pop() { if (count > 0) --count; } - void clear() + void reset() { if (data) { free(data); @@ -56,6 +65,18 @@ struct Array count = reserved = 0; } + void clear() + { + count = 0; + } + + void operator=(const Array& rhs) + { + reserve(rhs.count); + memcpy(data, rhs.data, sizeof(T) * reserved); + count = rhs.count; + } + ~Array() { if (data) free(data); diff --git a/src/lib/tvgCanvasImpl.h b/src/lib/tvgCanvasImpl.h index 5df625c0..03527c86 100644 --- a/src/lib/tvgCanvasImpl.h +++ b/src/lib/tvgCanvasImpl.h @@ -22,7 +22,6 @@ #ifndef _TVG_CANVAS_IMPL_H_ #define _TVG_CANVAS_IMPL_H_ -#include #include "tvgPaint.h" /************************************************************************/ @@ -31,7 +30,7 @@ struct Canvas::Impl { - vector paints; + Array paints; RenderMethod* renderer; Impl(RenderMethod* pRenderer):renderer(pRenderer) @@ -48,7 +47,7 @@ struct Canvas::Impl { auto p = paint.release(); if (!p) return Result::MemoryCorruption; - paints.push_back(p); + paints.push(p); return update(p); } @@ -62,9 +61,9 @@ struct Canvas::Impl //free paints if (free) { - for (auto paint : paints) { - paint->pImpl->dispose(*renderer); - delete(paint); + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + (*paint)->pImpl->dispose(*renderer); + delete(*paint); } } @@ -77,15 +76,15 @@ struct Canvas::Impl { if (!renderer) return Result::InsufficientCondition; - vector compList; + Array compList; //Update single paint node if (paint) { paint->pImpl->update(*renderer, nullptr, 255, compList, RenderUpdateFlag::None); //Update all retained paint nodes } else { - for (auto paint : paints) { - paint->pImpl->update(*renderer, nullptr, 255, compList, RenderUpdateFlag::None); + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + (*paint)->pImpl->update(*renderer, nullptr, 255, compList, RenderUpdateFlag::None); } } return Result::Success; @@ -97,8 +96,8 @@ struct Canvas::Impl if (!renderer->preRender()) return Result::InsufficientCondition; - for (auto paint : paints) { - if (!paint->pImpl->render(*renderer)) return Result::InsufficientCondition; + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + if (!(*paint)->pImpl->render(*renderer)) return Result::InsufficientCondition; } if (!renderer->postRender()) return Result::InsufficientCondition; diff --git a/src/lib/tvgPaint.h b/src/lib/tvgPaint.h index d3907132..0d811a21 100644 --- a/src/lib/tvgPaint.h +++ b/src/lib/tvgPaint.h @@ -26,6 +26,7 @@ #include #include "tvgRender.h" + namespace tvg { struct StrategyMethod @@ -33,7 +34,7 @@ namespace tvg virtual ~StrategyMethod() {} virtual bool dispose(RenderMethod& renderer) = 0; - virtual void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, vector compList, RenderUpdateFlag pFlag) = 0; //Return engine data if it has. + virtual void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag pFlag) = 0; //Return engine data if it has. virtual bool render(RenderMethod& renderer) = 0; virtual bool bounds(float* x, float* y, float* w, float* h) const = 0; virtual Paint* duplicate() = 0; @@ -51,6 +52,7 @@ namespace tvg uint8_t opacity = 255; ~Impl() { + if (compTarget) delete(compTarget); if (smethod) delete(smethod); if (rTransform) delete(rTransform); } @@ -129,7 +131,7 @@ namespace tvg return smethod->dispose(renderer); } - void* update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, vector& compList, uint32_t pFlag) + void* update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, Array& compList, uint32_t pFlag) { if (flag & RenderUpdateFlag::Transform) { if (!rTransform) return nullptr; @@ -143,7 +145,7 @@ namespace tvg if (compTarget && compMethod == CompositeMethod::ClipPath) { compdata = compTarget->pImpl->update(renderer, pTransform, opacity, compList, pFlag); - if (compdata) compList.push_back({compdata, compMethod}); + if (compdata) compList.push({compdata, compMethod}); } void *edata = nullptr; @@ -159,7 +161,7 @@ namespace tvg edata = smethod->update(renderer, outTransform, opacity, compList, newFlag); } - if (compdata) compList.pop_back(); + if (compdata) compList.pop(); return edata; } @@ -215,7 +217,7 @@ namespace tvg return inst->dispose(renderer); } - void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, vector compList, RenderUpdateFlag flag) override + void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag flag) override { return inst->update(renderer, transform, opacity, compList, flag); } diff --git a/src/lib/tvgPictureImpl.h b/src/lib/tvgPictureImpl.h index 40505125..0e52963f 100644 --- a/src/lib/tvgPictureImpl.h +++ b/src/lib/tvgPictureImpl.h @@ -110,7 +110,7 @@ struct Picture::Impl return RenderUpdateFlag::None; } - void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, vector& compList, RenderUpdateFlag pFlag) + void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag pFlag) { uint32_t flag = reload(); diff --git a/src/lib/tvgRender.h b/src/lib/tvgRender.h index c5e625b5..383f6784 100644 --- a/src/lib/tvgRender.h +++ b/src/lib/tvgRender.h @@ -22,8 +22,8 @@ #ifndef _TVG_RENDER_H_ #define _TVG_RENDER_H_ -#include #include "tvgCommon.h" +#include "tvgArray.h" namespace tvg { @@ -65,8 +65,8 @@ class RenderMethod { public: virtual ~RenderMethod() {} - virtual void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, vector& compList, RenderUpdateFlag flags) = 0; - virtual void* prepare(const Picture& picture, void* data, uint32_t *buffer, const RenderTransform* transform, uint32_t opacity, vector& compList, RenderUpdateFlag flags) = 0; + virtual void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag flags) = 0; + virtual void* prepare(const Picture& picture, void* data, uint32_t *buffer, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag flags) = 0; virtual void* beginComposite(uint32_t x, uint32_t y, uint32_t w, uint32_t h) = 0; virtual bool endComposite(void* ctx, uint32_t opacity) = 0; virtual bool dispose(void *data) = 0; diff --git a/src/lib/tvgScene.cpp b/src/lib/tvgScene.cpp index fae2ff34..94721231 100644 --- a/src/lib/tvgScene.cpp +++ b/src/lib/tvgScene.cpp @@ -47,7 +47,7 @@ Result Scene::push(unique_ptr paint) noexcept { auto p = paint.release(); if (!p) return Result::MemoryCorruption; - pImpl->paints.push_back(p); + pImpl->paints.push(p); return Result::Success; } diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index 21fa75d8..9a9f36c2 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -22,7 +22,6 @@ #ifndef _TVG_SCENE_IMPL_H_ #define _TVG_SCENE_IMPL_H_ -#include #include "tvgPaint.h" /************************************************************************/ @@ -31,21 +30,21 @@ struct Scene::Impl { - vector paints; + Array paints; uint32_t opacity; bool dispose(RenderMethod& renderer) { - for (auto paint : paints) { - paint->pImpl->dispose(renderer); - delete(paint); + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + (*paint)->pImpl->dispose(renderer); + delete(*paint); } paints.clear(); return true; } - void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, vector& compList, RenderUpdateFlag flag) + void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag flag) { this->opacity = opacity; @@ -57,8 +56,8 @@ struct Scene::Impl This is necessary for scene composition */ void* edata = nullptr; - for (auto paint : paints) { - edata = paint->pImpl->update(renderer, transform, opacity, compList, static_cast(flag)); + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + edata = (*paint)->pImpl->update(renderer, transform, opacity, compList, static_cast(flag)); } return edata; @@ -77,8 +76,8 @@ struct Scene::Impl ctx = renderer.beginComposite(0, 0, 0, 0); } - for (auto paint : paints) { - if (!paint->pImpl->render(renderer)) return false; + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + if (!(*paint)->pImpl->render(renderer)) return false; } if (ctx) return renderer.endComposite(ctx, opacity); @@ -88,20 +87,20 @@ struct Scene::Impl bool bounds(float* px, float* py, float* pw, float* ph) { - if (paints.size() == 0) return false; + if (paints.count == 0) return false; auto x1 = FLT_MAX; auto y1 = FLT_MAX; auto x2 = 0.0f; auto y2 = 0.0f; - for (auto paint : paints) { + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { auto x = FLT_MAX; auto y = FLT_MAX; auto w = 0.0f; auto h = 0.0f; - if (!paint->pImpl->bounds(&x, &y, &w, &h)) continue; + if (!(*paint)->pImpl->bounds(&x, &y, &w, &h)) continue; //Merge regions if (x < x1) x1 = x; @@ -124,10 +123,10 @@ struct Scene::Impl if (!ret) return nullptr; auto dup = ret.get()->pImpl; - dup->paints.reserve(paints.size()); + dup->paints.reserve(paints.count); - for (auto paint : paints) { - dup->paints.push_back(paint->duplicate()); + for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + dup->paints.push((*paint)->duplicate()); } return ret.release(); diff --git a/src/lib/tvgShapeImpl.h b/src/lib/tvgShapeImpl.h index bd13ff75..7df14259 100644 --- a/src/lib/tvgShapeImpl.h +++ b/src/lib/tvgShapeImpl.h @@ -223,7 +223,7 @@ struct Shape::Impl return renderer.render(*shape, edata); } - void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, vector& compList, RenderUpdateFlag pFlag) + void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array& compList, RenderUpdateFlag pFlag) { this->edata = renderer.prepare(*shape, this->edata, transform, opacity, compList, static_cast(pFlag | flag)); flag = RenderUpdateFlag::None; diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index 71e7599b..85f86cbf 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -2196,6 +2196,7 @@ static void _styleInherit(SvgStyleProperty* child, SvgStyleProperty* parent) if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Dash)) { if (parent->stroke.dash.array.count > 0) { child->stroke.dash.array.clear(); + child->stroke.dash.array.reserve(parent->stroke.dash.array.count); for (uint32_t i = 0; i < parent->stroke.dash.array.count; ++i) { child->stroke.dash.array.push(parent->stroke.dash.array.data[i]); } @@ -2297,7 +2298,7 @@ static void _freeGradientStyle(SvgStyleGradient* grad) auto colorStop = grad->stops.data[i]; free(colorStop); } - grad->stops.clear(); + grad->stops.reset(); free(grad); } @@ -2308,7 +2309,7 @@ static void _freeNodeStyle(SvgStyleProperty* style) _freeGradientStyle(style->fill.paint.gradient); delete style->fill.paint.url; _freeGradientStyle(style->stroke.paint.gradient); - if (style->stroke.dash.array.count > 0) style->stroke.dash.array.clear(); + if (style->stroke.dash.array.count > 0) style->stroke.dash.array.reset(); delete style->stroke.paint.url; free(style); } @@ -2321,7 +2322,7 @@ static void _freeNode(SvgNode* node) for (uint32_t i = 0; i < node->child.count; ++i, ++child) { _freeNode(*child); } - node->child.clear(); + node->child.reset(); delete node->id; free(node->transform); @@ -2349,7 +2350,7 @@ static void _freeNode(SvgNode* node) _freeGradientStyle(*gradients); ++gradients; } - node->node.defs.gradients.clear(); + node->node.defs.gradients.reset(); break; } default: { @@ -2540,11 +2541,11 @@ bool SvgLoader::close() _freeGradientStyle(*gradients); ++gradients; } - loaderData.gradients.clear(); + loaderData.gradients.reset(); _freeNode(loaderData.doc); loaderData.doc = nullptr; - loaderData.stack.clear(); + loaderData.stack.reset(); return true; }