Statistics
| Branch: | Revision:

root / hw / display / pxa2xx_template.h @ 2cdaca90

History | View | Annotate | Download (11.6 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)  do { *to = from; SKIP_PIXEL(to); } while (0)
15
#elif BITS == 15 || BITS == 16
16
# define COPY_PIXEL(to, from)    \
17
    do {                         \
18
        *(uint16_t *) to = from; \
19
        SKIP_PIXEL(to);          \
20
    } while (0)
21
#elif BITS == 24
22
# define COPY_PIXEL(to, from)     \
23
    do {                          \
24
        *(uint16_t *) to = from;  \
25
        *(to + 2) = (from) >> 16; \
26
        SKIP_PIXEL(to);           \
27
    } while (0)
28
#elif BITS == 32
29
# define COPY_PIXEL(to, from)    \
30
    do {                         \
31
        *(uint32_t *) to = from; \
32
        SKIP_PIXEL(to);          \
33
    } while (0)
34
#else
35
# error unknown bit depth
36
#endif
37

    
38
#ifdef HOST_WORDS_BIGENDIAN
39
# define SWAP_WORDS        1
40
#endif
41

    
42
#define FN_2(x)                FN(x + 1) FN(x)
43
#define FN_4(x)                FN_2(x + 2) FN_2(x)
44

    
45
static void glue(pxa2xx_draw_line2_, BITS)(void *opaque,
46
                uint8_t *dest, const uint8_t *src, int width, int deststep)
47
{
48
    uint32_t *palette = opaque;
49
    uint32_t data;
50
    while (width > 0) {
51
        data = *(uint32_t *) src;
52
#define FN(x)                COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
53
#ifdef SWAP_WORDS
54
        FN_4(12)
55
        FN_4(8)
56
        FN_4(4)
57
        FN_4(0)
58
#else
59
        FN_4(0)
60
        FN_4(4)
61
        FN_4(8)
62
        FN_4(12)
63
#endif
64
#undef FN
65
        width -= 16;
66
        src += 4;
67
    }
68
}
69

    
70
static void glue(pxa2xx_draw_line4_, BITS)(void *opaque,
71
                uint8_t *dest, const uint8_t *src, int width, int deststep)
72
{
73
    uint32_t *palette = opaque;
74
    uint32_t data;
75
    while (width > 0) {
76
        data = *(uint32_t *) src;
77
#define FN(x)                COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
78
#ifdef SWAP_WORDS
79
        FN_2(6)
80
        FN_2(4)
81
        FN_2(2)
82
        FN_2(0)
83
#else
84
        FN_2(0)
85
        FN_2(2)
86
        FN_2(4)
87
        FN_2(6)
88
#endif
89
#undef FN
90
        width -= 8;
91
        src += 4;
92
    }
93
}
94

    
95
static void glue(pxa2xx_draw_line8_, BITS)(void *opaque,
96
                uint8_t *dest, const uint8_t *src, int width, int deststep)
97
{
98
    uint32_t *palette = opaque;
99
    uint32_t data;
100
    while (width > 0) {
101
        data = *(uint32_t *) src;
102
#define FN(x)                COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
103
#ifdef SWAP_WORDS
104
        FN(24)
105
        FN(16)
106
        FN(8)
107
        FN(0)
108
#else
109
        FN(0)
110
        FN(8)
111
        FN(16)
112
        FN(24)
113
#endif
114
#undef FN
115
        width -= 4;
116
        src += 4;
117
    }
118
}
119

    
120
static void glue(pxa2xx_draw_line16_, BITS)(void *opaque,
121
                uint8_t *dest, const uint8_t *src, int width, int deststep)
122
{
123
    uint32_t data;
124
    unsigned int r, g, b;
125
    while (width > 0) {
126
        data = *(uint32_t *) src;
127
#ifdef SWAP_WORDS
128
        data = bswap32(data);
129
#endif
130
        b = (data & 0x1f) << 3;
131
        data >>= 5;
132
        g = (data & 0x3f) << 2;
133
        data >>= 6;
134
        r = (data & 0x1f) << 3;
135
        data >>= 5;
136
        COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
137
        b = (data & 0x1f) << 3;
138
        data >>= 5;
139
        g = (data & 0x3f) << 2;
140
        data >>= 6;
141
        r = (data & 0x1f) << 3;
142
        COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
143
        width -= 2;
144
        src += 4;
145
    }
146
}
147

    
148
static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
149
                uint8_t *dest, const uint8_t *src, int width, int deststep)
