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 (yMin > pt->y) yMin = pt->y;
if (yMax < pt->y) yMax = 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) { if (fastTrack) {
renderRegion.min.x = static_cast<SwCoord>(nearbyint(xMin / 64.0f)); renderRegion.min.x = static_cast<SwCoord>(nearbyint(xMin / 64.0f));
renderRegion.max.x = static_cast<SwCoord>(nearbyint(xMax / 64.0f)); renderRegion.max.x = static_cast<SwCoord>(nearbyint(xMax / 64.0f));

View file

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