sw_engine texmap: code optimization.

Unify textmap methods that are overly duplicated with each other.

Still trying to simplifying raster code so that thorvg could introduce
the a bunch of masking method code nicely.

This reduces the size like: 214773 -> 212843 (-2kb)
This commit is contained in:
Hermet Park 2023-05-31 12:13:35 +09:00 committed by Hermet Park
parent 01974f652c
commit 9032c00347
2 changed files with 96 additions and 89 deletions

View file

@ -71,31 +71,13 @@ static bool _arrange(const SwImage* image, const SwBBox* region, int& yStart, in
static void _rasterMaskedPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t opacity, AASpans* aaSpans)
{
#define TEXMAP_TRANSLUCENT
#define TEXMAP_MASKING
#include "tvgSwRasterTexmapInternal.h"
#undef TEXMAP_MASKING
#undef TEXMAP_TRANSLUCENT
}
static void _rasterMaskedPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, AASpans* aaSpans)
{
#define TEXMAP_MASKING
#include "tvgSwRasterTexmapInternal.h"
#undef TEXMAP_MASKING
}
static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t opacity, AASpans* aaSpans)
{
#define TEXMAP_TRANSLUCENT
#include "tvgSwRasterTexmapInternal.h"
#undef TEXMAP_TRANSLUCENT
}
static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, AASpans* aaSpans)
{
#include "tvgSwRasterTexmapInternal.h"
}
@ -191,13 +173,8 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const
dxdyb = dxdy[0];
xb = x[0] + dy * dxdyb + (off_y * dxdyb);
if (masking) {
if (opacity == 255) _rasterMaskedPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans);
else _rasterMaskedPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, aaSpans);
} else {
if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans);
else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, aaSpans);
}
if (masking) _rasterMaskedPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, aaSpans);
else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, aaSpans);
upper = true;
}
@ -212,13 +189,8 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const
// Set right edge X-slope and perform subpixel pre-stepping
dxdyb = dxdy[2];
xb = x[1] + (1 - (y[1] - yi[1])) * dxdyb + (off_y * dxdyb);
if (masking) {
if (opacity == 255) _rasterMaskedPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans);
else _rasterMaskedPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, aaSpans);
} else {
if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans);
else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, aaSpans);
}
if (masking) _rasterMaskedPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, aaSpans);
else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, aaSpans);
}
//Longer edge is on the right side
} else {
@ -241,13 +213,8 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const
ua = u[0] + dy * dudya + (off_y * dudya);
va = v[0] + dy * dvdya + (off_y * dvdya);
if (masking) {
if (opacity == 255) _rasterMaskedPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans);
else _rasterMaskedPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, aaSpans);
} else {
if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans);
else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, aaSpans);
}
if (masking) _rasterMaskedPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, aaSpans);
else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, aaSpans);
upper = true;
}
@ -265,13 +232,8 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const
ua = u[1] + dy * dudya + (off_y * dudya);
va = v[1] + dy * dvdya + (off_y * dvdya);
if (masking) {
if (opacity == 255) _rasterMaskedPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans);
else _rasterMaskedPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, aaSpans);
} else {
if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans);
else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, aaSpans);
}
if (masking) _rasterMaskedPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, aaSpans);
else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, aaSpans);
}
}
}

View file

