diff --git a/src/renderer/tvgCanvas.h b/src/renderer/tvgCanvas.h index 5eca8fa9..54442408 100644 --- a/src/renderer/tvgCanvas.h +++ b/src/renderer/tvgCanvas.h @@ -26,7 +26,7 @@ #include "tvgPaint.h" -enum Status : uint8_t {Synced = 0, Updating, Drawing}; +enum Status : uint8_t {Synced = 0, Updating, Drawing, Damanged}; struct Canvas::Impl { @@ -35,8 +35,6 @@ struct Canvas::Impl RenderRegion vport = {0, 0, INT32_MAX, INT32_MAX}; Status status = Status::Synced; - bool refresh = false; //if all paints should be updated by force. - Impl(RenderMethod* pRenderer) : renderer(pRenderer) { renderer->ref(); @@ -87,18 +85,13 @@ struct Canvas::Impl return Result::Success; } - void needRefresh() - { - refresh = true; - } - Result update(Paint* paint, bool force) { if (paints.empty() || status == Status::Drawing) return Result::InsufficientCondition; Array clips; auto flag = RenderUpdateFlag::None; - if (refresh || force) flag = RenderUpdateFlag::All; + if (status == Status::Damanged || force) flag = RenderUpdateFlag::All; if (paint) { paint->pImpl->update(renderer, nullptr, clips, 255, flag); @@ -106,7 +99,6 @@ struct Canvas::Impl for (auto paint : paints) { paint->pImpl->update(renderer, nullptr, clips, 255, flag); } - refresh = false; } status = Status::Updating; return Result::Success; @@ -114,6 +106,7 @@ struct Canvas::Impl Result draw() { + if (status == Status::Damanged) update(nullptr, false); if (status == Status::Drawing || paints.empty() || !renderer->preRender()) return Result::InsufficientCondition; bool rendered = false; @@ -129,7 +122,7 @@ struct Canvas::Impl Result sync() { - if (status == Status::Synced) return Result::InsufficientCondition; + if (status == Status::Synced || status == Status::Damanged) return Result::InsufficientCondition; if (renderer->sync()) { status = Status::Synced; @@ -141,7 +134,8 @@ struct Canvas::Impl Result viewport(int32_t x, int32_t y, int32_t w, int32_t h) { - if (status != Status::Synced) return Result::InsufficientCondition; + if (status != Status::Damanged && status != Status::Synced) return Result::InsufficientCondition; + RenderRegion val = {x, y, w, h}; //intersect if the target buffer is already set. auto surface = renderer->mainSurface(); @@ -151,7 +145,7 @@ struct Canvas::Impl if (vport == val) return Result::Success; renderer->viewport(val); vport = val; - needRefresh(); + status = Status::Damanged; return Result::Success; } }; diff --git a/src/renderer/tvgGlCanvas.cpp b/src/renderer/tvgGlCanvas.cpp index fdf28d53..82666b7a 100644 --- a/src/renderer/tvgGlCanvas.cpp +++ b/src/renderer/tvgGlCanvas.cpp @@ -62,7 +62,9 @@ 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; + if (Canvas::pImpl->status != Status::Damanged && Canvas::pImpl->status != Status::Synced) { + return Result::InsufficientCondition; + } //We know renderer type, avoid dynamic_cast for performance. auto renderer = static_cast(Canvas::pImpl->renderer); @@ -73,7 +75,7 @@ Result GlCanvas::target(int32_t id, uint32_t w, uint32_t h) noexcept renderer->viewport(Canvas::pImpl->vport); //Paints must be updated again with this new target. - Canvas::pImpl->needRefresh(); + Canvas::pImpl->status = Status::Damanged; return Result::Success; #endif diff --git a/src/renderer/tvgSwCanvas.cpp b/src/renderer/tvgSwCanvas.cpp index 7a95167b..d762492f 100644 --- a/src/renderer/tvgSwCanvas.cpp +++ b/src/renderer/tvgSwCanvas.cpp @@ -82,7 +82,9 @@ 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; + if (Canvas::pImpl->status != Status::Damanged && Canvas::pImpl->status != Status::Synced) { + return Result::InsufficientCondition; + } //We know renderer type, avoid dynamic_cast for performance. auto renderer = static_cast(Canvas::pImpl->renderer); @@ -92,12 +94,12 @@ Result SwCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t Canvas::pImpl->vport = {0, 0, (int32_t)w, (int32_t)h}; renderer->viewport(Canvas::pImpl->vport); - //Paints must be updated again with this new target. - Canvas::pImpl->needRefresh(); - //FIXME: The value must be associated with an individual canvas instance. ImageLoader::cs = static_cast(cs); + //Paints must be updated again with this new target. + Canvas::pImpl->status = Status::Damanged; + return Result::Success; #endif return Result::NonSupport; diff --git a/src/renderer/tvgWgCanvas.cpp b/src/renderer/tvgWgCanvas.cpp index fbc6fd30..067e35b1 100644 --- a/src/renderer/tvgWgCanvas.cpp +++ b/src/renderer/tvgWgCanvas.cpp @@ -57,7 +57,9 @@ WgCanvas::~WgCanvas() Result WgCanvas::target(void* instance, void* surface, uint32_t w, uint32_t h) noexcept { #ifdef THORVG_WG_RASTER_SUPPORT - if (Canvas::pImpl->status != Status::Synced) return Result::InsufficientCondition; + if (Canvas::pImpl->status != Status::Damanged && Canvas::pImpl->status != Status::Synced) { + return Result::InsufficientCondition; + } if (!instance || !surface || (w == 0) || (h == 0)) return Result::InvalidArguments; @@ -70,7 +72,7 @@ Result WgCanvas::target(void* instance, void* surface, uint32_t w, uint32_t h) n renderer->viewport(Canvas::pImpl->vport); //Paints must be updated again with this new target. - Canvas::pImpl->needRefresh(); + Canvas::pImpl->status = Status::Damanged; return Result::Success; #endif