sw_engine raster: fix the texmap regression bug.
authorHermet Park <chuneon.park@samsung.com>
Fri, 26 Nov 2021 08:14:44 +0000 (17:14 +0900)
committerHermet Park <chuneon.park@samsung.com>
Tue, 30 Nov 2021 03:48:04 +0000 (12:48 +0900)
Wrong inline function with C-preprocessing doesn't work at all...
Correct them with including the separate files instead.

src/lib/sw_engine/meson.build
src/lib/sw_engine/tvgSwRasterTexmap.h
src/lib/sw_engine/tvgSwRasterTexmapInternal.h [new file with mode: 0644]

index f390d0397ca0199a74d2f703938e9243b689d0a7..8d41bee64802cfddf72a2e78eae92f8152c5c8d6 100644 (file)
@@ -4,6 +4,7 @@ source_file = [
    'tvgSwRasterAvx.h',
    'tvgSwRasterNeon.h',
    'tvgSwRasterTexmap.h',
+   'tvgSwRasterTexmapInternal.h',
    'tvgSwFill.cpp',
    'tvgSwImage.cpp',
    'tvgSwMath.cpp',
index c4ee7cea249afd25034ae25d8b0d1b1e19623f75..ca4e30352e64700d1f12e4c05a941e6f80140e53 100644 (file)
@@ -44,153 +44,35 @@ static float dxdya, dxdyb, dudya, dvdya;
 static float xa, xb, ua, va;
 
 
-static inline void _rasterRGBA(SwSurface* surface, const SwImage* image, const SwBBox& region, int ystart, int yend, TVG_UNUSED uint32_t opacity, TVG_UNUSED uint32_t (*blendMethod)(uint32_t))
+static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox& region, int ystart, int yend, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
 {
-    float _dudx = dudx, _dvdx = dvdx;
-    float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya;
-    float _xa = xa, _xb = xb, _ua = ua, _va = va;
-    auto sbuf = image->data;
-    auto dbuf = surface->buffer;
-    int sw = static_cast<int>(image->stride);
-    int sh = image->h;
-    int dw = surface->stride;
-    int x1, x2, x, y, ar, ab, iru, irv, px;
-    int vv = 0;
-    int uu = 0;
-    float dx, u, v, iptr;
-    uint32_t* buf;
-
-    //Range exception handling
-    if (ystart >= region.max.y) return;
-    if (ystart < region.min.y) ystart = region.min.y;
-    if (yend > region.max.y) yend = region.max.y;
-
-    //Loop through all lines in the segment
-    y = ystart;
-
-    while (y < yend) {
-        x1 = _xa;
-        x2 = _xb;
-
-        //Range exception handling
-        if (x1 < region.min.x) x1 = region.min.x;
-        if (x2 > region.max.x) x2 = region.max.x;
-
-        if ((x2 - x1) < 1) goto next;
-        if ((x1 >= region.max.x) || (x2 <= region.min.x)) goto next;
-
-        //Perform subtexel pre-stepping on UV
-        dx = 1 - (_xa - x1);
-        u = _ua + dx * _dudx;
-        v = _va + dx * _dvdx;
-
-        buf = dbuf + ((y * dw) + x1);
-
-        x = x1;
-
-#ifdef TEXMAP_MAKSING
-        auto cmp = &surface->compositor->image.data[y * surface->compositor->image.stride + x1];
-#endif
-        //Draw horizontal line
-        while (x++ < x2) {
-            uu = (int) u;
-            vv = (int) v;
-            /* FIXME: sometimes u and v are < 0 - don'tc crash */
-            if (uu < 0) uu = 0;
-            if (vv < 0) vv = 0;
-
-            /* Range exception handling */
-            /* OPTIMIZE ME, handle in advance? */
-            if (uu >= sw) uu = sw - 1;
-            if (vv >= sh) vv = sh - 1;
-
-            ar = (int)(255 * (1 - modff(u, &iptr)));
-            ab = (int)(255 * (1 - modff(v, &iptr)));
-            iru = uu + 1;
-            irv = vv + 1;
-            px = *(sbuf + (vv * sw) + uu);
-
-            /* horizontal interpolate */
-            if (iru < sw) {
-                /* right pixel */
-                int px2 = *(sbuf + (vv * sw) + iru);
-                px = INTERPOLATE(ar, px, px2);
-            }
-            /* 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(ar, px2, px3);
-                }
-                px = INTERPOLATE(ab, px, px2);
-            }
-#if defined(TEXMAP_MAKSING) && defined(TEXTMAP_TRANSLUCENT)
-            auto src = ALPHA_BLEND(px, _multiplyAlpha(opacity, blendMethod(*cmp)));
-#elif defined(TEXMAP_MAKSING)
-            auto src = ALPHA_BLEND(px, blendMethod(*cmp));
-#elif defined(TEXTMAP_TRANSLUCENT)
-            auto src = ALPHA_BLEND(px, opacity);
-#else
-            auto src = px;
-#endif
-            *buf = src + ALPHA_BLEND(*buf, surface->blender.ialpha(src));
-            ++buf;
-#ifdef TEXMAP_MAKSING
-            ++cmp;
-#endif
-            //Step UV horizontally
-            u += _dudx;
-            v += _dvdx;
-        }
-next:
-        //Step along both edges
-        _xa += _dxdya;
-        _xb += _dxdyb;
-        _ua += _dudya;
-        _va += _dvdya;
-
-        y++;
-    }
-    xa = _xa;
-    xb = _xb;
-    ua = _ua;
-    va = _va;
-}
-
-static inline void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox& region, int ystart, int yend, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
-{
-#define TEXTMAP_TRANSLUCENT
-#define TEXMAP_MAKSING
-    _rasterRGBA(surface, image, region, ystart, yend, opacity, blendMethod);
+#define TEXMAP_TRANSLUCENT
+#define TEXMAP_MASKING
+      #include "tvgSwRasterTexmapInternal.h"
 #undef TEXMAP_MASKING
-#undef TEXTMAP_TRANSLUCENT
+#undef TEXMAP_TRANSLUCENT
 }
 
 
-static inline void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox& region, int ystart, int yend, uint32_t (*blendMethod)(uint32_t))
+static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox& region, int ystart, int yend, uint32_t (*blendMethod)(uint32_t))
 {
-#define TEXMAP_MAKSING
-    _rasterRGBA(surface, image, region, ystart, yend, 255, nullptr);
+#define TEXMAP_MASKING
+    #include "tvgSwRasterTexmapInternal.h"
 #undef TEXMAP_MASKING
 }
 
 
-static inline void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox& region, int ystart, int yend, uint32_t opacity)
+static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox& region, int ystart, int yend, uint32_t opacity)
 {
-#define TEXTMAP_TRANSLUCENT
-    _rasterRGBA(surface, image, region, ystart, yend, opacity, nullptr);
-#undef TEXTMAP_TRANSLUCENT
+#define TEXMAP_TRANSLUCENT
+     #include "tvgSwRasterTexmapInternal.h"
+#undef TEXMAP_TRANSLUCENT
 }
 
 
-static inline void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox& region, int ystart, int yend)
+static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox& region, int ystart, int yend)
 {
-    _rasterRGBA(surface, image, region, ystart, yend, 255, nullptr);
+    #include "tvgSwRasterTexmapInternal.h"
 }
 
 
diff --git a/src/lib/sw_engine/tvgSwRasterTexmapInternal.h b/src/lib/sw_engine/tvgSwRasterTexmapInternal.h
new file mode 100644 (file)
index 0000000..d7084bc
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+{
+    float _dudx = dudx, _dvdx = dvdx;
+    float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya;
+    float _xa = xa, _xb = xb, _ua = ua, _va = va;
+    auto sbuf = image->data;
+    auto dbuf = surface->buffer;
+    int sw = static_cast<int>(image->stride);
+    int sh = image->h;
+    int dw = surface->stride;
+    int x1, x2, x, y, ar, ab, iru, irv, px;
+    int vv = 0;
+    int uu = 0;
+    float dx, u, v, iptr;
+    uint32_t* buf;
+#ifdef TEXMAP_MASKING
+    uint32_t* cmp;
+#endif
+
+    //Range exception handling
+    if (ystart >= region.max.y) return;
+    if (ystart < region.min.y) ystart = region.min.y;
+    if (yend > region.max.y) yend = region.max.y;
+
+    //Loop through all lines in the segment
+    y = ystart;
+
+    while (y < yend) {
+        x1 = _xa;
+        x2 = _xb;
+
+        //Range exception handling
+        if (x1 < region.min.x) x1 = region.min.x;
+        if (x2 > region.max.x) x2 = region.max.x;
+
+        if ((x2 - x1) < 1) goto next;
+        if ((x1 >= region.max.x) || (x2 <= region.min.x)) goto next;
+
+        //Perform subtexel pre-stepping on UV
+        dx = 1 - (_xa - x1);
+        u = _ua + dx * _dudx;
+        v = _va + dx * _dvdx;
+
+        buf = dbuf + ((y * dw) + x1);
+
+        x = x1;
+
+#ifdef TEXMAP_MASKING
+        cmp = &surface->compositor->image.data[y * surface->compositor->image.stride + x1];
+#endif
+        //Draw horizontal line
+        while (x++ < x2) {
+            uu = (int) u;
+            vv = (int) v;
+            /* FIXME: sometimes u and v are < 0 - don'tc crash */
+            if (uu < 0) uu = 0;
+            if (vv < 0) vv = 0;
+
+            /* Range exception handling */
+            /* OPTIMIZE ME, handle in advance? */
+            if (uu >= sw) uu = sw - 1;
+            if (vv >= sh) vv = sh - 1;
+
+            ar = (int)(255 * (1 - modff(u, &iptr)));
+            ab = (int)(255 * (1 - modff(v, &iptr)));
+            iru = uu + 1;
+            irv = vv + 1;
+            px = *(sbuf + (vv * sw) + uu);
+
+            /* horizontal interpolate */
+            if (iru < sw) {
+                /* right pixel */
+                int px2 = *(sbuf + (vv * sw) + iru);
+                px = INTERPOLATE(ar, px, px2);
+            }
+            /* 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(ar, px2, px3);
+                }
+                px = INTERPOLATE(ab, px, px2);
+            }
+#if defined(TEXMAP_MASKING) && defined(TEXMAP_TRANSLUCENT)
+            auto src = ALPHA_BLEND(px, _multiplyAlpha(opacity, blendMethod(*cmp)));
+#elif defined(TEXMAP_MASKING)
+            auto src = ALPHA_BLEND(px, blendMethod(*cmp));
+#elif defined(TEXMAP_TRANSLUCENT)
+            auto src = ALPHA_BLEND(px, opacity);
+#else
+            auto src = px;            
+#endif
+            *buf = src + ALPHA_BLEND(*buf, surface->blender.ialpha(src));
+            ++buf;
+#ifdef TEXMAP_MASKING
+            ++cmp;
+#endif
+            //Step UV horizontally
+            u += _dudx;
+            v += _dvdx;
+        }
+next:
+        //Step along both edges
+        _xa += _dxdya;
+        _xb += _dxdyb;
+        _ua += _dudya;
+        _va += _dvdya;
+
+        y++;
+    }
+    xa = _xa;
+    xb = _xb;
+    ua = _ua;
+    va = _va;
+}
\ No newline at end of file