]>
Commit | Line | Data |
---|---|---|
a171fe39 AZ |
1 | /* |
2 | * Intel XScale PXA255/270 LCDC emulation. | |
3 | * | |
4 | * Copyright (c) 2006 Openedhand Ltd. | |
5 | * Written by Andrzej Zaborowski <[email protected]> | |
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) | |
5fafdf24 | 17 | #elif BITS == 24 |
a171fe39 AZ |
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 | ||
e2542fe2 | 26 | #ifdef HOST_WORDS_BIGENDIAN |
a171fe39 AZ |
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 | ||
714fa308 | 33 | static void glue(pxa2xx_draw_line2_, BITS)(void *opaque, |
a171fe39 AZ |
34 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
35 | { | |
714fa308 | 36 | uint32_t *palette = opaque; |
a171fe39 AZ |
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 | ||
714fa308 | 58 | static void glue(pxa2xx_draw_line4_, BITS)(void *opaque, |
a171fe39 AZ |
59 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
60 | { | |
714fa308 | 61 | uint32_t *palette = opaque; |
a171fe39 AZ |
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 | ||
714fa308 | 83 | static void glue(pxa2xx_draw_line8_, BITS)(void *opaque, |
a171fe39 AZ |
84 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
85 | { | |
714fa308 | 86 | uint32_t *palette = opaque; |
a171fe39 AZ |
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 | ||
714fa308 | 108 | static void glue(pxa2xx_draw_line16_, BITS)(void *opaque, |
a171fe39 AZ |
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 | ||
714fa308 | 136 | static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque, |
a171fe39 AZ |
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; | |
abbaab5c | 162 | data >>= 5; |
a171fe39 AZ |
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 | ||
714fa308 | 172 | static void glue(pxa2xx_draw_line18_, BITS)(void *opaque, |
a171fe39 AZ |
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 */ | |
714fa308 | 194 | static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque, |
a171fe39 AZ |
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 | ||
714fa308 | 242 | static void glue(pxa2xx_draw_line19_, BITS)(void *opaque, |
a171fe39 AZ |
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 */ | |
714fa308 | 268 | static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque, |
a171fe39 AZ |
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 | ||
714fa308 | 332 | static void glue(pxa2xx_draw_line24_, BITS)(void *opaque, |
a171fe39 AZ |
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 | ||
714fa308 | 353 | static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque, |
a171fe39 AZ |
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 | ||
714fa308 | 378 | static void glue(pxa2xx_draw_line25_, BITS)(void *opaque, |
a171fe39 AZ |
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 | { | |
b9d38e95 | 406 | [0 ... 0xf] = NULL, |
a171fe39 AZ |
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 | { | |
b9d38e95 | 419 | [0 ... 0xf] = NULL, |
a171fe39 AZ |
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 |