From 4b01c0ef529a98ede41b07e497050110bd142dd7 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Sun, 23 Jun 2024 18:40:29 +0900 Subject: [PATCH] renderer/canvas: ++exceptional handling. do not allow change the target if the condition is not satisfied. --- inc/thorvg.h | 14 +++++++++++--- src/bindings/capi/thorvg_capi.h | 1 + src/renderer/tvgCanvas.h | 4 ++-- src/renderer/tvgGlCanvas.cpp | 2 ++ src/renderer/tvgSwCanvas.cpp | 2 ++ src/renderer/tvgWgCanvas.cpp | 6 +++--- 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/inc/thorvg.h b/inc/thorvg.h index b3f2e165..9a5ad2f9 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -1734,11 +1734,13 @@ public: * @retval Result::Success When succeed. * @retval Result::MemoryCorruption When casting in the internal function implementation failed. * @retval Result::InvalidArguments In case no valid pointer is provided or the width, or the height or the stride is zero. + * @retval Result::InsufficientCondition if the canvas is performing rendering. Please ensure the canvas is synced. * @retval Result::NonSupport In case the software engine is not supported. * * @warning Do not access @p buffer during Canvas::push() - Canvas::sync(). It should not be accessed while the engine is writing on it. * * @see Canvas::viewport() + * @see Canvas::sync() */ Result target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Colorspace cs) noexcept; @@ -1801,10 +1803,13 @@ public: * @param[in] w The width (in pixels) of the raster image. * @param[in] h The height (in pixels) of the raster image. * - * @warning This API is experimental and not officially supported. It may be modified or removed in future versions. - * @warning Drawing on the main surface is currently not permitted. If the identifier (@p id) is set to @c 0, the operation will be aborted. + * @retval Result::Success When succeed. + * @retval Result::MemoryCorruption When casting in the internal function implementation failed. + * @retval Result::InsufficientCondition if the canvas is performing rendering. Please ensure the canvas is synced. + * @retval Result::NonSupport In case the gl engine is not supported. * * @see Canvas::viewport() + * @see Canvas::sync() * * @note Currently, this only allows the GL_RGBA8 color space format. * @note Experimental API @@ -1844,10 +1849,13 @@ public: * @param[in] instance WGPUInstance, context for all other wgpu objects. * @param[in] surace WGPUSurface, handle to a presentable surface. * - * @warning Please do not use it, this API is not official one. It could be modified in the next version. + * @retval Result::InsufficientCondition if the canvas is performing rendering. Please ensure the canvas is synced. + * @retval Result::NonSupport In case the wg engine is not supported. * * @note Experimental API + * * @see Canvas::viewport() + * @see Canvas::sync() */ Result target(void* instance, void* surface, uint32_t w, uint32_t h) noexcept; diff --git a/src/bindings/capi/thorvg_capi.h b/src/bindings/capi/thorvg_capi.h index f1b40eca..30919ff4 100644 --- a/src/bindings/capi/thorvg_capi.h +++ b/src/bindings/capi/thorvg_capi.h @@ -452,6 +452,7 @@ TVG_API Tvg_Canvas* tvg_swcanvas_create(void); * \retval TVG_RESULT_SUCCESS Succeed. * \retval TVG_RESULT_MEMORY_CORRUPTION Casting in the internal function implementation failed. * \retval TVG_RESULT_INVALID_ARGUMENTS An invalid canvas or buffer pointer passed or one of the @p stride, @p w or @p h being zero. +* \retval TVG_RESULT_INSUFFICIENT_CONDITION if the canvas is performing rendering. Please ensure the canvas is synced. * \retval TVG_RESULT_NOT_SUPPORTED The software engine is not supported. * * \warning Do not access @p buffer during tvg_canvas_draw() - tvg_canvas_sync(). It should not be accessed while the engine is writing on it. diff --git a/src/renderer/tvgCanvas.h b/src/renderer/tvgCanvas.h index 8c146f82..c9fbebe2 100644 --- a/src/renderer/tvgCanvas.h +++ b/src/renderer/tvgCanvas.h @@ -26,10 +26,10 @@ #include "tvgPaint.h" +enum Status : uint8_t {Synced = 0, Updating, Drawing}; + struct Canvas::Impl { - enum Status : uint8_t {Synced = 0, Updating, Drawing}; - list paints; RenderMethod* renderer; RenderRegion vport = {0, 0, INT32_MAX, INT32_MAX}; diff --git a/src/renderer/tvgGlCanvas.cpp b/src/renderer/tvgGlCanvas.cpp index 64b68577..fdf28d53 100644 --- a/src/renderer/tvgGlCanvas.cpp +++ b/src/renderer/tvgGlCanvas.cpp @@ -62,6 +62,8 @@ GlCanvas::~GlCanvas() Result GlCanvas::target(int32_t id, uint32_t w, uint32_t h) noexcept { #ifdef THORVG_GL_RASTER_SUPPORT + if (Canvas::pImpl->status != Status::Synced) return Result::InsufficientCondition; + //We know renderer type, avoid dynamic_cast for performance. auto renderer = static_cast(Canvas::pImpl->renderer); if (!renderer) return Result::MemoryCorruption; diff --git a/src/renderer/tvgSwCanvas.cpp b/src/renderer/tvgSwCanvas.cpp index 32c608f8..7a95167b 100644 --- a/src/renderer/tvgSwCanvas.cpp +++ b/src/renderer/tvgSwCanvas.cpp @@ -82,6 +82,8 @@ Result SwCanvas::mempool(MempoolPolicy policy) noexcept Result SwCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Colorspace cs) noexcept { #ifdef THORVG_SW_RASTER_SUPPORT + if (Canvas::pImpl->status != Status::Synced) return Result::InsufficientCondition; + //We know renderer type, avoid dynamic_cast for performance. auto renderer = static_cast(Canvas::pImpl->renderer); if (!renderer) return Result::MemoryCorruption; diff --git a/src/renderer/tvgWgCanvas.cpp b/src/renderer/tvgWgCanvas.cpp index 7e7a6ceb..fbc6fd30 100644 --- a/src/renderer/tvgWgCanvas.cpp +++ b/src/renderer/tvgWgCanvas.cpp @@ -57,9 +57,9 @@ WgCanvas::~WgCanvas() Result WgCanvas::target(void* instance, void* surface, uint32_t w, uint32_t h) noexcept { #ifdef THORVG_WG_RASTER_SUPPORT - if (!instance) return Result::InvalidArguments; - if (!surface) return Result::InvalidArguments; - if ((w == 0) || (h == 0)) return Result::InvalidArguments; + if (Canvas::pImpl->status != Status::Synced) return Result::InsufficientCondition; + + if (!instance || !surface || (w == 0) || (h == 0)) return Result::InvalidArguments; //We know renderer type, avoid dynamic_cast for performance. auto renderer = static_cast(Canvas::pImpl->renderer);