From b214fd23bc4df3a42d41d31ab1c49d6c65151fb4 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 7 Jun 2023 18:17:35 +0900 Subject: [PATCH] common canvas/scene: introduce paints() api that returns the list of the paints. These new apis would enable users to easily modify the motion scene, The data structure of the paints has been changed from an array to a list. @APIs: std::list& Canvas::paints() noexcept; std::list& Scene::paints() noexcept; @Deprecated: Result Canvas::reserve(uint32_t size) noexcept; Result Scene::reserve(uint32_t size) noexcept; @Issue: https://github.com/thorvg/thorvg/issues/1203 --- inc/thorvg.h | 40 +++++++++++--- src/bindings/capi/thorvg_capi.h | 8 ++- src/bindings/capi/tvgCapi.cpp | 6 +-- src/examples/Blending.cpp | 2 - src/examples/Capi.cpp | 3 -- src/examples/ClipPath.cpp | 1 - src/examples/Duplicate.cpp | 1 - src/examples/LinearGradient.cpp | 2 - src/examples/MultiShapes.cpp | 2 - src/examples/Opacity.cpp | 2 - src/examples/RadialGradient.cpp | 2 - src/examples/Scene.cpp | 2 - src/examples/SceneTransform.cpp | 2 - src/examples/Stacking.cpp | 2 - src/lib/tvgCanvas.cpp | 11 ++-- src/lib/tvgCanvasImpl.h | 26 ++++----- src/lib/tvgScene.cpp | 14 +++-- src/lib/tvgSceneImpl.h | 69 ++++++++++++------------ src/lib/tvgSwCanvas.cpp | 2 +- src/loaders/tvg/tvgTvgBinInterpreter.cpp | 9 ---- test/capi/capiScene.cpp | 17 ------ test/capi/capiSwCanvas.cpp | 17 ------ test/testScene.cpp | 12 ----- test/testSwCanvasBase.cpp | 16 ------ 24 files changed, 105 insertions(+), 163 deletions(-) diff --git a/inc/thorvg.h b/inc/thorvg.h index 0cfe7e24..d31458b3 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -18,6 +18,7 @@ #include #include #include +#include #ifdef TVG_API #undef TVG_API @@ -548,14 +549,25 @@ public: * * @return Result::Success when succeed. */ - Result reserve(uint32_t n) noexcept; + TVG_DEPRECATED Result reserve(uint32_t n) noexcept; + + /** + * @brief Returns the list of the paints that currently held by the Canvas. + * + * This function provides the list of paint nodes, allowing users a direct opportunity to modify the scene tree. + * + * @warning Please avoid accessing the paints during Canvas update/draw. You can access them after calling sync(). + * @see Canvas::sync() + * + * @BETA_API + */ + std::list& paints() noexcept; /** * @brief Passes drawing elements to the Canvas using Paint objects. * * Only pushed paints in the canvas will be drawing targets. * They are retained by the canvas until you call Canvas::clear(). - * If you know the number of the pushed objects in advance, please call Canvas::reserve(). * * @param[in] paint A Paint object to be drawn. * @@ -564,7 +576,7 @@ public: * @retval Result::InsufficientCondition An internal error. * * @note The rendering order of the paints is the same as the order as they were pushed into the canvas. Consider sorting the paints before pushing them if you intend to use layering. - * @see Canvas::reserve() + * @see Canvas::paints() * @see Canvas::clear() */ virtual Result push(std::unique_ptr paint) noexcept; @@ -578,6 +590,8 @@ public: * @return Result::Success when succeed, Result::InsufficientCondition otherwise. * * @warning If you don't free the paints they become dangled. They are supposed to be reused, otherwise you are responsible for their lives. Thus please use the @p free argument only when you know how it works, otherwise it's not recommended. + * @see Canvas::push() + * @see Canvas::paints() */ virtual Result clear(bool free = true) noexcept; @@ -1329,14 +1343,14 @@ public: * * Only the paints pushed into the scene will be the drawn targets. * The paints are retained by the scene until Scene::clear() is called. - * If you know the number of the pushed objects in advance, please call Scene::reserve(). * * @param[in] paint A Paint object to be drawn. * * @return Result::Success when succeed, Result::MemoryCorruption otherwise. * * @note The rendering order of the paints is the same as the order as they were pushed. Consider sorting the paints before pushing them if you intend to use layering. - * @see Scene::reserve() + * @see Scene::paints() + * @see Scene::clear() */ Result push(std::unique_ptr paint) noexcept; @@ -1350,7 +1364,21 @@ public: * * @return Result::Success when succeed, Result::FailedAllocation otherwise. */ - Result reserve(uint32_t size) noexcept; + TVG_DEPRECATED Result reserve(uint32_t size) noexcept; + + /** + * @brief Returns the list of the paints that currently held by the Scene. + * + * This function provides the list of paint nodes, allowing users a direct opportunity to modify the scene tree. + * + * @warning Please avoid accessing the paints during Scene update/draw. You can access them after calling Canvas::sync(). + * @see Canvas::sync() + * @see Scene::push() + * @see Scene::clear() + * + * @BETA_API + */ + std::list& paints() noexcept; /** * @brief Sets the total number of the paints pushed into the scene to be zero. diff --git a/src/bindings/capi/thorvg_capi.h b/src/bindings/capi/thorvg_capi.h index 3c1fccac..93c09eb2 100644 --- a/src/bindings/capi/thorvg_capi.h +++ b/src/bindings/capi/thorvg_capi.h @@ -540,7 +540,7 @@ TVG_API Tvg_Result tvg_canvas_destroy(Tvg_Canvas* canvas); * \retval TVG_RESULT_INSUFFICIENT_CONDITION An internal error. * * \note The rendering order of the paints is the same as the order as they were pushed. Consider sorting the paints before pushing them if you intend to use layering. -* \see tvg_canvas_reserve(), tvg_canvas_clear() +* \see tvg_canvas_clear() */ TVG_API Tvg_Result tvg_canvas_push(Tvg_Canvas* canvas, Tvg_Paint* paint); @@ -562,7 +562,6 @@ TVG_API Tvg_Result tvg_canvas_push(Tvg_Canvas* canvas, Tvg_Paint* paint); * if (!buffer) return; * * tvg_swcanvas_set_target(canvas, buffer, 100, 100, 100, TVG_COLORSPACE_ARGB8888); -* tvg_canvas_reserve(canvas, 100); //reserve array for 100 paints in canvas. * * tvg_canvas_destroy(canvas); * tvg_engine_term(TVG_ENGINE_SW) @@ -576,7 +575,7 @@ TVG_API Tvg_Result tvg_canvas_push(Tvg_Canvas* canvas, Tvg_Paint* paint); * \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Canvas pointer. * \retval TVG_RESULT_FAILED_ALLOCATION An internal error with memory allocation. */ -TVG_API Tvg_Result tvg_canvas_reserve(Tvg_Canvas* canvas, uint32_t n); +TVG_DEPRECATED TVG_API Tvg_Result tvg_canvas_reserve(Tvg_Canvas* canvas, uint32_t n); /*! @@ -1976,7 +1975,7 @@ TVG_API Tvg_Paint* tvg_scene_new(); * \retval TVG_RESULT_FAILED_ALLOCATION An internal error with a memory allocation. * \retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. */ -TVG_API Tvg_Result tvg_scene_reserve(Tvg_Paint* scene, uint32_t size); +TVG_DEPRECATED TVG_API Tvg_Result tvg_scene_reserve(Tvg_Paint* scene, uint32_t size); /*! @@ -1995,7 +1994,6 @@ TVG_API Tvg_Result tvg_scene_reserve(Tvg_Paint* scene, uint32_t size); * \retval TVG_RESULT_MEMORY_CORRUPTION An internal error. * * \note The rendering order of the paints is the same as the order as they were pushed. Consider sorting the paints before pushing them if you intend to use layering. -* \see tvg_scene_reserve() */ TVG_API Tvg_Result tvg_scene_push(Tvg_Paint* scene, Tvg_Paint* paint); diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp index 810349f7..3e9831dc 100644 --- a/src/bindings/capi/tvgCapi.cpp +++ b/src/bindings/capi/tvgCapi.cpp @@ -89,8 +89,7 @@ TVG_API Tvg_Result tvg_canvas_push(Tvg_Canvas* canvas, Tvg_Paint* paint) TVG_API Tvg_Result tvg_canvas_reserve(Tvg_Canvas* canvas, uint32_t n) { - if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; - return (Tvg_Result) reinterpret_cast(canvas)->reserve(n); + return TVG_RESULT_NOT_SUPPORTED; } @@ -638,8 +637,7 @@ TVG_API Tvg_Paint* tvg_scene_new() TVG_API Tvg_Result tvg_scene_reserve(Tvg_Paint* scene, uint32_t size) { - if (!scene) return TVG_RESULT_INVALID_ARGUMENT; - return (Tvg_Result) reinterpret_cast(scene)->reserve(size); + return TVG_RESULT_NOT_SUPPORTED; } diff --git a/src/examples/Blending.cpp b/src/examples/Blending.cpp index ef92552f..40540e18 100644 --- a/src/examples/Blending.cpp +++ b/src/examples/Blending.cpp @@ -30,8 +30,6 @@ void tvgDrawCmds(tvg::Canvas* canvas) { if (!canvas) return; - canvas->reserve(5); - //Prepare Round Rectangle auto shape1 = tvg::Shape::gen(); shape1->appendRect(0, 0, 400, 400, 50, 50); //x, y, w, h, rx, ry diff --git a/src/examples/Capi.cpp b/src/examples/Capi.cpp index 7dc8f319..1a0167f9 100644 --- a/src/examples/Capi.cpp +++ b/src/examples/Capi.cpp @@ -41,8 +41,6 @@ void testCapi() tvg_swcanvas_set_target(canvas, buffer, WIDTH, WIDTH, HEIGHT, TVG_COLORSPACE_ARGB8888); tvg_swcanvas_set_mempool(canvas, TVG_MEMPOOL_POLICY_DEFAULT); - tvg_canvas_reserve(canvas, 6); - //////1. Linear gradient shape with a linear gradient stroke //Set a shape Tvg_Paint* shape1 = tvg_shape_new(); @@ -148,7 +146,6 @@ void testCapi() //////4. Scene //Set a scene Tvg_Paint* scene = tvg_scene_new(); - tvg_scene_reserve(scene, 2); //Set an arc Tvg_Paint* scene_shape1 = tvg_shape_new(); diff --git a/src/examples/ClipPath.cpp b/src/examples/ClipPath.cpp index 7ca57002..125807fa 100644 --- a/src/examples/ClipPath.cpp +++ b/src/examples/ClipPath.cpp @@ -52,7 +52,6 @@ void tvgDrawCmds(tvg::Canvas* canvas) ////////////////////////////////////////////// auto scene = tvg::Scene::gen(); - scene->reserve(2); auto star1 = tvg::Shape::gen(); tvgDrawStar(star1.get()); diff --git a/src/examples/Duplicate.cpp b/src/examples/Duplicate.cpp index 718173a0..9e9c9ef9 100644 --- a/src/examples/Duplicate.cpp +++ b/src/examples/Duplicate.cpp @@ -72,7 +72,6 @@ void tvgDrawCmds(tvg::Canvas* canvas) { //Create a Scene1 auto scene1 = tvg::Scene::gen(); - scene1->reserve(3); auto shape1 = tvg::Shape::gen(); shape1->appendRect(0, 0, 400, 400, 50, 50); diff --git a/src/examples/LinearGradient.cpp b/src/examples/LinearGradient.cpp index 358b1879..52ac939f 100644 --- a/src/examples/LinearGradient.cpp +++ b/src/examples/LinearGradient.cpp @@ -30,8 +30,6 @@ void tvgDrawCmds(tvg::Canvas* canvas) { if (!canvas) return; - canvas->reserve(3); //reserve 3 shape nodes (optional) - //Prepare Round Rectangle auto shape1 = tvg::Shape::gen(); shape1->appendRect(0, 0, 400, 400, 0, 0); //x, y, w, h, rx, ry diff --git a/src/examples/MultiShapes.cpp b/src/examples/MultiShapes.cpp index 342020e5..aebba027 100644 --- a/src/examples/MultiShapes.cpp +++ b/src/examples/MultiShapes.cpp @@ -30,8 +30,6 @@ void tvgDrawCmds(tvg::Canvas* canvas) { if (!canvas) return; - canvas->reserve(3); //reserve 3 shape nodes (optional) - //Prepare Round Rectangle auto shape1 = tvg::Shape::gen(); shape1->appendRect(0, 0, 400, 400, 50, 50); //x, y, w, h, rx, ry diff --git a/src/examples/Opacity.cpp b/src/examples/Opacity.cpp index 6c00e573..2c2dc286 100644 --- a/src/examples/Opacity.cpp +++ b/src/examples/Opacity.cpp @@ -33,7 +33,6 @@ void tvgDrawCmds(tvg::Canvas* canvas) //Create a Scene auto scene = tvg::Scene::gen(); scene->opacity(175); //Apply opacity to scene (0 - 255) - scene->reserve(2); //Prepare Circle auto shape1 = tvg::Shape::gen(); @@ -57,7 +56,6 @@ void tvgDrawCmds(tvg::Canvas* canvas) auto scene2 = tvg::Scene::gen(); scene2->opacity(127); //Apply opacity to scene (0 - 255) scene2->scale(1.2); - scene2->reserve(2); //Star auto shape3 = tvg::Shape::gen(); diff --git a/src/examples/RadialGradient.cpp b/src/examples/RadialGradient.cpp index 71de4702..247942a2 100644 --- a/src/examples/RadialGradient.cpp +++ b/src/examples/RadialGradient.cpp @@ -30,8 +30,6 @@ void tvgDrawCmds(tvg::Canvas* canvas) { if (!canvas) return; - canvas->reserve(3); //reserve 3 shape nodes (optional) - //Prepare Round Rectangle auto shape1 = tvg::Shape::gen(); shape1->appendRect(0, 0, 400, 400, 0, 0); //x, y, w, h, rx, ry diff --git a/src/examples/Scene.cpp b/src/examples/Scene.cpp index 1dd1471c..3ac496b6 100644 --- a/src/examples/Scene.cpp +++ b/src/examples/Scene.cpp @@ -32,7 +32,6 @@ void tvgDrawCmds(tvg::Canvas* canvas) //Create a Scene auto scene = tvg::Scene::gen(); - scene->reserve(3); //reserve 3 shape nodes (optional) //Prepare Round Rectangle auto shape1 = tvg::Shape::gen(); @@ -54,7 +53,6 @@ void tvgDrawCmds(tvg::Canvas* canvas) //Create another Scene auto scene2 = tvg::Scene::gen(); - scene2->reserve(2); //reserve 2 shape nodes (optional) //Star auto shape4 = tvg::Shape::gen(); diff --git a/src/examples/SceneTransform.cpp b/src/examples/SceneTransform.cpp index 0715ffa2..36199946 100644 --- a/src/examples/SceneTransform.cpp +++ b/src/examples/SceneTransform.cpp @@ -34,7 +34,6 @@ void tvgUpdateCmds(tvg::Canvas* canvas, float progress) //Create a Scene1 auto scene = tvg::Scene::gen(); - scene->reserve(3); //reserve 3 shape nodes (optional) //Prepare Round Rectangle (Scene1) auto shape1 = tvg::Shape::gen(); @@ -62,7 +61,6 @@ void tvgUpdateCmds(tvg::Canvas* canvas, float progress) //Create Scene2 auto scene2 = tvg::Scene::gen(); - scene2->reserve(2); //reserve 2 shape nodes (optional) //Star (Scene2) auto shape4 = tvg::Shape::gen(); diff --git a/src/examples/Stacking.cpp b/src/examples/Stacking.cpp index 1e311ecc..a4e08d86 100644 --- a/src/examples/Stacking.cpp +++ b/src/examples/Stacking.cpp @@ -33,8 +33,6 @@ void tvgDrawCmds(tvg::Canvas* canvas) { if (!canvas) return; - canvas->reserve(4); //reserve 3 shape nodes (optional) - //Prepare Round Rectangle auto shape1 = tvg::Shape::gen(); paints[0] = shape1.get(); diff --git a/src/lib/tvgCanvas.cpp b/src/lib/tvgCanvas.cpp index 7e17802d..1dee3703 100644 --- a/src/lib/tvgCanvas.cpp +++ b/src/lib/tvgCanvas.cpp @@ -37,10 +37,15 @@ Canvas::~Canvas() } -Result Canvas::reserve(uint32_t n) noexcept +Result Canvas::reserve(TVG_UNUSED uint32_t n) noexcept { - if (!pImpl->paints.reserve(n)) return Result::FailedAllocation; - return Result::Success; + return Result::NonSupport; +} + + +list& Canvas::paints() noexcept +{ + return pImpl->paints; } diff --git a/src/lib/tvgCanvasImpl.h b/src/lib/tvgCanvasImpl.h index 6f5760f5..0a38e05d 100644 --- a/src/lib/tvgCanvasImpl.h +++ b/src/lib/tvgCanvasImpl.h @@ -31,7 +31,7 @@ struct Canvas::Impl { - Array paints; + list paints; RenderMethod* renderer; bool refresh = false; //if all paints should be updated by force. bool drawing = false; //on drawing condition? @@ -53,7 +53,7 @@ struct Canvas::Impl auto p = paint.release(); if (!p) return Result::MemoryCorruption; - paints.push(p); + paints.push_back(p); return update(p, true); } @@ -64,9 +64,9 @@ struct Canvas::Impl if (!renderer || !renderer->clear()) return Result::InsufficientCondition; //Free paints - for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { - (*paint)->pImpl->dispose(*renderer); - if (free) delete(*paint); + for (auto paint : paints) { + paint->pImpl->dispose(*renderer); + if (free) delete(paint); } paints.clear(); @@ -83,7 +83,7 @@ struct Canvas::Impl Result update(Paint* paint, bool force) { - if (paints.count == 0 || drawing || !renderer) return Result::InsufficientCondition; + if (paints.empty() || drawing || !renderer) return Result::InsufficientCondition; Array clips; auto flag = RenderUpdateFlag::None; @@ -92,8 +92,8 @@ struct Canvas::Impl //Update single paint node if (paint) { //Optimize Me: Can we skip the searching? - for (auto paint2 = paints.data; paint2 < (paints.data + paints.count); ++paint2) { - if ((*paint2) == paint) { + for (auto paint2 : paints) { + if (paint2 == paint) { paint->pImpl->update(*renderer, nullptr, 255, clips, flag); return Result::Success; } @@ -101,8 +101,8 @@ struct Canvas::Impl return Result::InvalidArguments; //Update all retained paint nodes } else { - for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { - (*paint)->pImpl->update(*renderer, nullptr, 255, clips, flag); + for (auto paint : paints) { + paint->pImpl->update(*renderer, nullptr, 255, clips, flag); } } @@ -113,11 +113,11 @@ struct Canvas::Impl Result draw() { - if (drawing || paints.count == 0 || !renderer || !renderer->preRender()) return Result::InsufficientCondition; + if (drawing || paints.empty() || !renderer || !renderer->preRender()) return Result::InsufficientCondition; bool rendered = false; - for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { - if ((*paint)->pImpl->render(*renderer)) rendered = true; + for (auto paint : paints) { + if (paint->pImpl->render(*renderer)) rendered = true; } if (!rendered || !renderer->postRender()) return Result::InsufficientCondition; diff --git a/src/lib/tvgScene.cpp b/src/lib/tvgScene.cpp index feb45a9d..9fd2ad70 100644 --- a/src/lib/tvgScene.cpp +++ b/src/lib/tvgScene.cpp @@ -55,17 +55,15 @@ Result Scene::push(unique_ptr paint) noexcept { auto p = paint.release(); if (!p) return Result::MemoryCorruption; - pImpl->paints.push(p); + pImpl->paints.push_back(p); return Result::Success; } -Result Scene::reserve(uint32_t size) noexcept +Result Scene::reserve(TVG_UNUSED uint32_t size) noexcept { - if (!pImpl->paints.reserve(size)) return Result::FailedAllocation; - - return Result::Success; + return Result::NonSupport; } @@ -75,3 +73,9 @@ Result Scene::clear(bool free) noexcept return Result::Success; } + + +list& Scene::paints() noexcept +{ + return pImpl->paints; +} \ No newline at end of file diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index 504cee4d..ecff5161 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -32,33 +32,36 @@ struct SceneIterator : Iterator { - Array* paints; - uint32_t idx = 0; + list* paints; + list::iterator itr; - SceneIterator(Array* p) : paints(p) + SceneIterator(list* p) : paints(p) { + begin(); } const Paint* next() override { - if (idx >= paints->count) return nullptr; - return paints->data[idx++]; + if (itr == paints->end()) return nullptr; + auto paint = *itr; + ++itr; + return paint; } uint32_t count() override { - return paints->count; + return paints->size(); } void begin() override { - idx = 0; + itr = paints->begin(); } }; struct Scene::Impl { - Array paints; + list paints; RenderMethod* renderer = nullptr; //keep it for explicit clear RenderData rd = nullptr; Scene* scene = nullptr; @@ -71,15 +74,15 @@ struct Scene::Impl ~Impl() { - for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { - delete(*paint); + for (auto paint : paints) { + delete(paint); } } bool dispose(RenderMethod& renderer) { - for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { - (*paint)->pImpl->dispose(renderer); + for (auto paint : paints) { + paint->pImpl->dispose(renderer); } auto ret = renderer.dispose(rd); @@ -91,7 +94,7 @@ struct Scene::Impl bool needComposition(uint32_t opacity) { - if (opacity == 0 || paints.count == 0) return false; + if (opacity == 0 || paints.empty()) return false; //Masking may require composition (even if opacity == 255) auto compMethod = scene->composite(nullptr); @@ -103,7 +106,7 @@ struct Scene::Impl //If scene has several children or only scene, it may require composition. //OPTIMIZE: the bitmap type of the picture would not need the composition. //OPTIMIZE: a single paint of a scene would not need the composition. - if (paints.count == 1 && (*paints.data)->identifier() == TVG_CLASS_ID_SHAPE) return false; + if (paints.size() == 1 && paints.front()->identifier() == TVG_CLASS_ID_SHAPE) return false; return true; } @@ -121,15 +124,15 @@ struct Scene::Impl if (clipper) { Array rds; - rds.reserve(paints.count); - for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { - rds.push((*paint)->pImpl->update(renderer, transform, opacity, clips, flag, true)); + rds.reserve(paints.size()); + for (auto paint : paints) { + rds.push(paint->pImpl->update(renderer, transform, opacity, clips, flag, true)); } rd = renderer.prepare(rds, rd, transform, opacity, clips, flag); return rd; } else { - for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { - (*paint)->pImpl->update(renderer, transform, opacity, clips, flag, false); + for (auto paint : paints) { + paint->pImpl->update(renderer, transform, opacity, clips, flag, false); } return nullptr; } @@ -144,8 +147,8 @@ struct Scene::Impl renderer.beginComposite(cmp, CompositeMethod::None, opacity); } - for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { - if (!(*paint)->pImpl->render(renderer)) return false; + for (auto paint : paints) { + if (!paint->pImpl->render(renderer)) return false; } if (cmp) renderer.endComposite(cmp); @@ -155,15 +158,15 @@ struct Scene::Impl RenderRegion bounds(RenderMethod& renderer) const { - if (paints.count == 0) return {0, 0, 0, 0}; + if (paints.empty()) return {0, 0, 0, 0}; int32_t x1 = INT32_MAX; int32_t y1 = INT32_MAX; int32_t x2 = 0; int32_t y2 = 0; - for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { - auto region = (*paint)->pImpl->bounds(renderer); + for (auto paint : paints) { + auto region = paint->pImpl->bounds(renderer); //Merge regions if (region.x < x1) x1 = region.x; @@ -177,20 +180,20 @@ struct Scene::Impl bool bounds(float* px, float* py, float* pw, float* ph) { - if (paints.count == 0) return false; + if (paints.empty()) return false; auto x1 = FLT_MAX; auto y1 = FLT_MAX; auto x2 = -FLT_MAX; auto y2 = -FLT_MAX; - for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { + for (auto paint : paints) { auto x = FLT_MAX; auto y = FLT_MAX; auto w = 0.0f; auto h = 0.0f; - if ((*paint)->bounds(&x, &y, &w, &h, true) != tvg::Result::Success) continue; + if (paint->bounds(&x, &y, &w, &h, true) != tvg::Result::Success) continue; //Merge regions if (x < x1) x1 = x; @@ -213,10 +216,8 @@ struct Scene::Impl auto dup = ret.get()->pImpl; - dup->paints.reserve(paints.count); - - for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { - dup->paints.push((*paint)->duplicate()); + for (auto paint : paints) { + dup->paints.push_back(paint->duplicate()); } return ret.release(); @@ -226,9 +227,9 @@ struct Scene::Impl { auto dispose = renderer ? true : false; - for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { - if (dispose) (*paint)->pImpl->dispose(*renderer); - if (free) delete(*paint); + for (auto paint : paints) { + if (dispose) paint->pImpl->dispose(*renderer); + if (free) delete(paint); } paints.clear(); renderer = nullptr; diff --git a/src/lib/tvgSwCanvas.cpp b/src/lib/tvgSwCanvas.cpp index 626bd51a..7e6bc40c 100644 --- a/src/lib/tvgSwCanvas.cpp +++ b/src/lib/tvgSwCanvas.cpp @@ -67,7 +67,7 @@ Result SwCanvas::mempool(MempoolPolicy policy) noexcept if (!renderer) return Result::MemoryCorruption; //It can't change the policy during the running. - if (Canvas::pImpl->paints.count > 0) return Result::InsufficientCondition; + if (!Canvas::pImpl->paints.empty()) return Result::InsufficientCondition; if (policy == MempoolPolicy::Individual) renderer->mempool(false); else renderer->mempool(true); diff --git a/src/loaders/tvg/tvgTvgBinInterpreter.cpp b/src/loaders/tvg/tvgTvgBinInterpreter.cpp index db16fb3d..b5d1435e 100644 --- a/src/loaders/tvg/tvgTvgBinInterpreter.cpp +++ b/src/loaders/tvg/tvgTvgBinInterpreter.cpp @@ -108,15 +108,6 @@ static bool _parseScene(TvgBinBlock block, Paint *paint) { auto scene = static_cast(paint); - //Case1: scene reserve count - if (block.type == TVG_TAG_SCENE_RESERVEDCNT) { - if (block.length != SIZE(uint32_t)) return false; - uint32_t reservedCnt; - READ_UI32(&reservedCnt, block.data); - scene->reserve(reservedCnt); - return true; - } - //Case2: Base Paint Properties if (_parsePaintProperty(block, scene)) return true; diff --git a/test/capi/capiScene.cpp b/test/capi/capiScene.cpp index 387c9329..6701173c 100644 --- a/test/capi/capiScene.cpp +++ b/test/capi/capiScene.cpp @@ -55,23 +55,6 @@ TEST_CASE("Paints Into a Scene", "[capiScene]") REQUIRE(tvg_paint_del(scene) == TVG_RESULT_SUCCESS); } -TEST_CASE("Scene Reservation", "[capiScene]") -{ - Tvg_Paint* scene = tvg_scene_new(); - REQUIRE(scene); - - //Check Growth / Reduction - REQUIRE(tvg_scene_reserve(scene, 100) == TVG_RESULT_SUCCESS); - REQUIRE(tvg_scene_reserve(scene, 1000) == TVG_RESULT_SUCCESS); - REQUIRE(tvg_scene_reserve(scene, 100) == TVG_RESULT_SUCCESS); - REQUIRE(tvg_scene_reserve(scene, 0) == TVG_RESULT_SUCCESS); - - //Invalid scene - REQUIRE(tvg_scene_reserve(NULL, 1) == TVG_RESULT_INVALID_ARGUMENT); - - REQUIRE(tvg_paint_del(scene) == TVG_RESULT_SUCCESS); -} - TEST_CASE("Clear the Scene", "[capiScene]") { Tvg_Paint* scene = tvg_scene_new(); diff --git a/test/capi/capiSwCanvas.cpp b/test/capi/capiSwCanvas.cpp index 3d8a122d..e4260a42 100644 --- a/test/capi/capiSwCanvas.cpp +++ b/test/capi/capiSwCanvas.cpp @@ -48,23 +48,6 @@ TEST_CASE("Basic canvas", "[capiSwCanvas]") REQUIRE(tvg_engine_term(TVG_ENGINE_SW) == TVG_RESULT_SUCCESS); } -TEST_CASE("Memory Reservation", "[capiSwCanvas]") -{ - REQUIRE(tvg_engine_init(TVG_ENGINE_SW, 0) == TVG_RESULT_SUCCESS); - - Tvg_Canvas* canvas = tvg_swcanvas_create(); - REQUIRE(canvas); - - REQUIRE(tvg_canvas_reserve(canvas, 1) == TVG_RESULT_SUCCESS); - REQUIRE(tvg_canvas_reserve(canvas, 10) == TVG_RESULT_SUCCESS); - REQUIRE(tvg_canvas_reserve(canvas, 100) == TVG_RESULT_SUCCESS); - REQUIRE(tvg_canvas_reserve(canvas, 0) == TVG_RESULT_SUCCESS); - - REQUIRE(tvg_canvas_destroy(canvas) == TVG_RESULT_SUCCESS); - - REQUIRE(tvg_engine_term(TVG_ENGINE_SW) == TVG_RESULT_SUCCESS); -} - TEST_CASE("Canvas initialization", "[capiSwCanvas]") { uint32_t* buffer = (uint32_t*) malloc(sizeof(uint32_t) * 200 * 200); diff --git a/test/testScene.cpp b/test/testScene.cpp index fa4615a9..82456791 100644 --- a/test/testScene.cpp +++ b/test/testScene.cpp @@ -54,18 +54,6 @@ TEST_CASE("Pushing Paints Into Scene", "[tvgScene]") REQUIRE(scene->push(std::move(shape)) == Result::MemoryCorruption); } -TEST_CASE("Scene Memory Reservation", "[tvgScene]") -{ - auto scene = Scene::gen(); - REQUIRE(scene); - - //Check Growth / Reduction - REQUIRE(scene->reserve(10) == Result::Success); - REQUIRE(scene->reserve(1000) == Result::Success); - REQUIRE(scene->reserve(100) == Result::Success); - REQUIRE(scene->reserve(0) == Result::Success); -} - TEST_CASE("Scene Clear", "[tvgScene]") { auto scene = Scene::gen(); diff --git a/test/testSwCanvasBase.cpp b/test/testSwCanvasBase.cpp index cae8bda7..a40e5944 100644 --- a/test/testSwCanvasBase.cpp +++ b/test/testSwCanvasBase.cpp @@ -27,22 +27,6 @@ using namespace tvg; -TEST_CASE("Memory Reservation", "[tvgSwCanvasBase]") -{ - REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success); - - auto canvas = SwCanvas::gen(); - REQUIRE(canvas); - - //Check Growth / Reduction - REQUIRE(canvas->reserve(10) == Result::Success); - REQUIRE(canvas->reserve(1000) == Result::Success); - REQUIRE(canvas->reserve(100) == Result::Success); - REQUIRE(canvas->reserve(0) == Result::Success); - - REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success); -} - TEST_CASE("Pushing Paints", "[tvgSwCanvasBase]") { REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);