From 9032c00347f4f6d5bd146cf3ebb5e6aba6a2b48d Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 31 May 2023 12:13:35 +0900 Subject: [PATCH] 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) --- src/lib/sw_engine/tvgSwRasterTexmap.h | 54 ++------ src/lib/sw_engine/tvgSwRasterTexmapInternal.h | 131 ++++++++++++------ 2 files changed, 96 insertions(+), 89 deletions(-) diff --git a/src/lib/sw_engine/tvgSwRasterTexmap.h b/src/lib/sw_engine/tvgSwRasterTexmap.h index cc0c5afb..0727461d 100644 --- a/src/lib/sw_engine/tvgSwRasterTexmap.h +++ b/src/lib/sw_engine/tvgSwRasterTexmap.h @@ -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); } } } diff --git a/src/lib/sw_engine/tvgSwRasterTexmapInternal.h b/src/lib/sw_engine/tvgSwRasterTexmapInternal.h index 750f7520..a2a98e86 100644 --- a/src/lib/sw_engine/tvgSwRasterTexmapInternal.h +++ b/src/lib/sw_engine/tvgSwRasterTexmapInternal.h @@ -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