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