sw_engine raster: code refactoring.
authorHermet Park <chuneon.park@samsung.com>
Wed, 4 Aug 2021 10:11:12 +0000 (19:11 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Fri, 6 Aug 2021 01:04:08 +0000 (10:04 +0900)
Separate simd implementation by files to maintain them easier.

Now we have avx, c, neon version implementation base,
we can add implementations to them.

src/lib/sw_engine/meson.build
src/lib/sw_engine/tvgSwCommon.h
src/lib/sw_engine/tvgSwRaster.cpp
src/lib/sw_engine/tvgSwRasterAvx.h [new file with mode: 0644]
src/lib/sw_engine/tvgSwRasterC.h [new file with mode: 0644]
src/lib/sw_engine/tvgSwRasterNeon.h [new file with mode: 0644]

index 7357a88..0b1a6a7 100644 (file)
@@ -1,5 +1,8 @@
 source_file = [
    'tvgSwCommon.h',
+   'tvgSwRasterC.h',
+   'tvgSwRasterAvx.h',
+   'tvgSwRasterNeon.h',
    'tvgSwFill.cpp',
    'tvgSwImage.cpp',
    'tvgSwMath.cpp',
index 6ad2df4..e77424c 100644 (file)
 #include "tvgCommon.h"
 #include "tvgRender.h"
 
-#ifdef THORVG_AVX_VECTOR_SUPPORT
-    #include <immintrin.h>
-#endif
-
-#ifdef THORVG_NEON_VECTOR_SUPPORT
-    #include <arm_neon.h>
-#endif
-
 #if 0
 #include <sys/time.h>
 static double timeStamp()
index 5fcc81a..8498561 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "tvgSwCommon.h"
-#include "tvgRender.h"
 #include <float.h>
 #include <math.h>
+#include "tvgSwCommon.h"
+#include "tvgRender.h"
+#include "tvgSwRasterC.h"
+#include "tvgSwRasterAvx.h"
+#include "tvgSwRasterNeon.h"
 
 /************************************************************************/
 /* Internal Class Implementation                                        */
@@ -208,48 +211,6 @@ static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, uint32_t
 /************************************************************************/
 
 
-static bool _translucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color)
-{
-    auto span = rle->spans;
-    uint32_t src;
-
-    for (uint32_t i = 0; i < rle->size; ++i) {
-        auto dst = &surface->buffer[span->y * surface->stride + span->x];
-
-#if defined(THORVG_NEON_VECTOR_SUPPORT)
-        uint8x8_t *vDst = (uint8x8_t*) dst;
-#endif
-
-        if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage);
-        else src = color;
-        auto ialpha = 255 - surface->blender.alpha(src);
-
-#if defined(THORVG_NEON_VECTOR_SUPPORT)
-        uint8x8_t vSrc = (uint8x8_t) vdup_n_u32(src);
-        uint8x8_t vIalpha = (uint8x8_t) vdup_n_u32(ialpha);
-
-        uint32_t iterations = span->len / 2;
-        uint32_t left = span->len % 2;
-
-        for (uint32_t x = 0; x < iterations; x+=2) {
-            vDst[x] = vadd_u8(vSrc, ALPHA_BLEND_NEON(vDst[x], vIalpha));
-        }
-
-        if (left) {
-            dst[span->len] = src + ALPHA_BLEND(dst[span->len], ialpha);
-        }
-#else
-
-        for (uint32_t x = 0; x < span->len; ++x) {
-            dst[x] = src + ALPHA_BLEND(dst[x], ialpha);
-        }
-#endif
-        ++span;
-    }
-    return true;
-}
-
-
 static bool _translucentRleAlphaMask(SwSurface* surface, const SwRleData* rle, uint32_t color)
 {
     TVGLOG("SW_ENGINE", "Rle Alpha Mask Composition");
@@ -308,7 +269,12 @@ static bool _rasterTranslucentRle(SwSurface* surface, SwRleData* rle, uint32_t c
             return _translucentRleInvAlphaMask(surface, rle, color);
         }
     }
-    return _translucentRle(surface, rle, color);
+
+#if defined(THORVG_NEON_VECTOR_SUPPORT)
+    return neonRasterTranslucentRle(surface, rle, color);
+#else
+    return cRasterTranslucentRle(surface, rle, color);
+#endif
 }
 
 
