mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-23 22:58:44 +00:00
engines: manage the update with the precise update flags
this also fixes one broken clipping issue. issue: https://github.com/thorvg/thorvg/issues/3448
This commit is contained in:
parent
d33a3e53f5
commit
3889ffe8ec
3 changed files with 34 additions and 24 deletions
|
@ -1329,7 +1329,7 @@ RenderData GlRenderer::prepare(RenderSurface* image, RenderData data, const Matr
|
||||||
|
|
||||||
sdata->geometry->tesselate(image, flags);
|
sdata->geometry->tesselate(image, flags);
|
||||||
|
|
||||||
if (!clips.empty()) {
|
if (flags & RenderUpdateFlag::Clip) {
|
||||||
sdata->clips.clear();
|
sdata->clips.clear();
|
||||||
sdata->clips.push(clips);
|
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<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper)
|
RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper)
|
||||||
{
|
{
|
||||||
|
if (flags == RenderUpdateFlag::None) return data;
|
||||||
|
|
||||||
// If prepare for clip, only path is meaningful.
|
// If prepare for clip, only path is meaningful.
|
||||||
if (clipper) flags = RenderUpdateFlag::Path;
|
if (clipper) flags = RenderUpdateFlag::Path;
|
||||||
|
|
||||||
|
@ -1353,7 +1355,6 @@ RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const
|
||||||
sdata->viewWd = static_cast<float>(surface.w);
|
sdata->viewWd = static_cast<float>(surface.w);
|
||||||
sdata->viewHt = static_cast<float>(surface.h);
|
sdata->viewHt = static_cast<float>(surface.h);
|
||||||
sdata->updateFlag = RenderUpdateFlag::None;
|
sdata->updateFlag = RenderUpdateFlag::None;
|
||||||
|
|
||||||
sdata->geometry = make_unique<GlGeometry>();
|
sdata->geometry = make_unique<GlGeometry>();
|
||||||
sdata->opacity = opacity;
|
sdata->opacity = opacity;
|
||||||
|
|
||||||
|
@ -1362,10 +1363,7 @@ RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const
|
||||||
rshape.fillColor(nullptr, nullptr, nullptr, &alphaF);
|
rshape.fillColor(nullptr, nullptr, nullptr, &alphaF);
|
||||||
rshape.strokeColor(nullptr, nullptr, nullptr, &alphaS);
|
rshape.strokeColor(nullptr, nullptr, nullptr, &alphaS);
|
||||||
|
|
||||||
if ( ((flags & RenderUpdateFlag::Gradient) == 0) &&
|
if ((flags & RenderUpdateFlag::Gradient) == 0 && ((flags & RenderUpdateFlag::Color) && alphaF == 0) && ((flags & RenderUpdateFlag::Stroke) && alphaS == 0)) {
|
||||||
((flags & RenderUpdateFlag::Color) && alphaF == 0) &&
|
|
||||||
((flags & RenderUpdateFlag::Stroke) && alphaS == 0) )
|
|
||||||
{
|
|
||||||
return sdata;
|
return sdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1383,12 +1381,11 @@ RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const
|
||||||
sdata->geometry->updateTransform(transform);
|
sdata->geometry->updateTransform(transform);
|
||||||
sdata->geometry->setViewport(mViewport);
|
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 (!sdata->geometry->tesselate(rshape, sdata->updateFlag)) return sdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!clipper && !clips.empty()) {
|
if (flags & RenderUpdateFlag::Clip) {
|
||||||
sdata->clips.clear();
|
sdata->clips.clear();
|
||||||
sdata->clips.push(clips);
|
sdata->clips.push(clips);
|
||||||
}
|
}
|
||||||
|
|
|
@ -750,8 +750,7 @@ void SwRenderer::dispose(RenderData data)
|
||||||
|
|
||||||
void* SwRenderer::prepareCommon(SwTask* task, const Matrix& transform, const Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags)
|
void* SwRenderer::prepareCommon(SwTask* task, const Matrix& transform, const Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags)
|
||||||
{
|
{
|
||||||
if (!surface) return task;
|
if (!surface || (transform.e11 == 0.0f && transform.e12 == 0.0f) || (transform.e21 == 0.0f && transform.e22 == 0.0f)) return task; //invalid
|
||||||
if (flags == RenderUpdateFlag::None) return task;
|
|
||||||
|
|
||||||
//TODO: Failed threading them. It would be better if it's possible.
|
//TODO: Failed threading them. It would be better if it's possible.
|
||||||
//See: https://github.com/thorvg/thorvg/issues/1409
|
//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);
|
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<SwTask*>(clips[i])->done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags) TaskScheduler::request(task);
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
@ -791,10 +799,11 @@ RenderData SwRenderer::prepare(RenderSurface* surface, RenderData data, const Ma
|
||||||
{
|
{
|
||||||
//prepare task
|
//prepare task
|
||||||
auto task = static_cast<SwImageTask*>(data);
|
auto task = static_cast<SwImageTask*>(data);
|
||||||
if (!task) task = new SwImageTask;
|
if (task) task->done();
|
||||||
else task->done();
|
else {
|
||||||
|
task = new SwImageTask;
|
||||||
task->source = surface;
|
task->source = surface;
|
||||||
|
}
|
||||||
|
|
||||||
return prepareCommon(task, transform, clips, opacity, flags);
|
return prepareCommon(task, transform, clips, opacity, flags);
|
||||||
}
|
}
|
||||||
|
@ -804,10 +813,12 @@ RenderData SwRenderer::prepare(const RenderShape& rshape, RenderData data, const
|
||||||
{
|
{
|
||||||
//prepare task
|
//prepare task
|
||||||
auto task = static_cast<SwShapeTask*>(data);
|
auto task = static_cast<SwShapeTask*>(data);
|
||||||
if (!task) task = new SwShapeTask;
|
if (task) task->done();
|
||||||
else task->done();
|
else {
|
||||||
|
task = new SwShapeTask;
|
||||||
|
task->rshape = &rshape;
|
||||||
|
}
|
||||||
|
|
||||||
task->rshape = &rshape;
|
|
||||||
task->clipper = clipper;
|
task->clipper = clipper;
|
||||||
|
|
||||||
return prepareCommon(task, transform, clips, opacity, flags);
|
return prepareCommon(task, transform, clips, opacity, flags);
|
||||||
|
|
|
@ -82,13 +82,14 @@ void WgRenderer::disposeObjects()
|
||||||
|
|
||||||
RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper)
|
RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper)
|
||||||
{
|
{
|
||||||
// get or create render data shape
|
if (flags == RenderUpdateFlag::None) return data;
|
||||||
|
|
||||||
auto renderDataShape = (WgRenderDataShape*)data;
|
auto renderDataShape = (WgRenderDataShape*)data;
|
||||||
if (!renderDataShape)
|
if (!renderDataShape)
|
||||||
renderDataShape = mRenderDataShapePool.allocate(mContext);
|
renderDataShape = mRenderDataShapePool.allocate(mContext);
|
||||||
|
|
||||||
// update geometry
|
// update geometry
|
||||||
if ((!data) || (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke))) {
|
if (!data || (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke))) {
|
||||||
renderDataShape->updateMeshes(mContext, rshape, transform);
|
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);
|
renderDataShape->renderSettingsStroke.update(mContext, rshape.stroke->fill, rshape.stroke->color, flags);
|
||||||
|
|
||||||
// store clips data
|
// store clips data
|
||||||
renderDataShape->updateClips(clips);
|
if (flags & RenderUpdateFlag::Clip) renderDataShape->updateClips(clips);
|
||||||
|
|
||||||
return renderDataShape;
|
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<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags)
|
RenderData WgRenderer::prepare(RenderSurface* surface, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags)
|
||||||
{
|
{
|
||||||
|
if (flags == RenderUpdateFlag::None) return data;
|
||||||
|
|
||||||
// get or create render data shape
|
// get or create render data shape
|
||||||
auto renderDataPicture = (WgRenderDataPicture*)data;
|
auto renderDataPicture = (WgRenderDataPicture*)data;
|
||||||
if (!renderDataPicture)
|
if (!renderDataPicture)
|
||||||
|
@ -139,8 +142,7 @@ RenderData WgRenderer::prepare(RenderSurface* surface, RenderData data, const Ma
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// store clips data
|
if (flags & RenderUpdateFlag::Clip) renderDataPicture->updateClips(clips);
|
||||||
renderDataPicture->updateClips(clips);
|
|
||||||
|
|
||||||
return renderDataPicture;
|
return renderDataPicture;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue