|
1 /* |
|
2 * Render Engine for framebuffer devices |
|
3 * |
|
4 * Copyright (c) 2008 CodeSourcery |
|
5 * |
|
6 * This library is free software; you can redistribute it and/or |
|
7 * modify it under the terms of the GNU Lesser General Public |
|
8 * License as published by the Free Software Foundation; either |
|
9 * version 2 of the License, or (at your option) any later version. |
|
10 * |
|
11 * This library is distributed in the hope that it will be useful, |
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 * Lesser General Public License for more details. |
|
15 * |
|
16 * You should have received a copy of the GNU Lesser General Public |
|
17 * License along with this library; if not, write to the Free Software |
|
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
19 */ |
|
20 |
|
21 /* This file is included from fb_render_def.h |
|
22 At the moment of this inclusion, the following |
|
23 preprocessor parameters are defined: |
|
24 DEST_BPP { 8,15,16,24,32 } |
|
25 FB_SRC_COLOR_ORDER { FB_CO_RGB, FB_CO_BGR } |
|
26 FB_SRC_BYTE_ORDER { FB_LITTLE_ENDIAN, FB_BIG_ENDIAN } |
|
27 FB_SRC_PIXEL_ORDER { FB_LITTLE_ENDIAN, FB_BIG_ENDIAN } |
|
28 */ |
|
29 |
|
30 |
|
31 /* The COPY_PIXEL macro does two things: |
|
32 1) Copies all the bytes involved in the pixel (depending on the DEST_BPP) |
|
33 2) Leaves the 'dest' parameter pointing to the first byte of next pixel. |
|
34 This depends also by the rotation parameter. The rotation modifies the |
|
35 'increment' bytes between pixels. |
|
36 */ |
|
37 |
|
38 #if DEST_BPP == 8 |
|
39 # define COPY_PIXEL(to, from, increment) { *to = from; to += increment; } |
|
40 #elif DEST_BPP == 15 || DEST_BPP == 16 |
|
41 # define COPY_PIXEL(to, from, increment) { *(uint16_t *)to = from; to += increment; } |
|
42 #elif DEST_BPP == 24 |
|
43 # define COPY_PIXEL(to, from, increment) \ |
|
44 { *to = from; to += increment; *to = (from) >> 8; to += increment; *to = (from) >> 16; to += increment; } |
|
45 #elif DEST_BPP == 32 |
|
46 # define COPY_PIXEL(to, from, increment) *(uint32_t *)to = from; to += increment; |
|
47 #else |
|
48 # error unknown bit depth |
|
49 #endif |
|
50 |
|
51 |
|
52 /* Define the infixes of the functions name */ |
|
53 |
|
54 #if FB_SRC_COLOR_ORDER == FB_CO_RGB |
|
55 # define SRC_COLOR_ORDER_INFIX rgb |
|
56 #else |
|
57 # define SRC_COLOR_ORDER_INFIX bgr |
|
58 #endif |
|
59 |
|
60 #if FB_SRC_BYTE_ORDER == FB_LITTLE_ENDIAN |
|
61 # define SRC_BYTE_ORDER_INFIX lb |
|
62 #else |
|
63 # define SRC_BYTE_ORDER_INFIX bb |
|
64 #endif |
|
65 |
|
66 #if FB_SRC_PIXEL_ORDER == FB_LITTLE_ENDIAN |
|
67 # define SRC_PIXEL_ORDER_INFIX lp |
|
68 #else |
|
69 # define SRC_PIXEL_ORDER_INFIX bp |
|
70 #endif |
|
71 |
|
72 #define MAKE_FN_SUFFIX(dest_bpp,color_order,byte_order,pixel_order) \ |
|
73 byte_order##pixel_order##_##color_order##dest_bpp |
|
74 |
|
75 #define FN_SUFFIX glue(SRC_BYTE_ORDER_INFIX,glue(SRC_PIXEL_ORDER_INFIX,glue(_,glue(SRC_COLOR_ORDER_INFIX,DEST_BPP)))) |
|
76 |
|
77 #ifdef WORDS_BIGENDIAN |
|
78 # define FB_DEST_BYTE_ORDER FB_BIG_ENDIAN |
|
79 #else |
|
80 # define FB_DEST_BYTE_ORDER FB_LITTLE_ENDIAN |
|
81 #endif |
|
82 |
|
83 |
|
84 #if FB_SRC_BYTE_ORDER != FB_DEST_BYTE_ORDER |
|
85 # define SWAP_WORDS 1 |
|
86 #endif |
|
87 |
|
88 #if FB_SRC_BYTE_ORDER != FB_SRC_PIXEL_ORDER |
|
89 # define SWAP_PIXELS 1 |
|
90 #endif |
|
91 |
|
92 |
|
93 #define FN_2(x, y) FN(x, y) FN(x+1, y) |
|
94 #define FN_4(x, y) FN_2(x, y) FN_2(x+2, y) |
|
95 #define FN_8(y) FN_4(0, y) FN_4(4, y) |
|
96 |
|
97 |
|
98 static void glue(fb_draw_line1_,FN_SUFFIX)(uint32_t *palette, uint8_t *d, const uint8_t *src, int width, int increment) |
|
99 { |
|
100 uint32_t data; |
|
101 while (width > 0) { |
|
102 data = *(uint32_t *)src; |
|
103 #ifdef SWAP_PIXELS |
|
104 # define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 7 - (x))) & 1], increment); |
|
105 #else |
|
106 # define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x) + y)) & 1], increment); |
|
107 #endif |
|
108 #ifdef SWAP_WORDS |
|
109 FN_8(24) |
|
110 FN_8(16) |
|
111 FN_8(8) |
|
112 FN_8(0) |
|
113 #else |
|
114 FN_8(0) |
|
115 FN_8(8) |
|
116 FN_8(16) |
|
117 FN_8(24) |
|
118 #endif |
|
119 #undef FN |
|
120 width -= 32; |
|
121 src += 4; |
|
122 } |
|
123 } |
|
124 |
|
125 static void glue(fb_draw_line2_,FN_SUFFIX)(uint32_t *palette, uint8_t *d, const uint8_t *src, int width, int increment) |
|
126 { |
|
127 uint32_t data; |
|
128 while (width > 0) { |
|
129 data = *(uint32_t *)src; |
|
130 #ifdef SWAP_PIXELS |
|
131 #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 6 - (x)*2)) & 3], increment); |
|
132 #else |
|
133 #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*2 + y)) & 3], increment); |
|
134 #endif |
|
135 #ifdef SWAP_WORDS |
|
136 FN_4(0, 24) |
|
137 FN_4(0, 16) |
|
138 FN_4(0, 8) |
|
139 FN_4(0, 0) |
|
140 #else |
|
141 FN_4(0, 0) |
|
142 FN_4(0, 8) |
|
143 FN_4(0, 16) |
|
144 FN_4(0, 24) |
|
145 #endif |
|
146 #undef FN |
|
147 width -= 16; |
|
148 src += 4; |
|
149 } |
|
150 } |
|
151 |
|
152 static void glue(fb_draw_line4_,FN_SUFFIX)(uint32_t *palette, uint8_t *d, const uint8_t *src, int width, int increment) |
|
153 { |
|
154 uint32_t data; |
|
155 while (width > 0) { |
|
156 data = *(uint32_t *)src; |
|
157 #ifdef SWAP_PIXELS |
|
158 # define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 4 - (x)*4)) & 0xf], increment); |
|
159 #else |
|
160 # define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*4 + y)) & 0xf], increment); |
|
161 #endif |
|
162 #ifdef SWAP_WORDS |
|
163 FN_2(0, 24) |
|
164 FN_2(0, 16) |
|
165 FN_2(0, 8) |
|
166 FN_2(0, 0) |
|
167 #else |
|
168 FN_2(0, 0) |
|
169 FN_2(0, 8) |
|
170 FN_2(0, 16) |
|
171 FN_2(0, 24) |
|
172 #endif |
|
173 #undef FN |
|
174 width -= 8; |
|
175 src += 4; |
|
176 } |
|
177 } |
|
178 |
|
179 static void glue(fb_draw_line8_,FN_SUFFIX)(uint32_t *palette, uint8_t *d, const uint8_t *src, int width, int increment) |
|
180 { |
|
181 uint32_t data; |
|
182 while (width > 0) { |
|
183 data = *(uint32_t *)src; |
|
184 #define FN(x) COPY_PIXEL(d, palette[(data >> (x)) & 0xff], increment); |
|
185 #ifdef SWAP_WORDS |
|
186 FN(24) |
|
187 FN(16) |
|
188 FN(8) |
|
189 FN(0) |
|
190 #else |
|
191 FN(0) |
|
192 FN(8) |
|
193 FN(16) |
|
194 FN(24) |
|
195 #endif |
|
196 #undef FN |
|
197 width -= 4; |
|
198 src += 4; |
|
199 } |
|
200 } |
|
201 |
|
202 static void glue(fb_draw_line15_,FN_SUFFIX)(uint32_t *palette, uint8_t *d, const uint8_t *src, int width, int increment) |
|
203 { |
|
204 uint32_t data; |
|
205 unsigned int r, g, b; |
|
206 while (width > 0) { |
|
207 data = *(uint32_t *)src; |
|
208 #ifdef SWAP_WORDS |
|
209 data = bswap32(data); |
|
210 #endif |
|
211 #if FB_SRC_COLOR_ORDER == FB_CO_RGB |
|
212 # define LSB r |
|
213 # define MSB b |
|
214 #else |
|
215 # define LSB b |
|
216 # define MSB r |
|
217 #endif |
|
218 |
|
219 /* byte swapping done by bswap32 */ |
|
220 LSB = (data & 0x1f) << 3; |
|
221 data >>= 5; |
|
222 g = (data & 0x1f) << 3; |
|
223 data >>= 5; |
|
224 MSB = (data & 0x1f) << 3; |
|
225 data >>= 6; |
|
226 COPY_PIXEL(d, glue(rgb_to_pixel,DEST_BPP)(r, g, b), increment); |
|
227 |
|
228 LSB = (data & 0x1f) << 3; |
|
229 data >>= 5; |
|
230 g = (data & 0x1f) << 3; |
|
231 data >>= 5; |
|
232 MSB = (data & 0x1f) << 3; |
|
233 COPY_PIXEL(d, glue(rgb_to_pixel,DEST_BPP)(r, g, b), increment); |
|
234 #undef MSB |
|
235 #undef LSB |
|
236 width -= 2; |
|
237 src += 4; |
|
238 } |
|
239 } |
|
240 |
|
241 static void glue(fb_draw_line16_,FN_SUFFIX)(uint32_t *palette, uint8_t *d, const uint8_t *src, int width, int increment) |
|
242 { |
|
243 uint32_t data; |
|
244 unsigned int r, g, b; |
|
245 while (width > 0) { |
|
246 data = *(uint32_t *)src; |
|
247 #ifdef SWAP_WORDS |
|
248 data = bswap32(data); |
|
249 #endif |
|
250 #if FB_SRC_COLOR_ORDER == FB_CO_RGB |
|
251 # define LSB r |
|
252 # define MSB b |
|
253 #else |
|
254 # define LSB b |
|
255 # define MSB r |
|
256 #endif |
|
257 |
|
258 /* byte swapping done by bswap32 */ |
|
259 LSB = (data & 0x1f) << 3; |
|
260 data >>= 5; |
|
261 g = (data & 0x3f) << 2; |
|
262 data >>= 6; |
|
263 MSB = (data & 0x1f) << 3; |
|
264 data >>= 5; |
|
265 COPY_PIXEL(d, glue(rgb_to_pixel,DEST_BPP)(r, g, b), increment); |
|
266 |
|
267 LSB = (data & 0x1f) << 3; |
|
268 data >>= 5; |
|
269 g = (data & 0x3f) << 2; |
|
270 data >>= 6; |
|
271 MSB = (data & 0x1f) << 3; |
|
272 data >>= 5; |
|
273 COPY_PIXEL(d, glue(rgb_to_pixel,DEST_BPP)(r, g, b), increment); |
|
274 #undef MSB |
|
275 #undef LSB |
|
276 width -= 2; |
|
277 src += 4; |
|
278 } |
|
279 } |
|
280 |
|
281 static void glue(fb_draw_line24_,FN_SUFFIX)(uint32_t *palette, uint8_t *d, const uint8_t *src, int width, int increment) |
|
282 { |
|
283 unsigned int r, g, b; |
|
284 while (width > 0) { |
|
285 #if FB_SRC_COLOR_ORDER == FB_CO_RGB |
|
286 # define LSB r |
|
287 # define MSB b |
|
288 #else |
|
289 # define LSB b |
|
290 # define MSB r |
|
291 #endif |
|
292 /* byte swapping not implemented in 24 bpp */ |
|
293 LSB = *src; src++; |
|
294 g = *src; src++; |
|
295 MSB = *src; src++; |
|
296 |
|
297 COPY_PIXEL(d, glue(rgb_to_pixel,DEST_BPP)(r, g, b), increment); |
|
298 #undef MSB |
|
299 #undef LSB |
|
300 width--; |
|
301 } |
|
302 } |
|
303 |
|
304 static void glue(fb_draw_line32_,FN_SUFFIX)(uint32_t *palette, uint8_t *d, const uint8_t *src, int width, int increment) |
|
305 { |
|
306 uint32_t data; |
|
307 unsigned int r, g, b; |
|
308 while (width > 0) { |
|
309 data = *(uint32_t *)src; |
|
310 #if FB_SRC_COLOR_ORDER == FB_CO_RGB |
|
311 # define LSB r |
|
312 # define MSB b |
|
313 #else |
|
314 # define LSB b |
|
315 # define MSB r |
|
316 #endif |
|
317 #ifndef SWAP_WORDS |
|
318 LSB = data & 0xff; |
|
319 g = (data >> 8) & 0xff; |
|
320 MSB = (data >> 16) & 0xff; |
|
321 #else |
|
322 LSB = (data >> 24) & 0xff; |
|
323 g = (data >> 16) & 0xff; |
|
324 MSB = (data >> 8) & 0xff; |
|
325 #endif |
|
326 COPY_PIXEL(d, glue(rgb_to_pixel,DEST_BPP)(r, g, b), increment); |
|
327 #undef MSB |
|
328 #undef LSB |
|
329 width--; |
|
330 src += 4; |
|
331 } |
|
332 } |
|
333 |
|
334 /* Undefine all the local definitions, so they don't collide with the next time |
|
335 this file is included in the tree */ |
|
336 |
|
337 #undef COPY_PIXEL |
|
338 #undef SWAP_PIXELS |
|
339 #undef SWAP_WORDS |
|
340 #undef FN_SUFFIX |
|
341 #undef FB_DEST_BYTE_ORDER |
|
342 #undef SRC_COLOR_ORDER_INFIX |
|
343 #undef SRC_BYTE_ORDER_INFIX |
|
344 #undef SRC_PIXEL_ORDER_INFIX |
|
345 |
|
346 |