find -type f | xargs sed -i 's/[\t ]$//g' # on most files
[qemu] / hw / pxa2xx_template.h
1 /*
2  * Intel XScale PXA255/270 LCDC emulation.
3  *
4  * Copyright (c) 2006 Openedhand Ltd.
5  * Written by Andrzej Zaborowski <balrog@zabor.org>
6  *
7  * This code is licensed under the GPLv2.
8  *
9  * Framebuffer format conversion routines.
10  */
11
12 # define SKIP_PIXEL(to)         to += deststep
13 #if BITS == 8
14 # define COPY_PIXEL(to, from)   *to = from; SKIP_PIXEL(to)
15 #elif BITS == 15 || BITS == 16
16 # define COPY_PIXEL(to, from)   *(uint16_t *) to = from; SKIP_PIXEL(to)
17 #elif BITS == 24
18 # define COPY_PIXEL(to, from)   \
19         *(uint16_t *) to = from; *(to + 2) = (from) >> 16; SKIP_PIXEL(to)
20 #elif BITS == 32
21 # define COPY_PIXEL(to, from)   *(uint32_t *) to = from; SKIP_PIXEL(to)
22 #else
23 # error unknown bit depth
24 #endif
25
26 #ifdef WORDS_BIGENDIAN
27 # define SWAP_WORDS     1
28 #endif
29
30 #define FN_2(x)         FN(x + 1) FN(x)
31 #define FN_4(x)         FN_2(x + 2) FN_2(x)
32
33 static void glue(pxa2xx_draw_line2_, BITS)(uint32_t *palette,
34                 uint8_t *dest, const uint8_t *src, int width, int deststep)
35 {
36     uint32_t data;
37     while (width > 0) {
38         data = *(uint32_t *) src;
39 #define FN(x)           COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
40 #ifdef SWAP_WORDS
41         FN_4(12)
42         FN_4(8)
43         FN_4(4)
44         FN_4(0)
45 #else
46         FN_4(0)
47         FN_4(4)
48         FN_4(8)
49         FN_4(12)
50 #endif
51 #undef FN
52         width -= 16;
53         src += 4;
54     }
55 }
56
57 static void glue(pxa2xx_draw_line4_, BITS)(uint32_t *palette,
58                 uint8_t *dest, const uint8_t *src, int width, int deststep)
59 {
60     uint32_t data;
61     while (width > 0) {
62         data = *(uint32_t *) src;
63 #define FN(x)           COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
64 #ifdef SWAP_WORDS
65         FN_2(6)
66         FN_2(4)
67         FN_2(2)
68         FN_2(0)
69 #else
70         FN_2(0)
71         FN_2(2)
72         FN_2(4)
73         FN_2(6)
74 #endif
75 #undef FN
76         width -= 8;
77         src += 4;
78     }
79 }
80
81 static void glue(pxa2xx_draw_line8_, BITS)(uint32_t *palette,
82                 uint8_t *dest, const uint8_t *src, int width, int deststep)
83 {
84     uint32_t data;
85     while (width > 0) {
86         data = *(uint32_t *) src;
87 #define FN(x)           COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
88 #ifdef SWAP_WORDS
89         FN(24)
90         FN(16)
91         FN(8)
92         FN(0)
93 #else
94         FN(0)
95         FN(8)
96         FN(16)
97         FN(24)
98 #endif
99 #undef FN
100         width -= 4;
101         src += 4;
102     }
103 }
104
105 static void glue(pxa2xx_draw_line16_, BITS)(uint32_t *palette,
106                 uint8_t *dest, const uint8_t *src, int width, int deststep)
107 {
108     uint32_t data;
109     unsigned int r, g, b;
110     while (width > 0) {
111         data = *(uint32_t *) src;
112 #ifdef SWAP_WORDS
113         data = bswap32(data);
114 #endif
115         b = (data & 0x1f) << 3;
116         data >>= 5;
117         g = (data & 0x3f) << 2;
118         data >>= 6;
119         r = (data & 0x1f) << 3;
120         data >>= 5;
121         COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
122         b = (data & 0x1f) << 3;
123         data >>= 5;
124         g = (data & 0x3f) << 2;
125         data >>= 6;
126         r = (data & 0x1f) << 3;
127         COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
128         width -= 2;
129         src += 4;
130     }
131 }
132
133 static void glue(pxa2xx_draw_line16t_, BITS)(uint32_t *palette,
134                 uint8_t *dest, const uint8_t *src, int width, int deststep)
135 {
136     uint32_t data;
137     unsigned int r, g, b;
138     while (width > 0) {
139         data = *(uint32_t *) src;
140 #ifdef SWAP_WORDS
141         data = bswap32(data);
142 #endif
143         b = (data & 0x1f) << 3;
144         data >>= 5;
145         g = (data & 0x1f) << 3;
146         data >>= 5;
147         r = (data & 0x1f) << 3;
148         data >>= 5;
149         if (data & 1)
150             SKIP_PIXEL(dest);
151         else
152             COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
153         data >>= 1;
154         b = (data & 0x1f) << 3;
155         data >>= 5;
156         g = (data & 0x1f) << 3;
157         data >>= 5;
158         r = (data & 0x1f) << 3;
159         if (data & 1)
160             SKIP_PIXEL(dest);
161         else
162             COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
163         width -= 2;
164         src += 4;
165     }
166 }
167
168 static void glue(pxa2xx_draw_line18_, BITS)(uint32_t *palette,
169                 uint8_t *dest, const uint8_t *src, int width, int deststep)
170 {
171     uint32_t data;
172     unsigned int r, g, b;
173     while (width > 0) {
174         data = *(uint32_t *) src;
175 #ifdef SWAP_WORDS
176         data = bswap32(data);
177 #endif
178         b = (data & 0x3f) << 2;
179         data >>= 6;
180         g = (data & 0x3f) << 2;
181         data >>= 6;
182         r = (data & 0x3f) << 2;
183         COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
184         width -= 1;
185         src += 4;
186     }
187 }
188
189 /* The wicked packed format */
190 static void glue(pxa2xx_draw_line18p_, BITS)(uint32_t *palette,
191                 uint8_t *dest, const uint8_t *src, int width, int deststep)
192 {
193     uint32_t data[3];
194     unsigned int r, g, b;
195     while (width > 0) {
196         data[0] = *(uint32_t *) src;
197         src += 4;
198         data[1] = *(uint32_t *) src;
199         src += 4;
200         data[2] = *(uint32_t *) src;
201         src += 4;
202 #ifdef SWAP_WORDS
203         data[0] = bswap32(data[0]);
204         data[1] = bswap32(data[1]);
205         data[2] = bswap32(data[2]);
206 #endif
207         b = (data[0] & 0x3f) << 2;
208         data[0] >>= 6;
209         g = (data[0] & 0x3f) << 2;
210         data[0] >>= 6;
211         r = (data[0] & 0x3f) << 2;
212         data[0] >>= 12;
213         COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
214         b = (data[0] & 0x3f) << 2;
215         data[0] >>= 6;
216         g = ((data[1] & 0xf) << 4) | (data[0] << 2);
217         data[1] >>= 4;
218         r = (data[1] & 0x3f) << 2;
219         data[1] >>= 12;
220         COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
221         b = (data[1] & 0x3f) << 2;
222         data[1] >>= 6;
223         g = (data[1] & 0x3f) << 2;
224         data[1] >>= 6;
225         r = ((data[2] & 0x3) << 6) | (data[1] << 2);
226         data[2] >>= 8;
227         COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
228         b = (data[2] & 0x3f) << 2;
229         data[2] >>= 6;
230         g = (data[2] & 0x3f) << 2;
231         data[2] >>= 6;
232         r = data[2] << 2;
233         COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
234         width -= 4;
235     }
236 }
237
238 static void glue(pxa2xx_draw_line19_, BITS)(uint32_t *palette,
239                 uint8_t *dest, const uint8_t *src, int width, int deststep)
240 {
241     uint32_t data;
242     unsigned int r, g, b;
243     while (width > 0) {
244         data = *(uint32_t *) src;
245 #ifdef SWAP_WORDS
246         data = bswap32(data);
247 #endif
248         b = (data & 0x3f) << 2;
249         data >>= 6;
250         g = (data & 0x3f) << 2;
251         data >>= 6;
252         r = (data & 0x3f) << 2;
253         data >>= 6;
254         if (data & 1)
255             SKIP_PIXEL(dest);
256         else
257             COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
258         width -= 1;
259         src += 4;
260     }
261 }
262
263 /* The wicked packed format */
264 static void glue(pxa2xx_draw_line19p_, BITS)(uint32_t *palette,
265                 uint8_t *dest, const uint8_t *src, int width, int deststep)
266 {
267     uint32_t data[3];
268     unsigned int r, g, b;
269     while (width > 0) {
270         data[0] = *(uint32_t *) src;
271         src += 4;
272         data[1] = *(uint32_t *) src;
273         src += 4;
274         data[2] = *(uint32_t *) src;
275         src += 4;
276 # ifdef SWAP_WORDS
277         data[0] = bswap32(data[0]);
278         data[1] = bswap32(data[1]);
279         data[2] = bswap32(data[2]);
280 # endif
281         b = (data[0] & 0x3f) << 2;
282         data[0] >>= 6;
283         g = (data[0] & 0x3f) << 2;
284         data[0] >>= 6;
285         r = (data[0] & 0x3f) << 2;
286         data[0] >>= 6;
287         if (data[0] & 1)
288             SKIP_PIXEL(dest);
289         else
290             COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
291         data[0] >>= 6;
292         b = (data[0] & 0x3f) << 2;
293         data[0] >>= 6;
294         g = ((data[1] & 0xf) << 4) | (data[0] << 2);
295         data[1] >>= 4;
296         r = (data[1] & 0x3f) << 2;
297         data[1] >>= 6;
298         if (data[1] & 1)
299             SKIP_PIXEL(dest);
300         else
301             COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
302         data[1] >>= 6;
303         b = (data[1] & 0x3f) << 2;
304         data[1] >>= 6;
305         g = (data[1] & 0x3f) << 2;
306         data[1] >>= 6;
307         r = ((data[2] & 0x3) << 6) | (data[1] << 2);
308         data[2] >>= 2;
309         if (data[2] & 1)
310             SKIP_PIXEL(dest);
311         else
312             COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
313         data[2] >>= 6;
314         b = (data[2] & 0x3f) << 2;
315         data[2] >>= 6;
316         g = (data[2] & 0x3f) << 2;
317         data[2] >>= 6;
318         r = data[2] << 2;
319         data[2] >>= 6;
320         if (data[2] & 1)
321             SKIP_PIXEL(dest);
322         else
323             COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
324         width -= 4;
325     }
326 }
327
328 static void glue(pxa2xx_draw_line24_, BITS)(uint32_t *palette,
329                 uint8_t *dest, const uint8_t *src, int width, int deststep)
330 {
331     uint32_t data;
332     unsigned int r, g, b;
333     while (width > 0) {
334         data = *(uint32_t *) src;
335 #ifdef SWAP_WORDS
336         data = bswap32(data);
337 #endif
338         b = data & 0xff;
339         data >>= 8;
340         g = data & 0xff;
341         data >>= 8;
342         r = data & 0xff;
343         COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
344         width -= 1;
345         src += 4;
346     }
347 }
348
349 static void glue(pxa2xx_draw_line24t_, BITS)(uint32_t *palette,
350                 uint8_t *dest, const uint8_t *src, int width, int deststep)
351 {
352     uint32_t data;
353     unsigned int r, g, b;
354     while (width > 0) {
355         data = *(uint32_t *) src;
356 #ifdef SWAP_WORDS
357         data = bswap32(data);
358 #endif
359         b = (data & 0x7f) << 1;
360         data >>= 7;
361         g = data & 0xff;
362         data >>= 8;
363         r = data & 0xff;
364         data >>= 8;
365         if (data & 1)
366             SKIP_PIXEL(dest);
367         else
368             COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
369         width -= 1;
370         src += 4;
371     }
372 }
373
374 static void glue(pxa2xx_draw_line25_, BITS)(uint32_t *palette,
375                 uint8_t *dest, const uint8_t *src, int width, int deststep)
376 {
377     uint32_t data;
378     unsigned int r, g, b;
379     while (width > 0) {
380         data = *(uint32_t *) src;
381 #ifdef SWAP_WORDS
382         data = bswap32(data);
383 #endif
384         b = data & 0xff;
385         data >>= 8;
386         g = data & 0xff;
387         data >>= 8;
388         r = data & 0xff;
389         data >>= 8;
390         if (data & 1)
391             SKIP_PIXEL(dest);
392         else
393             COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
394         width -= 1;
395         src += 4;
396     }
397 }
398
399 /* Overlay planes disabled, no transparency */
400 static drawfn glue(pxa2xx_draw_fn_, BITS)[16] =
401 {
402     [0 ... 0xf]       = 0,
403     [pxa_lcdc_2bpp]   = glue(pxa2xx_draw_line2_, BITS),
404     [pxa_lcdc_4bpp]   = glue(pxa2xx_draw_line4_, BITS),
405     [pxa_lcdc_8bpp]   = glue(pxa2xx_draw_line8_, BITS),
406     [pxa_lcdc_16bpp]  = glue(pxa2xx_draw_line16_, BITS),
407     [pxa_lcdc_18bpp]  = glue(pxa2xx_draw_line18_, BITS),
408     [pxa_lcdc_18pbpp] = glue(pxa2xx_draw_line18p_, BITS),
409     [pxa_lcdc_24bpp]  = glue(pxa2xx_draw_line24_, BITS),
410 };
411
412 /* Overlay planes enabled, transparency used */
413 static drawfn glue(glue(pxa2xx_draw_fn_, BITS), t)[16] =
414 {
415     [0 ... 0xf]       = 0,
416     [pxa_lcdc_4bpp]   = glue(pxa2xx_draw_line4_, BITS),
417     [pxa_lcdc_8bpp]   = glue(pxa2xx_draw_line8_, BITS),
418     [pxa_lcdc_16bpp]  = glue(pxa2xx_draw_line16t_, BITS),
419     [pxa_lcdc_19bpp]  = glue(pxa2xx_draw_line19_, BITS),
420     [pxa_lcdc_19pbpp] = glue(pxa2xx_draw_line19p_, BITS),
421     [pxa_lcdc_24bpp]  = glue(pxa2xx_draw_line24t_, BITS),
422     [pxa_lcdc_25bpp]  = glue(pxa2xx_draw_line25_, BITS),
423 };
424
425 #undef BITS
426 #undef COPY_PIXEL
427 #undef SKIP_PIXEL
428
429 #ifdef SWAP_WORDS
430 # undef SWAP_WORDS
431 #endif