From 9cb8ef26a51701306b865c8134e507f992c9dfe8 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 17 Jun 2025 16:58:51 +0900 Subject: [PATCH] engines: manage the update with the precise update flags this also fixes one broken clipping issue. issue: https://github.com/thorvg/thorvg/issues/3448 --- src/renderer/gl_engine/tvgGlRenderer.cpp | 15 +++++------- src/renderer/sw_engine/tvgSwRenderer.cpp | 29 +++++++++++++----------- src/renderer/wg_engine/tvgWgRenderer.cpp | 10 +++++--- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index ab2e8918..a5b6350b 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -1403,7 +1403,7 @@ RenderData GlRenderer::prepare(RenderSurface* image, RenderData data, const Matr sdata->geometry.tesselate(image, flags); - if (!clips.empty()) { + if (flags & RenderUpdateFlag::Clip) { sdata->clips.clear(); sdata->clips.push(clips); } @@ -1414,6 +1414,8 @@ RenderData GlRenderer::prepare(RenderSurface* image, RenderData data, const Matr RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) { + if (flags == RenderUpdateFlag::None) return data; + // If prepare for clip, only path is meaningful. if (clipper) flags = RenderUpdateFlag::Path; @@ -1427,7 +1429,6 @@ RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const sdata->viewWd = static_cast(surface.w); sdata->viewHt = static_cast(surface.h); sdata->updateFlag = RenderUpdateFlag::None; - sdata->geometry = GlGeometry(); sdata->opacity = opacity; @@ -1435,10 +1436,7 @@ RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const auto alphaF = rshape.color.a; auto alphaS = rshape.stroke ? rshape.stroke->color.a : 0; - if ( ((flags & RenderUpdateFlag::Gradient) == 0) && - ((flags & RenderUpdateFlag::Color) && alphaF == 0) && - ((flags & RenderUpdateFlag::Stroke) && alphaS == 0) ) - { + if ((flags & RenderUpdateFlag::Gradient) == 0 && ((flags & RenderUpdateFlag::Color) && alphaF == 0) && ((flags & RenderUpdateFlag::Stroke) && alphaS == 0)) { return sdata; } @@ -1456,12 +1454,11 @@ RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const sdata->geometry.matrix = transform; sdata->geometry.viewport = vport; - if (sdata->updateFlag & (RenderUpdateFlag::Color | RenderUpdateFlag::Stroke | RenderUpdateFlag::Gradient | RenderUpdateFlag::GradientStroke | RenderUpdateFlag::Transform | RenderUpdateFlag::Path)) - { + if (sdata->updateFlag & (RenderUpdateFlag::Color | RenderUpdateFlag::Stroke | RenderUpdateFlag::Gradient | RenderUpdateFlag::GradientStroke | RenderUpdateFlag::Transform | RenderUpdateFlag::Path)) { if (!sdata->geometry.tesselate(rshape, sdata->updateFlag)) return sdata; } - if (!clipper && !clips.empty()) { + if (flags & RenderUpdateFlag::Clip) { sdata->clips.clear(); sdata->clips.push(clips); } diff --git a/src/renderer/sw_engine/tvgSwRenderer.cpp b/src/renderer/sw_engine/tvgSwRenderer.cpp index b7429b7a..3be52319 100644 --- a/src/renderer/sw_engine/tvgSwRenderer.cpp +++ b/src/renderer/sw_engine/tvgSwRenderer.cpp @@ -695,9 +695,7 @@ void SwRenderer::dispose(RenderData data) void* SwRenderer::prepareCommon(SwTask* task, const Matrix& transform, const Array& clips, uint8_t opacity, RenderUpdateFlag flags) { - if (!surface) return task; - if (flags == RenderUpdateFlag::None) return task; - if ((transform.e11 == 0.0f && transform.e12 == 0.0f) || (transform.e21 == 0.0f && transform.e22 == 0.0f)) return task; //zero size? + if (!surface || (transform.e11 == 0.0f && transform.e12 == 0.0f) || (transform.e21 == 0.0f && transform.e22 == 0.0f)) return task; //invalid task->surface = surface; task->mpool = mpool; @@ -715,11 +713,13 @@ void* SwRenderer::prepareCommon(SwTask* task, const Matrix& transform, const Arr //TODO: Failed threading them. It would be better if it's possible. //See: https://github.com/thorvg/thorvg/issues/1409 //Guarantee composition targets get ready. - ARRAY_FOREACH(p, clips) { - static_cast(*p)->done(); + if (flags & RenderUpdateFlag::Clip) { + ARRAY_FOREACH(p, clips) { + static_cast(*p)->done(); + } } - TaskScheduler::request(task); + if (flags) TaskScheduler::request(task); return task; } @@ -729,10 +729,11 @@ RenderData SwRenderer::prepare(RenderSurface* surface, RenderData data, const Ma { //prepare task auto task = static_cast(data); - if (!task) task = new SwImageTask; - else task->done(); - - task->source = surface; + if (task) task->done(); + else { + task = new SwImageTask; + task->source = surface; + } return prepareCommon(task, transform, clips, opacity, flags); } @@ -742,10 +743,12 @@ RenderData SwRenderer::prepare(const RenderShape& rshape, RenderData data, const { //prepare task auto task = static_cast(data); - if (!task) task = new SwShapeTask; - else task->done(); + if (task) task->done(); + else { + task = new SwShapeTask; + task->rshape = &rshape; + } - task->rshape = &rshape; task->clipper = clipper; return prepareCommon(task, transform, clips, opacity, flags); diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index d1cb1a7c..6f8c937e 100644 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -131,10 +131,12 @@ bool WgRenderer::surfaceConfigure(WGPUSurface surface, WgContext& context, uint3 RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) { + if (flags == RenderUpdateFlag::None) return data; + auto renderDataShape = data ? (WgRenderDataShape*)data : mRenderDataShapePool.allocate(mContext); // update geometry - if ((!data) || (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke))) { + if (!data || (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke))) { renderDataShape->updateMeshes(rshape, transform, mBufferPool.pool); } @@ -154,7 +156,7 @@ RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const else if (flags & RenderUpdateFlag::Stroke) renderDataShape->renderSettingsStroke.update(mContext, rshape.stroke->color); } - renderDataShape->updateClips(clips); + if (flags & RenderUpdateFlag::Clip) renderDataShape->updateClips(clips); return renderDataShape; } @@ -162,6 +164,8 @@ RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const RenderData WgRenderer::prepare(RenderSurface* surface, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) { + if (flags == RenderUpdateFlag::None) return data; + auto renderDataPicture = data ? (WgRenderDataPicture*)data : mRenderDataPicturePool.allocate(mContext); // update paint settings @@ -175,7 +179,7 @@ RenderData WgRenderer::prepare(RenderSurface* surface, RenderData data, const Ma renderDataPicture->updateSurface(mContext, surface); } - renderDataPicture->updateClips(clips); + if (flags & RenderUpdateFlag::Clip) renderDataPicture->updateClips(clips); return renderDataPicture; }