@ -98,59 +98,104 @@
#ifdef TEXMAP_MASKING
cmp = &surface->compositor->image.buf8[(y * surface->compositor->image.stride + x1) * csize];
#endif
//Draw horizontal line
while (x++ < x2) {
uu = (int) u;
vv = (int) v;
if (opacity == 255) {
//Draw horizontal line
while (x++ < x2) {
uu = (int) u;
vv = (int) v;
ar = (int)(255 * (1 - modff(u, &iptr)));
ab = (int)(255 * (1 - modff(v, &iptr)));
iru = uu + 1;
irv = vv + 1;
ar = (int)(255 * (1 - modff(u, &iptr)));
ab = (int)(255 * (1 - modff(v, &iptr)));
iru = uu + 1;
irv = vv + 1;
if (vv >= sh) continue;
if (vv >= sh) continue;
px = *(sbuf + (vv * sw) + uu);
/* horizontal interpolate */
if (iru < sw) {
/* right pixel */
int px2 = *(sbuf + (vv * sw) + iru);
px = INTERPOLATE(px, px2, ar);
}
/* vertical interpolate */
if (irv < sh) {
/* bottom pixel */
int px2 = *(sbuf + (irv * sw) + uu);
px = *(sbuf + (vv * sw) + uu);
/* horizontal interpolate */
if (iru < sw) {
/* bottom right pixel */
int px3 = *(sbuf + (irv * sw) + iru);
px2 = INTERPOLATE(px2, px3, ar);
/* right pixel */
int px2 = *(sbuf + (vv * sw) + iru);
px = INTERPOLATE(px, px2, ar);
}
px = INTERPOLATE(px, px2, ab);
/* vertical interpolate */
if (irv < sh) {
/* bottom pixel */
int px2 = *(sbuf + (irv * sw) + uu);
/* horizontal interpolate */
if (iru < sw) {
/* bottom right pixel */
int px3 = *(sbuf + (irv * sw) + iru);
px2 = INTERPOLATE(px2, px3, ar);
}
px = INTERPOLATE(px, px2, ab);
}
#ifdef TEXMAP_MASKING
auto src = ALPHA_BLEND(px, alpha(cmp));
cmp += csize;
#else
auto src = px;
#endif
*buf = src + ALPHA_BLEND(*buf, IALPHA(src));
++buf;
//Step UV horizontally
u += _dudx;
v += _dvdx;
//range over?
if ((uint32_t)v >= image->h) break;
}
} else {
//Draw horizontal line
while (x++ < x2) {
uu = (int) u;
vv = (int) v;
#if defined(TEXMAP_MASKING) && defined(TEXMAP_TRANSLUCENT)
auto src = ALPHA_BLEND(px, MULTIPLY(opacity, alpha(cmp)));
cmp += csize;
#elif defined(TEXMAP_MASKING)
auto src = ALPHA_BLEND(px, alpha(cmp));
cmp += csize;
#elif defined(TEXMAP_TRANSLUCENT)
auto src = ALPHA_BLEND(px, opacity);
#else
auto src = px;
#endif
*buf = src + ALPHA_BLEND(*buf, IALPHA(src));
++buf;
ar = (int)(255 * (1 - modff(u, &iptr)));
ab = (int)(255 * (1 - modff(v, &iptr)));
iru = uu + 1;
irv = vv + 1;
//Step UV horizontally
u += _dudx;
v += _dvdx;
//range over?
if ((uint32_t)v >= image->h) break;
if (vv >= sh) continue;
px = *(sbuf + (vv * sw) + uu);
/* horizontal interpolate */
if (iru < sw) {
/* right pixel */
int px2 = *(sbuf + (vv * sw) + iru);
px = INTERPOLATE(px, px2, ar);
}
/* vertical interpolate */
if (irv < sh) {
/* bottom pixel */
int px2 = *(sbuf + (irv * sw) + uu);
/* horizontal interpolate */
if (iru < sw) {
/* bottom right pixel */
int px3 = *(sbuf + (irv * sw) + iru);
px2 = INTERPOLATE(px2, px3, ar);
}
px = INTERPOLATE(px, px2, ab);
}
#ifdef TEXMAP_MASKING
auto src = ALPHA_BLEND(px, MULTIPLY(opacity, alpha(cmp)));
cmp += csize;
#else
auto src = ALPHA_BLEND(px, opacity);
#endif
*buf = src + ALPHA_BLEND(*buf, IALPHA(src));
++buf;
//Step UV horizontally
u += _dudx;
v += _dvdx;
//range over?
if ((uint32_t)v >= image->h) break;
}
}
next:
//Step along both edges