1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
From 38aabb3be87ea68e37f34256c778d07f62680ec6 Mon Sep 17 00:00:00 2001
From: Siarhei Siamashka <siarhei.siamashka@nokia.com>
Date: Thu, 10 Dec 2009 00:51:50 +0200
Subject: [PATCH 1/6] ARM: HACK: added NEON optimizations for fetch/store r5g6b5 scanline
---
pixman/pixman-access.c | 23 ++++++++++++++++++++++-
pixman/pixman-arm-neon-asm.S | 20 ++++++++++++++++++++
pixman/pixman-arm-neon.c | 40 ++++++++++++++++++++++++++++++++++++++++
pixman/pixman-private.h | 5 +++++
4 files changed, 87 insertions(+), 1 deletions(-)
diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index f1ce0ba..b33da29 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -2836,7 +2836,7 @@ typedef struct
store_scanline_ ## format, store_scanline_generic_64 \
}
-static const format_info_t accessors[] =
+static format_info_t accessors[] =
{
/* 32 bpp formats */
FORMAT_INFO (a8r8g8b8),
@@ -2978,6 +2978,27 @@ _pixman_bits_image_setup_accessors (bits_image_t *image)
setup_accessors (image);
}
+void
+_pixman_bits_override_accessors (pixman_format_code_t format,
+ fetch_scanline_t fetch_func,
+ store_scanline_t store_func)
+{
+ format_info_t *info = accessors;
+
+ while (info->format != PIXMAN_null)
+ {
+ if (info->format == format)
+ {
+ if (fetch_func)
+ info->fetch_scanline_32 = fetch_func;
+ if (store_func)
+ info->store_scanline_32 = store_func;
+ return;
+ }
+ info++;
+ }
+}
+
#else
void
diff --git a/pixman/pixman-arm-neon-asm.S b/pixman/pixman-arm-neon-asm.S
index 9f6568f..e1a697e 100644
--- a/pixman/pixman-arm-neon-asm.S
+++ b/pixman/pixman-arm-neon-asm.S
@@ -458,6 +458,16 @@ generate_composite_function \
pixman_composite_src_8888_0565_process_pixblock_tail, \
pixman_composite_src_8888_0565_process_pixblock_tail_head
+generate_composite_function_single_scanline \
+ pixman_store_scanline_r5g6b5_asm_neon, 32, 0, 16, \
+ FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_src_8888_0565_process_pixblock_head, \
+ pixman_composite_src_8888_0565_process_pixblock_tail, \
+ pixman_composite_src_8888_0565_process_pixblock_tail_head
+
/******************************************************************************/
.macro pixman_composite_src_0565_8888_process_pixblock_head
@@ -493,6 +503,16 @@ generate_composite_function \
pixman_composite_src_0565_8888_process_pixblock_tail, \
pixman_composite_src_0565_8888_process_pixblock_tail_head
+generate_composite_function_single_scanline \
+ pixman_fetch_scanline_r5g6b5_asm_neon, 16, 0, 32, \
+ FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_src_0565_8888_process_pixblock_head, \
+ pixman_composite_src_0565_8888_process_pixblock_tail, \
+ pixman_composite_src_0565_8888_process_pixblock_tail_head
+
/******************************************************************************/
.macro pixman_composite_add_8000_8000_process_pixblock_head
diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c
index ece6054..e0d2001 100644
--- a/pixman/pixman-arm-neon.c
+++ b/pixman/pixman-arm-neon.c
@@ -344,6 +344,42 @@ BIND_COMBINE_U (over)
BIND_COMBINE_U (add)
BIND_COMBINE_U (out_reverse)
+void
+pixman_fetch_scanline_r5g6b5_asm_neon (int width,
+ uint32_t *buffer,
+ const uint16_t *pixel);
+void
+pixman_store_scanline_r5g6b5_asm_neon (int width,
+ uint16_t *pixel,
+ const uint32_t *values);
+
+static void
+neon_fetch_scanline_r5g6b5 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint16_t *pixel = (const uint16_t *)bits + x;
+
+ pixman_fetch_scanline_r5g6b5_asm_neon (width, buffer, pixel);
+}
+
+static void
+neon_store_scanline_r5g6b5 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint16_t *pixel = ((uint16_t *) bits) + x;
+
+ pixman_store_scanline_r5g6b5_asm_neon (width, pixel, values);
+}
+
pixman_implementation_t *
_pixman_implementation_create_arm_neon (void)
{
@@ -355,6 +391,10 @@ _pixman_implementation_create_arm_neon (void)
imp->combine_32[PIXMAN_OP_ADD] = neon_combine_add_u;
imp->combine_32[PIXMAN_OP_OUT_REVERSE] = neon_combine_out_reverse_u;
+ _pixman_bits_override_accessors (PIXMAN_r5g6b5,
+ neon_fetch_scanline_r5g6b5,
+ neon_store_scanline_r5g6b5);
+
imp->blt = arm_neon_blt;
imp->fill = arm_neon_fill;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index d85868f..564f8f0 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -206,6 +206,11 @@ void
_pixman_bits_image_setup_accessors (bits_image_t *image);
void
+_pixman_bits_override_accessors (pixman_format_code_t format,
+ fetch_scanline_t fetch_func,
+ store_scanline_t store_func);
+
+void
_pixman_image_get_scanline_generic_64 (pixman_image_t *image,
int x,
int y,
--
1.6.6.1
|