sw_engine: skip AA if texture are orthogonally rotated.

there is no necessary applying AA for 0/90/180/270 degree rotation

issue: https://github.com/thorvg/thorvg/issues/3452
This commit is contained in:
Hermet Park 2025-06-09 13:02:19 +09:00 committed by Hermet Park
parent ae97f5f20f
commit 8eb046c318
2 changed files with 21 additions and 24 deletions

View file

@ -90,7 +90,7 @@ bool operator==(const Matrix& lhs, const Matrix& rhs);
static inline bool rightAngle(const Matrix& m)
{
auto radian = fabsf(tvg::atan2(m.e21, m.e11));
if (radian < FLOAT_EPSILON || tvg::equal(radian, MATH_PI2) || tvg::equal(radian, MATH_PI)) return true;
if (tvg::zero(radian) || tvg::zero(radian - MATH_PI2) || tvg::zero(radian - MATH_PI)) return true;
return false;
}

View file

@ -131,9 +131,11 @@ static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage
if (x2 > maxx) x2 = maxx;
//Anti-Aliasing frames
if (aaSpans) {
ay = y - aaSpans->yStart;
if (aaSpans->lines[ay].x[0] > x1) aaSpans->lines[ay].x[0] = x1;
if (aaSpans->lines[ay].x[1] < x2) aaSpans->lines[ay].x[1] = x2;
}
//Range allowed
if ((x2 - x1) >= 1 && (x1 < maxx) && (x2 > minx)) {
@ -264,20 +266,19 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
if (x2 > maxx) x2 = maxx;
//Anti-Aliasing frames
if (aaSpans) {
ay = y - aaSpans->yStart;
if (aaSpans->lines[ay].x[0] > x1) aaSpans->lines[ay].x[0] = x1;
if (aaSpans->lines[ay].x[1] < x2) aaSpans->lines[ay].x[1] = x2;
}
//Range allowed
if ((x2 - x1) >= 1 && (x1 < maxx) && (x2 > minx)) {
//Perform subtexel pre-stepping on UV
dx = 1 - (_xa - x1);
u = _ua + dx * _dudx;
v = _va + dx * _dvdx;
buf = dbuf + ((y * surface->stride) + x1);
x = x1;
if (matting) cmp = &surface->compositor->image.buf8[(y * surface->compositor->image.stride + x1) * csize];
@ -576,13 +577,8 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const
}
static AASpans* _AASpans(float ymin, float ymax, const SwImage* image, const RenderRegion* bbox)
static AASpans* _AASpans(int yStart, int yEnd)
{
auto yStart = static_cast<int>(ymin);
auto yEnd = static_cast<int>(ymax);
if (!_arrange(image, bbox, yStart, yEnd)) return nullptr;
auto aaSpans = tvg::malloc<AASpans*>(sizeof(AASpans));
aaSpans->yStart = yStart;
aaSpans->yEnd = yEnd;
@ -791,7 +787,7 @@ static void _calcAAEdge(AASpans *aaSpans, int32_t eidx)
}
static bool _apply(SwSurface* surface, AASpans* aaSpans)
static void _apply(SwSurface* surface, AASpans* aaSpans)
{
auto end = surface->buf32 + surface->h * surface->stride;
auto y = aaSpans->yStart;
@ -848,8 +844,6 @@ static bool _apply(SwSurface* surface, AASpans* aaSpans)
tvg::free(aaSpans->lines);
tvg::free(aaSpans);
return true;
}
@ -873,8 +867,7 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const
//Exceptions: No dedicated drawing area?
if ((!image->rle && !bbox) || (image->rle && image->rle->size() == 0)) return true;
/* Prepare vertices.
shift XY coordinates to match the sub-pixeling technique. */
//Prepare vertices. Shift XY coordinates to match the sub-pixeling technique.
Vertex vertices[4];
vertices[0] = {{0.0f, 0.0f}, {0.0f, 0.0f}};
vertices[1] = {{float(image->w), 0.0f}, {float(image->w), 0.0f}};
@ -888,8 +881,11 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const
if (vertices[i].pt.y > ye) ye = vertices[i].pt.y;
}
auto aaSpans = _AASpans(ys, ye, image, bbox);
if (!aaSpans) return true;
auto yStart = static_cast<int>(ys);
auto yEnd = static_cast<int>(ye);
if (!_arrange(image, bbox, yStart, yEnd)) return true;
auto aaSpans = rightAngle(transform) ? nullptr : _AASpans(yStart, yEnd);
Polygon polygon;
@ -912,5 +908,6 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const
_compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox);
}
#endif
return _apply(surface, aaSpans);
if (aaSpans) _apply(surface, aaSpans);
return true;
}