mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-19 06:21:45 +00:00
api: revise the canvas update() API
Removed the paint parameter previously used to forcibly update a single paint. This behavior was unsafe in ThorVG, as a single paint object may be connected to others through the scene graph. Now, the canvas engine is responsible for properly updating all damaged paints as needed, allowing the user to simply call update() in any case. API Modifications: C++ API: * Result Canvas::update(Paint* paint) -> Result Canvas::update() CAPI: - tvg_canvas_update_paint() Issue: https://github.com/thorvg/thorvg/issues/3116
This commit is contained in:
parent
f606d58dfb
commit
39b0f87cb3
9 changed files with 17 additions and 51 deletions
|
@ -54,7 +54,7 @@ struct UserExample : tvgexam::Example
|
|||
|
||||
picture->scale((1.0f - progress) * 1.5f);
|
||||
|
||||
canvas->update(picture);
|
||||
canvas->update();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
12
inc/thorvg.h
12
inc/thorvg.h
|
@ -733,16 +733,12 @@ public:
|
|||
Result remove(Paint* paint = nullptr) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Request the canvas to update the paint objects.
|
||||
* @brief Requests the canvas to update the paint for up-to-date render preparation.
|
||||
*
|
||||
* If a @c nullptr is passed all paint objects retained by the Canvas are updated,
|
||||
* otherwise only the paint to which the given @p paint points.
|
||||
*
|
||||
* @param[in] paint A pointer to the Paint object or @c nullptr.
|
||||
*
|
||||
* @note The Update behavior can be asynchronous if the assigned thread number is greater than zero.
|
||||
* @note Only modified paint instances will undergo the internal update process.
|
||||
* @note The update operation may be asynchronous if the assigned thread count is greater than zero.
|
||||
*/
|
||||
Result update(Paint* paint = nullptr) noexcept;
|
||||
Result update() noexcept;
|
||||
|
||||
/**
|
||||
* @brief Requests the canvas to render Paint objects.
|
||||
|
|
|
@ -630,23 +630,6 @@ TVG_API Tvg_Result tvg_canvas_remove(Tvg_Canvas* canvas, Tvg_Paint* paint);
|
|||
TVG_API Tvg_Result tvg_canvas_update(Tvg_Canvas* canvas);
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Updates the given Tvg_Paint object from the canvas before the rendering.
|
||||
*
|
||||
* If a client application using the TVG library does not update the entire canvas with tvg_canvas_update() in the frame
|
||||
* rendering process, Tvg_Paint objects previously added to the canvas should be updated manually with this function.
|
||||
*
|
||||
* @param[in] canvas The Tvg_Canvas object to which the @p paint belongs.
|
||||
* @param[in] paint The Tvg_Paint object to be updated.
|
||||
*
|
||||
* @return Tvg_Result enumeration.
|
||||
* @retval TVG_RESULT_INVALID_ARGUMENT In case a @c nullptr is passed as the argument.
|
||||
*
|
||||
* @see tvg_canvas_update()
|
||||
*/
|
||||
TVG_API Tvg_Result tvg_canvas_update_paint(Tvg_Canvas* canvas, Tvg_Paint* paint);
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Requests the canvas to draw the Tvg_Paint objects.
|
||||
*
|
||||
|
|
|
@ -134,14 +134,7 @@ TVG_API Tvg_Result tvg_canvas_remove(Tvg_Canvas* canvas, Tvg_Paint* paint)
|
|||
|
||||
TVG_API Tvg_Result tvg_canvas_update(Tvg_Canvas* canvas)
|
||||
{
|
||||
if (canvas) return (Tvg_Result) reinterpret_cast<Canvas*>(canvas)->update(nullptr);
|
||||
return TVG_RESULT_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
|
||||
TVG_API Tvg_Result tvg_canvas_update_paint(Tvg_Canvas* canvas, Tvg_Paint* paint)
|
||||
{
|
||||
if (canvas && paint) return (Tvg_Result) reinterpret_cast<Canvas*>(canvas)->update((Paint*) paint);
|
||||
if (canvas) return (Tvg_Result) reinterpret_cast<Canvas*>(canvas)->update();
|
||||
return TVG_RESULT_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,11 +55,11 @@ Result Canvas::draw(bool clear) noexcept
|
|||
}
|
||||
|
||||
|
||||
Result Canvas::update(Paint* paint) noexcept
|
||||
Result Canvas::update() 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);
|
||||
auto ret = pImpl->update(false);
|
||||
TVGLOG("RENDERER", "Update E. ------------------------------ Canvas(%p)", this);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -56,7 +56,7 @@ struct Canvas::Impl
|
|||
auto ret = scene->push(target, at);
|
||||
if (ret != Result::Success) return ret;
|
||||
|
||||
return update(target, true);
|
||||
return update(true);
|
||||
}
|
||||
|
||||
Result remove(Paint* paint)
|
||||
|
@ -65,18 +65,16 @@ struct Canvas::Impl
|
|||
return scene->remove(paint);
|
||||
}
|
||||
|
||||
Result update(Paint* paint, bool force)
|
||||
Result update(bool force)
|
||||
{
|
||||
Array<RenderData> clips;
|
||||
auto flag = RenderUpdateFlag::None;
|
||||
if (status == Status::Damaged || force) flag = RenderUpdateFlag::All;
|
||||
|
||||
auto m = tvg::identity();
|
||||
|
||||
if (!renderer->preUpdate()) return Result::InsufficientCondition;
|
||||
|
||||
if (paint) PAINT(paint)->update(renderer, m, clips, 255, flag);
|
||||
else PAINT(scene)->update(renderer, m, clips, 255, flag);
|
||||
auto m = tvg::identity();
|
||||
PAINT(scene)->update(renderer, m, clips, 255, flag);
|
||||
|
||||
if (!renderer->postUpdate()) return Result::InsufficientCondition;
|
||||
|
||||
|
@ -87,13 +85,9 @@ struct Canvas::Impl
|
|||
Result draw(bool clear)
|
||||
{
|
||||
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);
|
||||
|
||||
if (status == Status::Damaged) update(false);
|
||||
if (!renderer->preRender()) return Result::InsufficientCondition;
|
||||
|
||||
if (!PAINT(scene)->render(renderer) || !renderer->postRender()) return Result::InsufficientCondition;
|
||||
|
|
|
@ -116,7 +116,7 @@ struct PictureImpl : Picture
|
|||
return Result::Success;
|
||||
}
|
||||
|
||||
Result bounds(Point* pt4, Matrix& m, TVG_UNUSED bool obb, TVG_UNUSED bool stroking)
|
||||
Result bounds(Point* pt4, Matrix& m, TVG_UNUSED bool obb, TVG_UNUSED bool stroking) const
|
||||
{
|
||||
pt4[0] = Point{0.0f, 0.0f} * m;
|
||||
pt4[1] = Point{w, 0.0f} * m;
|
||||
|
|
|
@ -116,7 +116,7 @@ struct SceneImpl : Scene
|
|||
opacity = 255;
|
||||
}
|
||||
for (auto paint : paints) {
|
||||
paint->pImpl->update(renderer, transform, clips, opacity, flag, false);
|
||||
PAINT(paint)->update(renderer, transform, clips, opacity, flag, false);
|
||||
}
|
||||
|
||||
if (effects) {
|
||||
|
|
|
@ -141,7 +141,7 @@ TEST_CASE("Bounding Box", "[tvgPaint]")
|
|||
REQUIRE(w == 20.0f);
|
||||
REQUIRE(h == 100.0f);
|
||||
|
||||
REQUIRE(canvas->update(shape) == Result::Success);
|
||||
REQUIRE(canvas->update() == Result::Success);
|
||||
Point pts[4];
|
||||
REQUIRE(shape->bounds(pts) == Result::Success);
|
||||
REQUIRE(pts[0].x == 100.0f);
|
||||
|
@ -165,7 +165,7 @@ TEST_CASE("Bounding Box", "[tvgPaint]")
|
|||
REQUIRE(w == 20.0f);
|
||||
REQUIRE(h == 200.0f);
|
||||
|
||||
REQUIRE(canvas->update(shape) == Result::Success);
|
||||
REQUIRE(canvas->update() == Result::Success);
|
||||
REQUIRE(shape->bounds(pts) == Result::Success);
|
||||
REQUIRE(pts[0].x == 0.0f);
|
||||
REQUIRE(pts[3].x == 0.0f);
|
||||
|
|
Loading…
Add table
Reference in a new issue