From 3889ffe8ecec3ccf7f2173de7460543bfd73c8c5 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 | 31 ++++++++++++++++-------- src/renderer/wg_engine/tvgWgRenderer.cpp | 12 +++++---- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index 1f4adfdf..eb91688e 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -1329,7 +1329,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); } @@ -1340,6 +1340,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; @@ -1353,7 +1355,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 = make_unique(); sdata->opacity = opacity; @@ -1362,10 +1363,7 @@ RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const rshape.fillColor(nullptr, nullptr, nullptr, &alphaF); rshape.strokeColor(nullptr, nullptr, nullptr, &alphaS); - 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; } @@ -1383,12 +1381,11 @@ RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const sdata->geometry->updateTransform(transform); sdata->geometry->setViewport(mViewport); - 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 2e8f3c84..feb8687d 100644 --- a/src/renderer/sw_engine/tvgSwRenderer.cpp +++ b/src/renderer/sw_engine/tvgSwRenderer.cpp @@ -750,8 +750,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 (!surface || (transform.e11 == 0.0f && transform.e12 == 0.0f) || (transform.e21 == 0.0f && transform.e22 == 0.0f)) return task; //invalid //TODO: Failed threading them. It would be better if it's possible. //See: https://github.com/thorvg/thorvg/issues/1409 @@ -781,7 +780,16 @@ void* SwRenderer::prepareCommon(SwTask* task, const Matrix& transform, const Arr tasks.push(task); } - TaskScheduler::request(task); + //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. + if (flags & RenderUpdateFlag::Clip) { + for (uint32_t i = 0; i < clips.count; ++i) { + static_cast(clips[i])->done(); + } + } + + if (flags) TaskScheduler::request(task); return task; } @@ -791,10 +799,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); } @@ -804,10 +813,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 10d5453f..c9ee7426 100755 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -82,13 +82,14 @@ void WgRenderer::disposeObjects() RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) { - // get or create render data shape + if (flags == RenderUpdateFlag::None) return data; + auto renderDataShape = (WgRenderDataShape*)data; if (!renderDataShape) renderDataShape = mRenderDataShapePool.allocate(mContext); // update geometry - if ((!data) || (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke))) { + if (!data || (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke))) { renderDataShape->updateMeshes(mContext, rshape, transform); } @@ -106,7 +107,7 @@ RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const renderDataShape->renderSettingsStroke.update(mContext, rshape.stroke->fill, rshape.stroke->color, flags); // store clips data - renderDataShape->updateClips(clips); + if (flags & RenderUpdateFlag::Clip) renderDataShape->updateClips(clips); return renderDataShape; } @@ -114,6 +115,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; + // get or create render data shape auto renderDataPicture = (WgRenderDataPicture*)data; if (!renderDataPicture) @@ -139,8 +142,7 @@ RenderData WgRenderer::prepare(RenderSurface* surface, RenderData data, const Ma ); } - // store clips data - renderDataPicture->updateClips(clips); + if (flags & RenderUpdateFlag::Clip) renderDataPicture->updateClips(clips); return renderDataPicture; }