sw_engine: properly update the render region

shape render region should be aligned with the
current shape bbox. this could bring the compact size
of the rendering region even shapes are not drawable.
This commit is contained in:
Hermet Park 2024-10-08 16:25:09 +09:00 committed by Hermet Park
parent 6cfc22d123
commit 4feab345fb
3 changed files with 15 additions and 12 deletions

View file

@ -303,9 +303,7 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S
if (yMin > pt->y) yMin = pt->y;
if (yMax < pt->y) yMax = pt->y;
}
//Since no antialiasing is applied in the Fast Track case,
//the rasterization region has to be rearranged.
//https://github.com/Samsung/thorvg/issues/916
if (fastTrack) {
renderRegion.min.x = static_cast<SwCoord>(nearbyint(xMin / 64.0f));
renderRegion.max.x = static_cast<SwCoord>(nearbyint(xMax / 64.0f));

View file

@ -41,7 +41,7 @@ struct SwTask : Task
{
SwSurface* surface = nullptr;
SwMpool* mpool = nullptr;
SwBBox bbox = {{0, 0}, {0, 0}}; //Whole Rendering Region
SwBBox bbox; //Rendering Region
Matrix transform;
Array<RenderData> clips;
RenderUpdateFlag flags = RenderUpdateFlag::None;
@ -112,11 +112,14 @@ struct SwShapeTask : SwTask
void run(unsigned tid) override
{
if (opacity == 0 && !clipper) return; //Invisible
//Invisible
if (opacity == 0 && !clipper) {
bbox.reset();
return;
}
auto strokeWidth = validStrokeWidth();
bool visibleFill = false;
auto clipRegion = bbox;
//This checks also for the case, if the invisible shape turned to visible by alpha.
auto prepareShape = false;
@ -128,10 +131,11 @@ struct SwShapeTask : SwTask
rshape->fillColor(nullptr, nullptr, nullptr, &alpha);
alpha = MULTIPLY(alpha, opacity);
visibleFill = (alpha > 0 || rshape->fill);
if (visibleFill || clipper) {
shapeReset(&shape);
if (!shapePrepare(&shape, rshape, transform, clipRegion, bbox, mpool, tid, clips.count > 0 ? true : false)) {
if (visibleFill || clipper) {
if (!shapePrepare(&shape, rshape, transform, bbox, shape.bbox, mpool, tid, clips.count > 0 ? true : false)) {
visibleFill = false;
shape.bbox.reset();
}
}
}
@ -152,7 +156,7 @@ struct SwShapeTask : SwTask
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) {
if (strokeWidth > 0.0f) {
shapeResetStroke(&shape, rshape, transform);
if (!shapeGenStrokeRle(&shape, rshape, transform, clipRegion, bbox, mpool, tid)) goto err;
if (!shapeGenStrokeRle(&shape, rshape, transform, bbox, shape.bbox, mpool, tid)) goto err;
if (auto fill = rshape->strokeFill()) {
auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false;
@ -177,9 +181,13 @@ struct SwShapeTask : SwTask
//Clip stroke rle
if (shape.strokeRle && !clipper->clip(shape.strokeRle)) goto err;
}
bbox = shape.bbox; //sync
return;
err:
bbox.reset();
shapeReset(&shape);
shapeDelOutline(&shape, mpool, tid);
}

View file

@ -498,9 +498,6 @@ bool shapePrepare(SwShape* shape, const RenderShape* rshape, const Matrix& trans
if (!_genOutline(shape, rshape, transform, mpool, tid, hasComposite)) return false;
if (!mathUpdateOutlineBBox(shape->outline, clipRegion, renderRegion, shape->fastTrack)) return false;
//Keep it for Rasterization Region
shape->bbox = renderRegion;
//Check valid region
if (renderRegion.max.x - renderRegion.min.x < 1 && renderRegion.max.y - renderRegion.min.y < 1) return false;