150
{
151
    uint32_t data;
152
    unsigned int r, g, b;
153
    while (width > 0) {
154
        data = *(uint32_t *) src;
155
#ifdef SWAP_WORDS
156
        data = bswap32(data);
157
#endif
158
        b = (data & 0x1f) << 3;
159
        data >>= 5;
160
        g = (data & 0x1f) << 3;
161
        data >>= 5;
162
        r = (data & 0x1f) << 3;
163
        data >>= 5;
164
        if (data & 1)
165
            SKIP_PIXEL(dest);
166
        else
167
            COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
168
        data >>= 1;
169
        b = (data & 0x1f) << 3;
170
        data >>= 5;
171
        g = (data & 0x1f) << 3;
172
        data >>= 5;
173
        r = (data & 0x1f) << 3;
174
        data >>= 5;
175
        if (data & 1)
176
            SKIP_PIXEL(dest);
177
        else
178
            COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
179
        width -= 2;
180
        src += 4;
181
    }
182
}
183

    
184
static void glue(pxa2xx_draw_line18_, BITS)(void *opaque,
185
                uint8_t *dest, const uint8_t *src, int width, int deststep)
186
{
187
    uint32_t data;
188
    unsigned int r, g, b;
189
    while (width > 0) {
190
        data = *(uint32_t *) src;
191
#ifdef SWAP_WORDS
192
        data = bswap32(data);
193
#endif
194
        b = (data & 0x3f) << 2;
195
        data >>= 6;
196
        g = (data & 0x3f) << 2;
197
        data >>= 6;
198
        r = (data & 0x3f) << 2;
199
        COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
200
        width -= 1;
201
        src += 4;
202
    }
203
}
204

    
205
/* The wicked packed format */
206
static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque,
207
                uint8_t *dest, const uint8_t *src, int width, int deststep)
208
{
209
    uint32_t data[3];
210
    unsigned int r, g, b;
211
    while (width > 0) {
212
        data[0] = *(uint32_t *) src;
213
        src += 4;
214
        data[1] = *(uint32_t *) src;
215
        src += 4;
216
        data[2] = *(uint32_t *) src;
217
        src += 4;
218
#ifdef SWAP_WORDS
219
        data[0] = bswap32(data[0]);
220
        data[1] = bswap32(data[1]);
221
        data[2] = bswap32(data[2]);
222
#endif
223
        b = (data[0] & 0x3f) << 2;
224
        data[0] >>= 6;
225
        g = (data[0] & 0x3f) << 2;
226
        data[0] >>= 6;
227
        r = (data[0] & 0x3f) << 2;
228
        data[0] >>= 12;
229
        COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
230
        b = (data[0] & 0x3f) << 2;
231
        data[0] >>= 6;
232
        g = ((data[1] & 0xf) << 4) | (data[0] << 2);
233
        data[1] >>= 4;
234
        r = (data[1] & 0x3f) << 2;
235
        data[1] >>= 12;
236
        COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
237
        b = (data[1] & 0x3f) << 2;
238
        data[1] >>= 6;
239
        g = (data[1] & 0x3f) << 2;
240
        data[1] >>= 6;
241
        r = ((data[2] & 0x3) << 6) | (data[1] << 2);
242
        data[2] >>= 8;
243
        COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
244
        b = (data[2] & 0x3f) << 2;
245
        data[2] >>= 6;
246
        g = (data[2] & 0x3f) << 2;
247
        data[2] >>= 6;
248
        r = data[2] << 2;
249
        COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
250
        width -= 4;
251
    }
252
}
253

    
254
static void glue(pxa2xx_draw_line19_, BITS)(void *opaque,
255
                uint8_t *dest, const uint8_t *src, int width, int deststep)
256
{
257
    uint32_t data;
258
    unsigned int r, g, b;
259
    while (width > 0) {
260
        data = *(uint32_t *) src;
261
#ifdef SWAP_WORDS
262
        data = bswap32(data);
263
#endif
264
        b = (data & 0x3f) << 2;
265
        data >>= 6;
266
        g = (data & 0x3f) << 2;
267
        data >>= 6;
268
        r = (data & 0x3f) << 2;
269
        data >>= 6;
270
        if (data & 1)
271
            SKIP_PIXEL(dest);
272
        else
273
            COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
274
        width -= 1;
275
        src += 4;
276
    }
277
}
278

    
279
/* The wicked packed format */
280
static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
281
                uint8_t *dest, const uint8_t *src, int width, int deststep)