@@ -1278,42 +1244,11 @@ static bool _rasterOpaqueRadialGradientRle(SwSurface* surface, const SwRleData*
 void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
 {
 #if defined(THORVG_AVX_VECTOR_SUPPORT)
-    //1. calculate how many iterations we need to cover length
-    uint32_t iterations = len / 8;
-    uint32_t avxFilled = iterations * 8;
-
-    //2. set beginning of the array
-    dst += offset;
-    __m256i_u* avxDst = (__m256i_u*) dst;
-
-    //3. fill octets
-    for (uint32_t i = 0; i < iterations; ++i) {
-        *avxDst = _mm256_set1_epi32(val);
-        avxDst++;
-    }
-
-    //4. fill leftovers (in first step we have to set pointer to place where avx job is done)
-    int32_t leftovers = len - avxFilled;
-    dst += avxFilled;
-
-    while (leftovers--) *dst++ = val;
+    avxRasterRGBA32(dst, val, offset, len);
 #elif defined(THORVG_NEON_VECTOR_SUPPORT)
-    uint32_t iterations = len / 4;
-    uint32_t neonFilled = iterations * 4;
-
-    dst += offset;
-    uint32x4_t vectorVal = {val, val, val, val};
-
-    for (uint32_t i = 0; i < iterations; ++i) {
-        vst1q_u32(dst, vectorVal);
-        dst += 4;
-    }
-
-    int32_t leftovers = len - neonFilled;
-    while (leftovers--) *dst++ = val;
+    neonRasterRGBA32(dst, val, offset, len);
 #else
-    dst += offset;
-    while (len--) *dst++ = val;
+    cRasterRGBA32(dst, val, offset, len);
 #endif
 }
 
diff --git a/src/lib/sw_engine/tvgSwRasterAvx.h b/src/lib/sw_engine/tvgSwRasterAvx.h
new file mode 100644 (file)
index 0000000..bbbbc39
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#ifdef THORVG_AVX_VECTOR_SUPPORT
+
+#include <immintrin.h>
+
+
+static inline void avxRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
+{
+    //1. calculate how many iterations we need to cover length
+    uint32_t iterations = len / 8;
+    uint32_t avxFilled = iterations * 8;
+
+    //2. set beginning of the array
+    dst += offset;
+    __m256i_u* avxDst = (__m256i_u*) dst;
+
+    //3. fill octets
+    for (uint32_t i = 0; i < iterations; ++i) {
+        *avxDst = _mm256_set1_epi32(val);
+        avxDst++;
+    }
+
+    //4. fill leftovers (in first step we have to set pointer to place where avx job is done)
+    int32_t leftovers = len - avxFilled;
+    dst += avxFilled;
+
+    while (leftovers--) *dst++ = val;
+}
+
+#endif
\ No newline at end of file
diff --git a/src/lib/sw_engine/tvgSwRasterC.h b/src/lib/sw_engine/tvgSwRasterC.h
new file mode 100644 (file)
index 0000000..c638a19
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+
+static inline void cRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
+{
+    dst += offset;
+    while (len--) *dst++ = val;
+}
+
+
+static inline bool cRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color)
+{
+    auto span = rle->spans;
+    uint32_t src;
+
+    for (uint32_t i = 0; i < rle->size; ++i) {
+        auto dst = &surface->buffer[span->y * surface->stride + span->x];
+
+        if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage);
+        else src = color;
+
+        auto ialpha = 255 - surface->blender.alpha(src);
+
+        for (uint32_t x = 0; x < span->len; ++x)
+            dst[x] = src + ALPHA_BLEND(dst[x], ialpha);
+
+        ++span;
+    }
+    return true;
+}
\ No newline at end of file
diff --git a/src/lib/sw_engine/tvgSwRasterNeon.h b/src/lib/sw_engine/tvgSwRasterNeon.h
new file mode 100644 (file)
index 0000000..7fccbb0
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+#ifdef THORVG_NEON_VECTOR_SUPPORT
+
+#include <arm_neon.h>
+
+
+static inline void neonRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
+{
+    uint32_t iterations = len / 4;
+    uint32_t neonFilled = iterations * 4;
+
+    dst += offset;
+    uint32x4_t vectorVal = {val, val, val, val};
+
+    for (uint32_t i = 0; i < iterations; ++i) {
+        vst1q_u32(dst, vectorVal);
+        dst += 4;
+    }
+
+    int32_t leftovers = len - neonFilled;
+    while (leftovers--) *dst++ = val;
+}
+
+
+static inline bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color)
+{
+    auto span = rle->spans;
+    uint32_t src;
+
+    for (uint32_t i = 0; i < rle->size; ++i) {
+        auto dst = &surface->buffer[span->y * surface->stride + span->x];
+
+        uint8x8_t *vDst = (uint8x8_t*) dst;
+
+        if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage);
+        else src = color;
+        auto ialpha = 255 - surface->blender.alpha(src);
+
+        uint8x8_t vSrc = (uint8x8_t) vdup_n_u32(src);
+        uint8x8_t vIalpha = (uint8x8_t) vdup_n_u32(ialpha);
+
+        uint32_t iterations = span->len / 2;
+        uint32_t left = span->len % 2;
+
+        for (uint32_t x = 0; x < iterations; x+=2) {
+            vDst[x] = vadd_u8(vSrc, ALPHA_BLEND_NEON(vDst[x], vIalpha));
+        }
+
+        if (left) {
+            dst[span->len] = src + ALPHA_BLEND(dst[span->len], ialpha);
+        }
+        ++span;
+    }
+    return true;
+}
+
+
+#endif
\ No newline at end of file