|
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 data >>= 5; |
|
160 if (data & 1) |
|
161 SKIP_PIXEL(dest); |
|
162 else |
|
163 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
164 width -= 2; |
|
165 src += 4; |
|
166 } |
|
167 } |
|
168 |
|
169 static void glue(pxa2xx_draw_line18_, BITS)(uint32_t *palette, |
|
170 uint8_t *dest, const uint8_t *src, int width, int deststep) |
|
171 { |
|
172 uint32_t data; |
|
173 unsigned int r, g, b; |
|
174 while (width > 0) { |
|
175 data = *(uint32_t *) src; |
|
176 #ifdef SWAP_WORDS |
|
177 data = bswap32(data); |
|
178 #endif |
|
179 b = (data & 0x3f) << 2; |
|
180 data >>= 6; |
|
181 g = (data & 0x3f) << 2; |
|
182 data >>= 6; |
|
183 r = (data & 0x3f) << 2; |
|
184 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
185 width -= 1; |
|
186 src += 4; |
|
187 } |
|
188 } |
|
189 |
|
190 /* The wicked packed format */ |
|
191 static void glue(pxa2xx_draw_line18p_, BITS)(uint32_t *palette, |
|
192 uint8_t *dest, const uint8_t *src, int width, int deststep) |
|
193 { |
|
194 uint32_t data[3]; |
|
195 unsigned int r, g, b; |
|
196 while (width > 0) { |
|
197 data[0] = *(uint32_t *) src; |
|
198 src += 4; |
|
199 data[1] = *(uint32_t *) src; |
|
200 src += 4; |
|
201 data[2] = *(uint32_t *) src; |
|
202 src += 4; |
|
203 #ifdef SWAP_WORDS |
|
204 data[0] = bswap32(data[0]); |
|
205 data[1] = bswap32(data[1]); |
|
206 data[2] = bswap32(data[2]); |
|
207 #endif |
|
208 b = (data[0] & 0x3f) << 2; |
|
209 data[0] >>= 6; |
|
210 g = (data[0] & 0x3f) << 2; |
|
211 data[0] >>= 6; |
|
212 r = (data[0] & 0x3f) << 2; |
|
213 data[0] >>= 12; |
|
214 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
215 b = (data[0] & 0x3f) << 2; |
|
216 data[0] >>= 6; |
|
217 g = ((data[1] & 0xf) << 4) | (data[0] << 2); |
|
218 data[1] >>= 4; |
|
219 r = (data[1] & 0x3f) << 2; |
|
220 data[1] >>= 12; |
|
221 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
222 b = (data[1] & 0x3f) << 2; |
|
223 data[1] >>= 6; |
|
224 g = (data[1] & 0x3f) << 2; |
|
225 data[1] >>= 6; |
|
226 r = ((data[2] & 0x3) << 6) | (data[1] << 2); |
|
227 data[2] >>= 8; |
|
228 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
229 b = (data[2] & 0x3f) << 2; |
|
230 data[2] >>= 6; |
|
231 g = (data[2] & 0x3f) << 2; |
|
232 data[2] >>= 6; |
|
233 r = data[2] << 2; |
|
234 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
235 width -= 4; |
|
236 } |
|
237 } |
|
238 |
|
239 static void glue(pxa2xx_draw_line19_, BITS)(uint32_t *palette, |
|
240 uint8_t *dest, const uint8_t *src, int width, int deststep) |
|
241 { |
|
242 uint32_t data; |
|
243 unsigned int r, g, b; |
|
244 while (width > 0) { |
|
245 data = *(uint32_t *) src; |
|
246 #ifdef SWAP_WORDS |
|
247 data = bswap32(data); |
|
248 #endif |
|
249 b = (data & 0x3f) << 2; |
|
250 data >>= 6; |
|
251 g = (data & 0x3f) << 2; |
|
252 data >>= 6; |
|
253 r = (data & 0x3f) << 2; |
|
254 data >>= 6; |
|
255 if (data & 1) |
|
256 SKIP_PIXEL(dest); |
|
257 else |
|
258 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
259 width -= 1; |
|
260 src += 4; |
|
261 } |
|
262 } |
|
263 |
|
264 /* The wicked packed format */ |
|
265 static void glue(pxa2xx_draw_line19p_, BITS)(uint32_t *palette, |
|
266 uint8_t *dest, const uint8_t *src, int width, int deststep) |
|
267 { |
|
268 uint32_t data[3]; |
|
269 unsigned int r, g, b; |
|
270 while (width > 0) { |
|
271 data[0] = *(uint32_t *) src; |
|
272 src += 4; |
|
273 data[1] = *(uint32_t *) src; |
|
274 src += 4; |
|
275 data[2] = *(uint32_t *) src; |
|
276 src += 4; |
|
277 # ifdef SWAP_WORDS |
|
278 data[0] = bswap32(data[0]); |
|
279 data[1] = bswap32(data[1]); |
|
280 data[2] = bswap32(data[2]); |
|
281 # endif |
|
282 b = (data[0] & 0x3f) << 2; |
|
283 data[0] >>= 6; |
|
284 g = (data[0] & 0x3f) << 2; |
|
285 data[0] >>= 6; |
|
286 r = (data[0] & 0x3f) << 2; |
|
287 data[0] >>= 6; |
|
288 if (data[0] & 1) |
|
289 SKIP_PIXEL(dest); |
|
290 else |
|
291 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
292 data[0] >>= 6; |
|
293 b = (data[0] & 0x3f) << 2; |
|
294 data[0] >>= 6; |
|
295 g = ((data[1] & 0xf) << 4) | (data[0] << 2); |
|
296 data[1] >>= 4; |
|
297 r = (data[1] & 0x3f) << 2; |
|
298 data[1] >>= 6; |
|
299 if (data[1] & 1) |
|
300 SKIP_PIXEL(dest); |
|
301 else |
|
302 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
303 data[1] >>= 6; |
|
304 b = (data[1] & 0x3f) << 2; |
|
305 data[1] >>= 6; |
|
306 g = (data[1] & 0x3f) << 2; |
|
307 data[1] >>= 6; |
|
308 r = ((data[2] & 0x3) << 6) | (data[1] << 2); |
|
309 data[2] >>= 2; |
|
310 if (data[2] & 1) |
|
311 SKIP_PIXEL(dest); |
|
312 else |
|
313 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
314 data[2] >>= 6; |
|
315 b = (data[2] & 0x3f) << 2; |
|
316 data[2] >>= 6; |
|
317 g = (data[2] & 0x3f) << 2; |
|
318 data[2] >>= 6; |
|
319 r = data[2] << 2; |
|
320 data[2] >>= 6; |
|
321 if (data[2] & 1) |
|
322 SKIP_PIXEL(dest); |
|
323 else |
|
324 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
325 width -= 4; |
|
326 } |
|
327 } |
|
328 |
|
329 static void glue(pxa2xx_draw_line24_, BITS)(uint32_t *palette, |
|
330 uint8_t *dest, const uint8_t *src, int width, int deststep) |
|
331 { |
|
332 uint32_t data; |
|
333 unsigned int r, g, b; |
|
334 while (width > 0) { |
|
335 data = *(uint32_t *) src; |
|
336 #ifdef SWAP_WORDS |
|
337 data = bswap32(data); |
|
338 #endif |
|
339 b = data & 0xff; |
|
340 data >>= 8; |
|
341 g = data & 0xff; |
|
342 data >>= 8; |
|
343 r = data & 0xff; |
|
344 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
345 width -= 1; |
|
346 src += 4; |
|
347 } |
|
348 } |
|
349 |
|
350 static void glue(pxa2xx_draw_line24t_, BITS)(uint32_t *palette, |
|
351 uint8_t *dest, const uint8_t *src, int width, int deststep) |
|
352 { |
|
353 uint32_t data; |
|
354 unsigned int r, g, b; |
|
355 while (width > 0) { |
|
356 data = *(uint32_t *) src; |
|
357 #ifdef SWAP_WORDS |
|
358 data = bswap32(data); |
|
359 #endif |
|
360 b = (data & 0x7f) << 1; |
|
361 data >>= 7; |
|
362 g = data & 0xff; |
|
363 data >>= 8; |
|
364 r = data & 0xff; |
|
365 data >>= 8; |
|
366 if (data & 1) |
|
367 SKIP_PIXEL(dest); |
|
368 else |
|
369 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
370 width -= 1; |
|
371 src += 4; |
|
372 } |
|
373 } |
|
374 |
|
375 static void glue(pxa2xx_draw_line25_, BITS)(uint32_t *palette, |
|
376 uint8_t *dest, const uint8_t *src, int width, int deststep) |
|
377 { |
|
378 uint32_t data; |
|
379 unsigned int r, g, b; |
|
380 while (width > 0) { |
|
381 data = *(uint32_t *) src; |
|
382 #ifdef SWAP_WORDS |
|
383 data = bswap32(data); |
|
384 #endif |
|
385 b = data & 0xff; |
|
386 data >>= 8; |
|
387 g = data & 0xff; |
|
388 data >>= 8; |
|
389 r = data & 0xff; |
|
390 data >>= 8; |
|
391 if (data & 1) |
|
392 SKIP_PIXEL(dest); |
|
393 else |
|
394 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); |
|
395 width -= 1; |
|
396 src += 4; |
|
397 } |
|
398 } |
|
399 |
|
400 /* Overlay planes disabled, no transparency */ |
|
401 static drawfn glue(pxa2xx_draw_fn_, BITS)[16] = |
|
402 { |
|
403 [0 ... 0xf] = 0, |
|
404 [pxa_lcdc_2bpp] = glue(pxa2xx_draw_line2_, BITS), |
|
405 [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS), |
|
406 [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS), |
|
407 [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16_, BITS), |
|
408 [pxa_lcdc_18bpp] = glue(pxa2xx_draw_line18_, BITS), |
|
409 [pxa_lcdc_18pbpp] = glue(pxa2xx_draw_line18p_, BITS), |
|
410 [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24_, BITS), |
|
411 }; |
|
412 |
|
413 /* Overlay planes enabled, transparency used */ |
|
414 static drawfn glue(glue(pxa2xx_draw_fn_, BITS), t)[16] = |
|
415 { |
|
416 [0 ... 0xf] = 0, |
|
417 [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS), |
|
418 [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS), |
|
419 [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16t_, BITS), |
|
420 [pxa_lcdc_19bpp] = glue(pxa2xx_draw_line19_, BITS), |
|
421 [pxa_lcdc_19pbpp] = glue(pxa2xx_draw_line19p_, BITS), |
|
422 [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24t_, BITS), |
|
423 [pxa_lcdc_25bpp] = glue(pxa2xx_draw_line25_, BITS), |
|
424 }; |
|
425 |
|
426 #undef BITS |
|
427 #undef COPY_PIXEL |
|
428 #undef SKIP_PIXEL |
|
429 |
|
430 #ifdef SWAP_WORDS |
|
431 # undef SWAP_WORDS |
|
432 #endif |