Statistics
| Branch: | Revision:

root / hw / pxa2xx_template.h @ 714fa308

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