282
{
283
    uint32_t data[3];
284
    unsigned int r, g, b;
285
    while (width > 0) {
286
        data[0] = *(uint32_t *) src;
287
        src += 4;
288
        data[1] = *(uint32_t *) src;
289
        src += 4;
290
        data[2] = *(uint32_t *) src;
291
        src += 4;
292
# ifdef SWAP_WORDS
293
        data[0] = bswap32(data[0]);
294
        data[1] = bswap32(data[1]);
295
        data[2] = bswap32(data[2]);
296
# endif
297
        b = (data[0] & 0x3f) << 2;
298
        data[0] >>= 6;
299
        g = (data[0] & 0x3f) << 2;
300
        data[0] >>= 6;
301
        r = (data[0] & 0x3f) << 2;
302
        data[0] >>= 6;
303
        if (data[0] & 1)
304
            SKIP_PIXEL(dest);
305
        else
306
            COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
307
        data[0] >>= 6;
308
        b = (data[0] & 0x3f) << 2;
309
        data[0] >>= 6;
310
        g = ((data[1] & 0xf) << 4) | (data[0] << 2);
311
        data[1] >>= 4;
312
        r = (data[1] & 0x3f) << 2;
313
        data[1] >>= 6;
314
        if (data[1] & 1)
315
            SKIP_PIXEL(dest);
316
        else
317
            COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
318
        data[1] >>= 6;
319
        b = (data[1] & 0x3f) << 2;
320
        data[1] >>= 6;
321
        g = (data[1] & 0x3f) << 2;
322
        data[1] >>= 6;
323
        r = ((data[2] & 0x3) << 6) | (data[1] << 2);
324
        data[2] >>= 2;
325
        if (data[2] & 1)
326
            SKIP_PIXEL(dest);
327
        else
328
            COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
329
        data[2] >>= 6;
330
        b = (data[2] & 0x3f) << 2;
331
        data[2] >>= 6;
332
        g = (data[2] & 0x3f) << 2;
333
        data[2] >>= 6;
334
        r = data[2] << 2;
335
        data[2] >>= 6;
336
        if (data[2] & 1)
337
            SKIP_PIXEL(dest);
338
        else
339
            COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
340
        width -= 4;
341
    }
342
}
343

    
344
static void glue(pxa2xx_draw_line24_, BITS)(void *opaque,
345
                uint8_t *dest, const uint8_t *src, int width, int deststep)
346
{
347
    uint32_t data;
348
    unsigned int r, g, b;
349
    while (width > 0) {
350
        data = *(uint32_t *) src;
351
#ifdef SWAP_WORDS
352
        data = bswap32(data);
353
#endif
354
        b = data & 0xff;
355
        data >>= 8;
356
        g = data & 0xff;
357
        data >>= 8;
358
        r = data & 0xff;
359
        COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
360
        width -= 1;
361
        src += 4;
362
    }
363
}
364

    
365
static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque,
366
                uint8_t *dest, const uint8_t *src, int width, int deststep)
367
{
368
    uint32_t data;
369
    unsigned int r, g, b;
370
    while (width > 0) {
371
        data = *(uint32_t *) src;
372
#ifdef SWAP_WORDS
373
        data = bswap32(data);
374
#endif
375
        b = (data & 0x7f) << 1;
376
        data >>= 7;
377
        g = data & 0xff;
378
        data >>= 8;
379
        r = data & 0xff;
380
        data >>= 8;
381
        if (data & 1)
382
            SKIP_PIXEL(dest);
383
        else
384
            COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
385
        width -= 1;
386
        src += 4;
387
    }
388
}
389

    
390
static void glue(pxa2xx_draw_line25_, BITS)(void *opaque,
391
                uint8_t *dest, const uint8_t *src, int width, int deststep)
392
{
393
    uint32_t data;
394
    unsigned int r, g, b;
395
    while (width > 0) {
396
        data = *(uint32_t *) src;
397
#ifdef SWAP_WORDS
398
        data = bswap32(data);
399
#endif
400
        b = data & 0xff;
401
        data >>= 8;
402
        g = data & 0xff;
403
        data >>= 8;
404
        r = data & 0xff;
405
        data >>= 8;
406
        if (data & 1)
407
            SKIP_PIXEL(dest);
408
        else
409
            COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
410
        width -= 1;
411
        src += 4;
412
    }
413
}
414

    
415
/* Overlay planes disabled, no transparency */
416
static drawfn glue(pxa2xx_draw_fn_, BITS)[16] =
417
{
418
    [0 ... 0xf]       = NULL,
419
    [pxa_lcdc_2bpp]   = glue(pxa2xx_draw_line2_, BITS),
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_line16_, BITS),
423
    [pxa_lcdc_18bpp]  = glue(pxa2xx_draw_line18_, BITS),
424
    [pxa_lcdc_18pbpp] = glue(pxa2xx_draw_line18p_, BITS),
425
    [pxa_lcdc_24bpp]  = glue(pxa2xx_draw_line24_, BITS),
426
};
427

    
428
/* Overlay planes enabled, transparency used */
429
static drawfn glue(glue(pxa2xx_draw_fn_, BITS), t)[16] =
430
{
431
    [0 ... 0xf]       = NULL,
432
    [pxa_lcdc_4bpp]   = glue(pxa2xx_draw_line4_, BITS),
433
    [pxa_lcdc_8bpp]   = glue(pxa2xx_draw_line8_, BITS),
434
    [pxa_lcdc_16bpp]  = glue(pxa2xx_draw_line16t_, BITS),
435
    [pxa_lcdc_19bpp]  = glue(pxa2xx_draw_line19_, BITS),
436
    [pxa_lcdc_19pbpp] = glue(pxa2xx_draw_line19p_, BITS),
437
    [pxa_lcdc_24bpp]  = glue(pxa2xx_draw_line24t_, BITS),
438
    [pxa_lcdc_25bpp]  = glue(pxa2xx_draw_line25_, BITS),
439
};
440

    
441
#undef BITS
442
#undef COPY_PIXEL
443
#undef SKIP_PIXEL
444

    
445
#ifdef SWAP_WORDS
446
# undef SWAP_WORDS
447
#endif