From 6761c5c2a04943595a377405c31cefb2d91da74b Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 10 Dec 2024 02:17:39 +0900 Subject: [PATCH] API: Replace the Canvas::clear() API with Canvas::remove() & draw() Added a `clear` parameter to Canvas::draw(), allowing users to decide whether to clear the target buffer before drawing. To remove the paints from a canvas, please use Canvas::remove() C++ API Removals: - Result Canvas::clear(bool paints, bool buffer) C++ API Modifications: - Result Canvas::draw() -> Result Canvas::draw(bool clear) C API Removals: - Tvg_Result tvg_canvas_clear(bool paints, bool buffer) C API Modifications: - Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas) -> Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas, bool clear) issue: https://github.com/thorvg/thorvg/issues/1372 --- examples/Animation.cpp | 2 +- examples/Blending.cpp | 2 +- examples/Capi.cpp | 5 +--- examples/CustomTransform.cpp | 4 +-- examples/DirectUpdate.cpp | 3 -- examples/EffectDropShadow.cpp | 4 +-- examples/EffectGaussianBlur.cpp | 4 +-- examples/Example.h | 6 ++-- examples/GradientTransform.cpp | 4 +-- examples/ImageRotation.cpp | 4 +-- examples/ImageScaleDown.cpp | 4 +-- examples/ImageScaleUp.cpp | 4 +-- examples/Interaction.cpp | 2 +- examples/Lottie.cpp | 2 +- examples/LottieExpressions.cpp | 2 +- examples/MaskingMethods.cpp | 2 +- examples/Performance.cpp | 4 +-- examples/Retaining.cpp | 2 +- examples/SceneTransform.cpp | 4 +-- examples/Svg.cpp | 2 +- examples/Transform.cpp | 4 +-- examples/Update.cpp | 4 +-- examples/Viewport.cpp | 4 +-- inc/thorvg.h | 31 +++++++------------ src/bindings/capi/thorvg_capi.h | 38 +++++------------------- src/bindings/capi/tvgCapi.cpp | 10 ++----- src/renderer/gl_engine/tvgGlRenderer.h | 2 +- src/renderer/tvgCanvas.cpp | 11 ++----- src/renderer/tvgCanvas.h | 26 +++++----------- src/renderer/wg_engine/tvgWgRenderer.cpp | 1 + src/savers/gif/tvgGifSaver.cpp | 3 +- test/testPaint.cpp | 10 ++----- tools/svg2png/svg2png.cpp | 4 +-- 33 files changed, 67 insertions(+), 147 deletions(-) diff --git a/examples/Animation.cpp b/examples/Animation.cpp index 498ec57b..09fba53f 100644 --- a/examples/Animation.cpp +++ b/examples/Animation.cpp @@ -90,5 +90,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv, 1024, 1024); + return tvgexam::main(new UserExample, argc, argv, false, 1024, 1024); } \ No newline at end of file diff --git a/examples/Blending.cpp b/examples/Blending.cpp index 55a4c99d..a5d867da 100644 --- a/examples/Blending.cpp +++ b/examples/Blending.cpp @@ -175,5 +175,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv, 1024, 1024); + return tvgexam::main(new UserExample, argc, argv, true, 1024, 1024); } \ No newline at end of file diff --git a/examples/Capi.cpp b/examples/Capi.cpp index d3da7780..263ac23f 100644 --- a/examples/Capi.cpp +++ b/examples/Capi.cpp @@ -332,9 +332,6 @@ int main(int argc, char **argv) } } - //Clear the canvas - tvg_canvas_clear(canvas, false, true); - //Update the animation if (animation) { float duration, totalFrame; @@ -345,7 +342,7 @@ int main(int argc, char **argv) //Draw the canvas tvg_canvas_update(canvas); - tvg_canvas_draw(canvas); + tvg_canvas_draw(canvas, true); tvg_canvas_sync(canvas); SDL_UpdateWindowSurface(window); diff --git a/examples/CustomTransform.cpp b/examples/CustomTransform.cpp index 1900594a..767ee109 100644 --- a/examples/CustomTransform.cpp +++ b/examples/CustomTransform.cpp @@ -37,7 +37,7 @@ struct UserExample : tvgexam::Example { if (!canvas) return false; - if (!tvgexam::verify(canvas->clear())) return false; + if (!tvgexam::verify(canvas->remove())) return false; auto progress = tvgexam::progress(elapsed, 2.0f, true); //play time 2 sec. @@ -108,5 +108,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv); + return tvgexam::main(new UserExample, argc, argv, true); } \ No newline at end of file diff --git a/examples/DirectUpdate.cpp b/examples/DirectUpdate.cpp index 53de70ca..fe9258b8 100644 --- a/examples/DirectUpdate.cpp +++ b/examples/DirectUpdate.cpp @@ -87,9 +87,6 @@ struct UserExample : tvgexam::Example { if (!canvas) return false; - //clear buffer and redraw! - if (!tvgexam::verify(canvas->clear(false))) return false; - auto progress = tvgexam::progress(elapsed, 2.0f, true); //play time 2 sec. //Reset Shape diff --git a/examples/EffectDropShadow.cpp b/examples/EffectDropShadow.cpp index f982517a..a0b4898c 100644 --- a/examples/EffectDropShadow.cpp +++ b/examples/EffectDropShadow.cpp @@ -96,8 +96,6 @@ struct UserExample : tvgexam::Example { if (!canvas) return false; - canvas->clear(false); - auto progress = tvgexam::progress(elapsed, 2.5f, true); //2.5 seconds //Clear the previously applied effects @@ -125,5 +123,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv, 800, 800, 4, true); + return tvgexam::main(new UserExample, argc, argv, false, 800, 800, 4, true); } \ No newline at end of file diff --git a/examples/EffectGaussianBlur.cpp b/examples/EffectGaussianBlur.cpp index 03c4bd15..b0356429 100644 --- a/examples/EffectGaussianBlur.cpp +++ b/examples/EffectGaussianBlur.cpp @@ -53,8 +53,6 @@ struct UserExample : tvgexam::Example { if (!canvas) return false; - canvas->clear(false); - auto progress = tvgexam::progress(elapsed, 2.5f, true); //2.5 seconds for (int i = 0; i < 3; ++i) { @@ -78,5 +76,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv, 1200, 400, 4, true); + return tvgexam::main(new UserExample, argc, argv, true, 1200, 400, 4, true); } \ No newline at end of file diff --git a/examples/Example.h b/examples/Example.h index 10f3c777..5566efbf 100644 --- a/examples/Example.h +++ b/examples/Example.h @@ -137,6 +137,7 @@ struct Window bool needResize = false; bool needDraw = false; bool initialized = false; + bool clearBuffer = false; bool print = false; Window(tvg::CanvasEngine engine, Example* example, uint32_t width, uint32_t height, uint32_t threadsCnt) @@ -170,7 +171,7 @@ struct Window bool draw() { //Draw the contents to the Canvas - if (verify(canvas->draw())) { + if (verify(canvas->draw(clearBuffer))) { verify(canvas->sync()); return true; } @@ -525,7 +526,7 @@ bool verify(tvg::Result result, string failMsg) } -int main(Example* example, int argc, char **argv, uint32_t width = 800, uint32_t height = 800, uint32_t threadsCnt = 4, bool print = false) +int main(Example* example, int argc, char **argv, bool clearBuffer = false, uint32_t width = 800, uint32_t height = 800, uint32_t threadsCnt = 4, bool print = false) { auto engine = tvg::CanvasEngine::Sw; @@ -544,6 +545,7 @@ int main(Example* example, int argc, char **argv, uint32_t width = 800, uint32_t window = unique_ptr(new WgWindow(example, width, height, threadsCnt)); } + window->clearBuffer = clearBuffer; window->print = print; if (window->ready()) { diff --git a/examples/GradientTransform.cpp b/examples/GradientTransform.cpp index e87ea020..bb6de714 100644 --- a/examples/GradientTransform.cpp +++ b/examples/GradientTransform.cpp @@ -37,7 +37,7 @@ struct UserExample : tvgexam::Example { if (!canvas) return false; - if (!tvgexam::verify(canvas->clear())) return false; + tvgexam::verify(canvas->remove()); auto progress = tvgexam::progress(elapsed, 2.0f, true); //play time 2 sec. @@ -129,5 +129,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv); + return tvgexam::main(new UserExample, argc, argv, true); } \ No newline at end of file diff --git a/examples/ImageRotation.cpp b/examples/ImageRotation.cpp index e044e708..0b07b1ab 100644 --- a/examples/ImageRotation.cpp +++ b/examples/ImageRotation.cpp @@ -54,8 +54,6 @@ struct UserExample : tvgexam::Example { if (!canvas) return false; - canvas->clear(false); - tvg::Matrix m = {1.0f, 0.0f, 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 1.0f}; //center pivoting @@ -95,5 +93,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv); + return tvgexam::main(new UserExample, argc, argv, true); } \ No newline at end of file diff --git a/examples/ImageScaleDown.cpp b/examples/ImageScaleDown.cpp index ffe7dc99..6e25275f 100644 --- a/examples/ImageScaleDown.cpp +++ b/examples/ImageScaleDown.cpp @@ -48,8 +48,6 @@ struct UserExample : tvgexam::Example { if (!canvas) return false; - canvas->clear(false); - auto progress = tvgexam::progress(elapsed, 7.0f, true); //play time 7 sec. picture->scale(1.0f - progress); @@ -67,5 +65,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv); + return tvgexam::main(new UserExample, argc, argv, true); } \ No newline at end of file diff --git a/examples/ImageScaleUp.cpp b/examples/ImageScaleUp.cpp index c6a88402..0d38d8f2 100644 --- a/examples/ImageScaleUp.cpp +++ b/examples/ImageScaleUp.cpp @@ -49,8 +49,6 @@ struct UserExample : tvgexam::Example { if (!canvas) return false; - canvas->clear(false); - auto progress = tvgexam::progress(elapsed, 7.0f, true); //play time 7 sec. picture->scale(progress * 4.0f); @@ -68,5 +66,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv); + return tvgexam::main(new UserExample, argc, argv, true); } \ No newline at end of file diff --git a/examples/Interaction.cpp b/examples/Interaction.cpp index 501e6131..0ff90710 100644 --- a/examples/Interaction.cpp +++ b/examples/Interaction.cpp @@ -145,5 +145,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv, 1024, 1024, 0); + return tvgexam::main(new UserExample, argc, argv, true, 1024, 1024, 0); } \ No newline at end of file diff --git a/examples/Lottie.cpp b/examples/Lottie.cpp index b4e64400..e3775596 100644 --- a/examples/Lottie.cpp +++ b/examples/Lottie.cpp @@ -121,5 +121,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv, 1280, 1280, 4, true); + return tvgexam::main(new UserExample, argc, argv, false, 1280, 1280, 4, true); } \ No newline at end of file diff --git a/examples/LottieExpressions.cpp b/examples/LottieExpressions.cpp index 54a04f96..f01be8d4 100644 --- a/examples/LottieExpressions.cpp +++ b/examples/LottieExpressions.cpp @@ -122,5 +122,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv, 800, 800, 0, true); + return tvgexam::main(new UserExample, argc, argv, false, 800, 800, 0, true); } \ No newline at end of file diff --git a/examples/MaskingMethods.cpp b/examples/MaskingMethods.cpp index 21296260..6eb6b5d5 100644 --- a/examples/MaskingMethods.cpp +++ b/examples/MaskingMethods.cpp @@ -566,5 +566,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv, 1500, 1024); + return tvgexam::main(new UserExample, argc, argv, false, 1500, 1024); } \ No newline at end of file diff --git a/examples/Performance.cpp b/examples/Performance.cpp index 8a4c4a33..c9aedce6 100644 --- a/examples/Performance.cpp +++ b/examples/Performance.cpp @@ -59,8 +59,6 @@ struct UserExample : tvgexam::Example auto progress = tvgexam::progress(elapsed, 2.0f, true); //play time 2 sec. - canvas->clear(false); - picture->translate(w * progress * 0.05f, h * progress * 0.05f); canvas->update(); @@ -76,5 +74,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv, 1024, 1024, 4, true); + return tvgexam::main(new UserExample, argc, argv, true, 1024, 1024, 4, true); } \ No newline at end of file diff --git a/examples/Retaining.cpp b/examples/Retaining.cpp index f3ae2ff7..5daa582a 100644 --- a/examples/Retaining.cpp +++ b/examples/Retaining.cpp @@ -106,5 +106,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv); + return tvgexam::main(new UserExample, argc, argv, true); } \ No newline at end of file diff --git a/examples/SceneTransform.cpp b/examples/SceneTransform.cpp index ef4f5460..90a89f0d 100644 --- a/examples/SceneTransform.cpp +++ b/examples/SceneTransform.cpp @@ -37,7 +37,7 @@ struct UserExample : tvgexam::Example { if (!canvas) return false; - if (!tvgexam::verify(canvas->clear())) return false; + if (!tvgexam::verify(canvas->remove())) return false; auto progress = tvgexam::progress(elapsed, 2.0f, true); //play time 2 sec. @@ -129,5 +129,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv); + return tvgexam::main(new UserExample, argc, argv, true); } \ No newline at end of file diff --git a/examples/Svg.cpp b/examples/Svg.cpp index 70435e8b..208ec5e2 100644 --- a/examples/Svg.cpp +++ b/examples/Svg.cpp @@ -114,5 +114,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv, 1280, 1280); + return tvgexam::main(new UserExample, argc, argv, false, 1280, 1280); } \ No newline at end of file diff --git a/examples/Transform.cpp b/examples/Transform.cpp index 8c4c4467..8f5ccf00 100644 --- a/examples/Transform.cpp +++ b/examples/Transform.cpp @@ -37,7 +37,7 @@ struct UserExample : tvgexam::Example { if (!canvas) return false; - if (!tvgexam::verify(canvas->clear())) return false; + if (!tvgexam::verify(canvas->remove())) return false; auto progress = tvgexam::progress(elapsed, 2.0f, true); //play time 2 sec. @@ -86,5 +86,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv); + return tvgexam::main(new UserExample, argc, argv, true); } \ No newline at end of file diff --git a/examples/Update.cpp b/examples/Update.cpp index 5556e460..d71f5f19 100644 --- a/examples/Update.cpp +++ b/examples/Update.cpp @@ -45,7 +45,7 @@ struct UserExample : tvgexam::Example { if (!canvas) return false; - if (!tvgexam::verify(canvas->clear())) return false; + if (!tvgexam::verify(canvas->remove())) return false; auto progress = tvgexam::progress(elapsed, 2.0f, true); //play time 2 sec. @@ -70,5 +70,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv); + return tvgexam::main(new UserExample, argc, argv, true); } \ No newline at end of file diff --git a/examples/Viewport.cpp b/examples/Viewport.cpp index e8fa2c45..ad583800 100644 --- a/examples/Viewport.cpp +++ b/examples/Viewport.cpp @@ -58,8 +58,6 @@ struct UserExample : tvgexam::Example { if (!canvas) return false; - canvas->clear(false); - auto progress = tvgexam::progress(elapsed, 2.0f, true); //play time 2 sec. if (!tvgexam::verify(canvas->viewport((w - VPORT_SIZE) * progress, (h - VPORT_SIZE) * progress, VPORT_SIZE, VPORT_SIZE))) return false; @@ -77,5 +75,5 @@ struct UserExample : tvgexam::Example int main(int argc, char **argv) { - return tvgexam::main(new UserExample, argc, argv, 1024, 1024, 4, true); + return tvgexam::main(new UserExample, argc, argv, true, 1024, 1024, 4, true); } \ No newline at end of file diff --git a/inc/thorvg.h b/inc/thorvg.h index dc4aa246..6156f886 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -642,7 +642,7 @@ public: * * @warning Please avoid accessing the paints during Canvas update/draw. You can access them after calling sync(). * @see Canvas::push() - * @see Canvas::clear() + * @see Canvas::remove() * * @warning This is read-only. Do not modify the list. * @note 1.0 @@ -667,25 +667,10 @@ public: * @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 Canvas::paints() - * @see Canvas::clear() + * @see Canvas::remove() */ Result push(Paint* target, Paint* at = nullptr) noexcept; - /** - * @brief Clear the internal canvas resources that used for the drawing. - * - * This API sets the total number of paints pushed into the canvas to zero. - * Depending on the value of the @p paints argument, the paints are either freed or retained. - * So if you need to update paint properties while maintaining the existing scene structure, you can set @p paints = false. - * - * @param[in] paints If @c true, the memory occupied by paints is deallocated; otherwise, the paints will be retained on the canvas. - * @param[in] buffer If @c true, the canvas target buffer is cleared with a zero value. - * - * @see Canvas::push() - * @see Canvas::paints() - */ - Result clear(bool paints = true, bool buffer = true) noexcept; - /** * @brief Removes a paint object or all paint objects from the root scene. * @@ -716,12 +701,18 @@ public: Result update(Paint* paint = nullptr) noexcept; /** - * @brief Requests the canvas to draw the Paint objects. + * @brief Requests the canvas to render Paint objects. + * + * @param[in] clear If @c true, clears the target buffer to zero before drawing. + * + * @note Clearing the buffer is unnecessary if the canvas will be fully covered + * with opaque content, which can improve performance. + * @note Drawing may be asynchronous if the thread count is greater than zero. + * To ensure drawing is complete, call sync() afterwards. * - * @note Drawing can be asynchronous if the assigned thread number is greater than zero. To guarantee the drawing is done, call sync() afterwards. * @see Canvas::sync() */ - Result draw() noexcept; + Result draw(bool clear = false) noexcept; /** * @brief Sets the drawing region in the canvas. diff --git a/src/bindings/capi/thorvg_capi.h b/src/bindings/capi/thorvg_capi.h index a167c6bd..4e9f6577 100644 --- a/src/bindings/capi/thorvg_capi.h +++ b/src/bindings/capi/thorvg_capi.h @@ -589,11 +589,6 @@ TVG_API Tvg_Result tvg_wgcanvas_set_target(Tvg_Canvas* canvas, void* device, voi * * @return Tvg_Result enumeration. * @retval TVG_RESULT_INVALID_ARGUMENT An invalid pointer to the Tvg_Canvas object is passed. -* -* @note If the paints from the canvas should not be released, the tvg_canvas_clear() with a @c free argument value set to @c false should be called. -* Please be aware that in such a case TVG is not responsible for the paints release anymore and it has to be done manually in order to avoid memory leaks. -* -* @see tvg_canvas_clear() */ TVG_API Tvg_Result tvg_canvas_destroy(Tvg_Canvas* canvas); @@ -605,7 +600,7 @@ TVG_API Tvg_Result tvg_canvas_destroy(Tvg_Canvas* canvas); * @param[in] paint The Tvg_Paint object to be drawn. * * Only the paints pushed into the canvas will be drawing targets. -* They are retained by the canvas until you call tvg_canvas_clear() or tvg_canvas_remove() +* They are retained by the canvas until you call tvg_canvas_remove() * * @return Tvg_Result return values: * @retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument. @@ -614,7 +609,6 @@ TVG_API Tvg_Result tvg_canvas_destroy(Tvg_Canvas* canvas); * @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_push_at() * @see tvg_canvas_remove() -* @see tvg_canvas_clear() */ TVG_API Tvg_Result tvg_canvas_push(Tvg_Canvas* canvas, Tvg_Paint* paint); @@ -639,29 +633,12 @@ TVG_API Tvg_Result tvg_canvas_push(Tvg_Canvas* canvas, Tvg_Paint* paint); * * @see tvg_canvas_push() * @see tvg_canvas_remove() - * @see tvg_canvas_clear() + * @see tvg_canvas_remove() * @since 1.0 */ TVG_API Tvg_Result tvg_canvas_push_at(Tvg_Canvas* canvas, Tvg_Paint* target, Tvg_Paint* at); -/*! -* @brief Sets the total number of the paints pushed into the canvas to be zero. -* Tvg_Paint objects stored in the canvas are released if @p paints is set to @c true, otherwise the memory is not deallocated and -* all paints should be released manually in order to avoid memory leaks. -* -* @param[in] canvas The Tvg_Canvas object to be cleared. -* @param[in] paints If @c true, The memory occupied by paints is deallocated; otherwise, the paints will be retained on the canvas. -* @param[in] buffer If @c true the canvas target buffer is cleared with a zero value. -* -* @return Tvg_Result enumeration. -* @retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Canvas pointer. -* -* @see tvg_canvas_destroy() -*/ -TVG_API Tvg_Result tvg_canvas_clear(Tvg_Canvas* canvas, bool paints, bool buffer); - - /** * @brief Removes a paint object from the root scene. * @@ -718,14 +695,18 @@ TVG_API Tvg_Result tvg_canvas_update_paint(Tvg_Canvas* canvas, Tvg_Paint* paint) * All paints from the given canvas will be rasterized to the buffer. * * @param[in] canvas The Tvg_Canvas object containing elements to be drawn. +* @param[in] clear If @c true, clears the target buffer to zero before drawing. * * @return Tvg_Result enumeration. * @retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Canvas pointer. * -* @note Drawing can be asynchronous based on the assigned thread number. To guarantee the drawing is done, call tvg_canvas_sync() afterwards. +* @note Clearing the buffer is unnecessary if the canvas will be fully covered +* with opaque content, which can improve performance. +* @note Drawing may be asynchronous if the thread count is greater than zero. +* To ensure drawing is complete, call tvg_canvas_sync() afterwards. * @see tvg_canvas_sync() */ -TVG_API Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas); +TVG_API Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas, bool clear); /*! @@ -787,10 +768,7 @@ TVG_API Tvg_Result tvg_canvas_set_viewport(Tvg_Canvas* canvas, int32_t x, int32_ * @return Tvg_Result enumeration. * @retval TVG_RESULT_INVALID_ARGUMENT An invalid Tvg_Paint pointer. * -* @warning If this function is used, tvg_canvas_clear() with the @c free argument value set to @c false should be used in order to avoid unexpected behaviours. -* * @see tvg_canvas_remove() -* @see tvg_canvas_clear() */ TVG_API Tvg_Result tvg_paint_del(Tvg_Paint* paint); diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp index daeccbe5..8ba203cc 100644 --- a/src/bindings/capi/tvgCapi.cpp +++ b/src/bindings/capi/tvgCapi.cpp @@ -130,12 +130,6 @@ TVG_API Tvg_Result tvg_canvas_push_at(Tvg_Canvas* canvas, Tvg_Paint* paint, Tvg_ } -TVG_API Tvg_Result tvg_canvas_clear(Tvg_Canvas* canvas, bool paints, bool buffer) -{ - if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; - return (Tvg_Result) reinterpret_cast(canvas)->clear(paints, buffer); -} - TVG_API Tvg_Result tvg_canvas_remove(Tvg_Canvas* canvas, Tvg_Paint* paint) { if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; @@ -157,10 +151,10 @@ TVG_API Tvg_Result tvg_canvas_update_paint(Tvg_Canvas* canvas, Tvg_Paint* paint) } -TVG_API Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas) +TVG_API Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas, bool clear) { if (!canvas) return TVG_RESULT_INVALID_ARGUMENT; - return (Tvg_Result) reinterpret_cast(canvas)->draw(); + return (Tvg_Result) reinterpret_cast(canvas)->draw(clear); } diff --git a/src/renderer/gl_engine/tvgGlRenderer.h b/src/renderer/gl_engine/tvgGlRenderer.h index 854646f5..b157b2e0 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.h +++ b/src/renderer/gl_engine/tvgGlRenderer.h @@ -133,7 +133,7 @@ private: Key key; } mDisposed; - bool mClearBuffer = true; + bool mClearBuffer = true; //FIXME: clear buffer should be optional (default is false) BlendMethod mBlendMethod = BlendMethod::Normal; }; diff --git a/src/renderer/tvgCanvas.cpp b/src/renderer/tvgCanvas.cpp index 27ae181d..eb0d38ac 100644 --- a/src/renderer/tvgCanvas.cpp +++ b/src/renderer/tvgCanvas.cpp @@ -49,16 +49,10 @@ Result Canvas::push(Paint* target, Paint* at) noexcept } -Result Canvas::clear(bool paints, bool buffer) noexcept -{ - return pImpl->clear(paints, buffer); -} - - -Result Canvas::draw() noexcept +Result Canvas::draw(bool clear) noexcept { TVGLOG("RENDERER", "Draw S. -------------------------------- Canvas(%p)", this); - auto ret = pImpl->draw(); + auto ret = pImpl->draw(clear); TVGLOG("RENDERER", "Draw E. -------------------------------- Canvas(%p)", this); return ret; @@ -68,7 +62,6 @@ Result Canvas::draw() noexcept Result Canvas::update(Paint* paint) noexcept { TVGLOG("RENDERER", "Update S. ------------------------------ Canvas(%p)", this); - if (pImpl->scene->paints().empty() || pImpl->status == Status::Drawing) return Result::InsufficientCondition; auto ret = pImpl->update(paint, false); TVGLOG("RENDERER", "Update E. ------------------------------ Canvas(%p)", this); diff --git a/src/renderer/tvgCanvas.h b/src/renderer/tvgCanvas.h index c521cf26..f609df4c 100644 --- a/src/renderer/tvgCanvas.h +++ b/src/renderer/tvgCanvas.h @@ -63,29 +63,12 @@ struct Canvas::Impl return update(target, true); } - Result clear(bool paints, bool buffer) - { - auto ret = Result::Success; - - if (status == Status::Drawing) return Result::InsufficientCondition; - - //Clear render target - if (buffer && !renderer->clear()) { - ret = Result::InsufficientCondition; - } - - if (paints) scene->remove(); - - return ret; - } - Result remove(Paint* paint) { if (status == Status::Drawing) return Result::InsufficientCondition; return scene->remove(paint); } - Result update(Paint* paint, bool force) { Array clips; @@ -101,9 +84,13 @@ struct Canvas::Impl return Result::Success; } - Result draw() + Result draw(bool clear) { - if (status == Status::Drawing || scene->paints().empty()) return Result::InsufficientCondition; + if (status == Status::Drawing) return Result::InsufficientCondition; + + if (clear && !renderer->clear()) return Result::InsufficientCondition; + + if (scene->paints().empty()) return Result::InsufficientCondition; if (status == Status::Damaged) update(nullptr, false); @@ -112,6 +99,7 @@ struct Canvas::Impl if (!PP(scene)->render(renderer) || !renderer->postRender()) return Result::InsufficientCondition; status = Status::Drawing; + return Result::Success; } diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index 007ebe26..58da66f9 100755 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -239,6 +239,7 @@ const RenderSurface* WgRenderer::mainSurface() bool WgRenderer::clear() { + //TODO: clear the current target buffer only if clear() is called return true; } diff --git a/src/savers/gif/tvgGifSaver.cpp b/src/savers/gif/tvgGifSaver.cpp index ab427069..f2c0bffb 100644 --- a/src/savers/gif/tvgGifSaver.cpp +++ b/src/savers/gif/tvgGifSaver.cpp @@ -65,11 +65,10 @@ void GifSaver::run(unsigned tid) auto duration = animation->duration(); for (auto p = 0.0f; p < duration; p += delay) { - canvas->clear(false); auto frameNo = animation->totalFrame() * (p / duration); animation->frame(frameNo); canvas->update(); - if (canvas->draw() == tvg::Result::Success) { + if (canvas->draw(true) == tvg::Result::Success) { canvas->sync(); } if (!gifWriteFrame(&writer, reinterpret_cast(buffer), w, h, uint32_t(delay * 100.0f), transparent)) { diff --git a/test/testPaint.cpp b/test/testPaint.cpp index 20574893..fc24acd9 100644 --- a/test/testPaint.cpp +++ b/test/testPaint.cpp @@ -308,18 +308,15 @@ TEST_CASE("Refernce Count", "[tvgPaint]") REQUIRE(shape->ref() == 1); canvas->push(shape); REQUIRE(shape->refCnt() == 2); - canvas->clear(); - REQUIRE(shape->refCnt() == 1); - REQUIRE(shape->unref() == 0); + REQUIRE(shape->unref() == 1); shape = Shape::gen(); REQUIRE(shape->ref() == 1); auto scene = Scene::gen(); scene->push(shape); canvas->push(scene); - canvas->clear(); - REQUIRE(shape->refCnt() == 1); - REQUIRE(shape->unref() == 0); + REQUIRE(shape->refCnt() == 2); + REQUIRE(shape->unref() == 1); shape = Shape::gen(); REQUIRE(shape->ref() == 1); @@ -327,7 +324,6 @@ TEST_CASE("Refernce Count", "[tvgPaint]") scene->push(shape); scene->remove(); canvas->push(scene); - canvas->clear(); REQUIRE(shape->unref() == 0); Initializer::term(); diff --git a/tools/svg2png/svg2png.cpp b/tools/svg2png/svg2png.cpp index f75a2ff5..42c48bf4 100644 --- a/tools/svg2png/svg2png.cpp +++ b/tools/svg2png/svg2png.cpp @@ -131,8 +131,6 @@ public: return 1; } - canvas->clear(); - //Background color if needed if (bgColor != 0xffffffff) { uint8_t r = (uint8_t)((bgColor & 0xff0000) >> 16); @@ -148,7 +146,7 @@ public: //Drawing canvas->push(picture); - canvas->draw(); + canvas->draw(true); canvas->sync(); //Build Png