[Pixman] [PATCH 35/37] armv6: Add fetcher for r5g6b5 bilinear-interpolation scaled images

Ben Avison bavison at riscosopen.org
Tue Sep 9 11:51:43 PDT 2014


This is constrained to support X increments in the positive X direction only.
It also doesn't attempt to support any form of image repeat.

Here are some affine-bench results for a variety of horizontal and vertical
scaling factors.

Before:
    x increment   0.5   0.75  1.0   1.5   2.0
y increment
    0.5            3.0   2.9   2.9   2.9   2.8
    0.75           2.9   2.9   2.9   2.8   2.8
    1.0            2.9   2.9         2.8   2.8
    1.5            2.9   2.9   2.8   2.8   2.7
    2.0            2.9   2.8   2.8   2.8   2.7

After:
    x increment   0.5   0.75  1.0   1.5   2.0
y increment
    0.5           20.2  18.5  19.1  17.6  16.3
    0.75          17.1  15.4  16.0  14.5  13.2
    1.0           20.1  17.1        15.6  13.6
    1.5           11.9  10.3  10.8   9.5   8.4
    2.0            9.9   8.4   8.9   7.7   6.8

Improvement:
    x increment   0.5     0.75    1.0     1.5     2.0
y increment
    0.5           +582.2% +530.7% +554.4% +514.7% +477.1%
    0.75          +481.5% +427.7% +451.2% +410.3% +371.4%
    1.0           +583.9% +486.9%         +453.3% +392.7%
    1.5           +308.1% +258.7% +281.0% +240.5% +208.1%
    2.0           +241.4% +196.9% +217.8% +179.9% +152.4%
---
 pixman/pixman-arm-simd-asm-scaled.S |   14 ++++++++++++
 pixman/pixman-arm-simd.c            |   38 +++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/pixman/pixman-arm-simd-asm-scaled.S b/pixman/pixman-arm-simd-asm-scaled.S
index 81da932..017b6b2 100644
--- a/pixman/pixman-arm-simd-asm-scaled.S
+++ b/pixman/pixman-arm-simd-asm-scaled.S
@@ -219,6 +219,20 @@ generate_bilinear_scaled_cover_functions  32, a8r8g8b8, 3, 3, 3, 3, 3, 3, 3, 3,
 
 generate_bilinear_scaled_cover_functions  32, x8r8g8b8, 3, 3, 3, 3, 3, 3, 3, 3, nop_macro, convert_x888_08080808
 
+.macro convert_0565_08080808  in_ag, rb
+        bic     \rb, \in_ag, #0x07E0               @ 0000000000000000rrrrr000000bbbbb
+        and     \in_ag, \in_ag, #0x07E0            @ 000000000000000000000gggggg00000
+        mov     \rb, \rb, lsl #3                   @ 0000000000000rrrrr000000bbbbb000
+        mov     \in_ag, \in_ag, lsr #3             @ 000000000000000000000000gggggg00
+        orr     \rb, \rb, \rb, lsr #5              @ 0000000000000rrrrrrrrrr0bbbbbbbb
+        orr     \in_ag, \in_ag, lsr #6             @ 000000000000000000000000gggggggg
+        pkhbt   \rb, \rb, \rb, lsl #5              @ 00000000rrrrrrrr-------0bbbbbbbb
+        orr     \in_ag, \in_ag, #0xFF0000          @ 000000001111111100000000gggggggg
+        bic     \rb, \rb, #0xFF00                  @ 00000000rrrrrrrr00000000bbbbbbbb
+.endm
+
+generate_bilinear_scaled_cover_functions  16, r5g6b5, 2, 2, 3, 3, 3, 3, 3, 3, nop_macro, convert_0565_08080808
+
 /******************************************************************************/
 
 .macro pass2_1pixel_internal  t0, t1, b0, b1, tmp, mul, d
diff --git a/pixman/pixman-arm-simd.c b/pixman/pixman-arm-simd.c
index 141fffd..5cfbb8c 100644
--- a/pixman/pixman-arm-simd.c
+++ b/pixman/pixman-arm-simd.c
@@ -430,6 +430,36 @@ static inline void armv6_convert_adjacent_x8r8g8b8 (const void *void_source,
 
 BIND_GET_SCANLINE_BILINEAR_SCALED_COVER(armv6, x8r8g8b8, uint32_t)
 
+static inline void armv6_convert_adjacent_r5g6b5 (const void *void_source,
+                                                  int         x,
+                                                  uint32_t   *lag,
+                                                  uint32_t   *rag,
+                                                  uint32_t   *lrb,
+                                                  uint32_t   *rrb)
+{
+    const uint16_t *source = void_source;
+    uint32_t left  = source[x];
+    uint32_t right = source[x+1];
+    uint32_t r = (left >> 8) & 0xf8;
+    uint32_t g = (left >> 3) & 0xfc;
+    uint32_t b = (left << 3) & 0xf8;
+    r |= r >> 5;
+    g |= g >> 6;
+    b |= b >> 5;
+    *lag = 0xff0000 | g;
+    *lrb = (r << 16) | b;
+    r = (right >> 8) & 0xf8;
+    g = (right >> 3) & 0xfc;
+    b = (right << 3) & 0xf8;
+    r |= r >> 5;
+    g |= g >> 6;
+    b |= b >> 5;
+    *rag = 0xff0000 | g;
+    *rrb = (r << 16) | b;
+}
+
+BIND_GET_SCANLINE_BILINEAR_SCALED_COVER(armv6, r5g6b5, uint16_t)
+
 #define NEAREST_SCALED_COVER_USES_SRC_BUFFER(op, src_format, dst_format) \
     (PIXMAN_OP_##op != PIXMAN_OP_SRC ||                                  \
      (PIXMAN_##dst_format != PIXMAN_a8r8g8b8 &&                          \
@@ -831,6 +861,14 @@ static const pixman_iter_info_t arm_simd_iters[] =
       NULL
     },
 
+    { PIXMAN_r5g6b5,
+      PIXMAN_ARM_BILINEAR_SCALED_COVER_FLAGS,
+      ITER_NARROW | ITER_SRC,
+      armv6_get_scanline_bilinear_init_r5g6b5,
+      armv6_get_scanline_bilinear_scaled_cover_r5g6b5,
+      NULL
+    },
+
     { PIXMAN_a1r5g5b5,
       (FAST_PATH_STANDARD_FLAGS             |
        FAST_PATH_ID_TRANSFORM               |
-- 
1.7.5.4



More information about the Pixman mailing list