Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
881 theseven 1
#include "global.h"
2
#include "interface/framebuffer/framebuffer.h"
3
#include "sys/util.h"
4
 
5
const uint8_t framebuffer_format_wordsize[] =
6
{
7
    [FRAMEBUFFER_FORMAT_I1] = 1,
8
    [FRAMEBUFFER_FORMAT_X1R1G1B1] = 4,
9
    [FRAMEBUFFER_FORMAT_I1R1G1B1] = 4,
10
    [FRAMEBUFFER_FORMAT_X7I1] = 8,
11
    [FRAMEBUFFER_FORMAT_X5R1G1B1] = 8,
12
    [FRAMEBUFFER_FORMAT_X2R2G2B2] = 8,
13
    [FRAMEBUFFER_FORMAT_R2G3B3] = 8,
14
    [FRAMEBUFFER_FORMAT_X1R5G5B5_LE] = 16,
15
    [FRAMEBUFFER_FORMAT_X1R5G5B5_BE] = 16,
16
    [FRAMEBUFFER_FORMAT_R5G6B5_LE] = 16,
17
    [FRAMEBUFFER_FORMAT_R5G6B5_BE] = 16,
18
    [FRAMEBUFFER_FORMAT_R8G8B8_LE] = 24,
19
    [FRAMEBUFFER_FORMAT_R8G8B8_BE] = 24,
20
    [FRAMEBUFFER_FORMAT_X31I1_LE] = 32,
21
    [FRAMEBUFFER_FORMAT_X31I1_BE] = 32,
22
    [FRAMEBUFFER_FORMAT_X8R8G8B8_LE] = 32,
23
    [FRAMEBUFFER_FORMAT_X8R8G8B8_BE] = 32,
24
};
25
 
26
uint32_t framebuffer_color_to_rgb888_be(enum framebuffer_format format, uint32_t color)
27
{
28
    uint32_t result = 0xff;
29
    switch (format)
30
    {
31
    case FRAMEBUFFER_FORMAT_X31I1_LE:
32
        color = swap32(color);
33
    case FRAMEBUFFER_FORMAT_I1:
34
    case FRAMEBUFFER_FORMAT_X7I1:
35
    case FRAMEBUFFER_FORMAT_X31I1_BE:
36
        result = (color & 1) ? 0xffffff : 0;
37
        break;
38
    case FRAMEBUFFER_FORMAT_I1R1G1B1:
39
        result = (color & 8) ? 0xff : 0x7f;
40
    case FRAMEBUFFER_FORMAT_X1R1G1B1:
41
    case FRAMEBUFFER_FORMAT_X5R1G1B1:
42
        result = ((color & 4) ? (result << 16) : 0) | ((color & 2) ? (result << 8) : 0) | ((color & 1) ? result : 0);
43
        break;
44
    case FRAMEBUFFER_FORMAT_X2R2G2B2:
45
        result = ((color & 0x30) << 18) | ((color & 0xc) << 14) | ((color & 3) << 6);
46
        result |= result >> 2;
47
        result |= result >> 4;
48
        break;
49
    case FRAMEBUFFER_FORMAT_R2G3B3:
50
        result = ((color & 0xc0) << 16) | ((color & 0x38) << 10) | ((color & 7) << 5);
51
        result |= (result & 0xc00000) >> 2;
52
        result |= (result & 0xf00000) >> 4;
53
        result |= (result & 0xe0e0) >> 3;
54
        result |= (result & 0xc0c0) >> 6;
55
        break;
56
    case FRAMEBUFFER_FORMAT_X1R5G5B5_LE:
57
        color = swap16(color);
58
    case FRAMEBUFFER_FORMAT_X1R5G5B5_BE:
59
        result = ((color & 0x7c00) << 9) | ((color & 0x3e0) << 6) | ((color & 0x1f) << 3);
60
        result |= (result & 0xe0e0e0) >> 5;
61
        break;
62
    case FRAMEBUFFER_FORMAT_R5G6B5_LE:
63
        color = swap16(color);
64
    case FRAMEBUFFER_FORMAT_R5G6B5_BE:
65
        result = ((color & 0xf800) << 8) | ((color & 0x7e0) << 5) | ((color & 0x1f) << 3);
66
        result |= (result & 0xe000e0) >> 5;
67
        result |= (result & 0xc000) >> 6;
68
        break;
69
    case FRAMEBUFFER_FORMAT_R8G8B8_LE:
70
        color <<= 8;
71
    case FRAMEBUFFER_FORMAT_X8R8G8B8_LE:
72
        color = swap32(color);
73
    case FRAMEBUFFER_FORMAT_R8G8B8_BE:
74
    case FRAMEBUFFER_FORMAT_X8R8G8B8_BE:
75
        result = color;
76
    }
77
    return result;
78
}
79
 
80
uint32_t framebuffer_color_from_rgb888_be(enum framebuffer_format format, uint32_t color)
81
{
82
    uint32_t result = 0;
83
    uint8_t r = (color & 0xff0000) >> 16;
84
    uint8_t g = (color & 0xff00) >> 8;
85
    uint8_t b = color & 0xff;
86
    switch (format)
87
    {
88
    case FRAMEBUFFER_FORMAT_I1:
89
    case FRAMEBUFFER_FORMAT_X7I1:
90
    case FRAMEBUFFER_FORMAT_X31I1_BE:
91
        result = r + g + b >= 0x180 ? 1 : 0;
92
        break;
93
    case FRAMEBUFFER_FORMAT_X31I1_LE:
94
        result = r + g + b >= 0x180 ? 0x01000000 : 0;
95
        break;
96
    case FRAMEBUFFER_FORMAT_X1R1G1B1:
97
    case FRAMEBUFFER_FORMAT_X5R1G1B1:
98
        result = ((r & 0x80) >> 5) | ((g & 0x80) >> 6) | ((b & 0x80) >> 7);
99
        break;
100
    case FRAMEBUFFER_FORMAT_I1R1G1B1:
101
        result = r + g + b >= 0x180 ? (8 | (r >= 0x80 ? 4 : 0) | (g >= 0x80 ? 2 : 0) | (b >= 0x80 ? 1 : 0))
102
                                    : ((r >= 0x40 ? 4 : 0) | (g >= 0x40 ? 2 : 0) | (b >= 0x40 ? 1 : 0));
103
        break;
104
    case FRAMEBUFFER_FORMAT_X2R2G2B2:
105
        result = (((r - (r >> 2)) >> 6) << 4) | (((g - (g >> 2)) >> 6) << 2) | ((b - (b >> 2)) >> 6);
106
        break;
107
    case FRAMEBUFFER_FORMAT_R2G3B3:
108
        result = (((r - (r >> 2)) >> 6) << 6) | (((g - (g >> 3)) >> 5) << 3) | ((b - (b >> 3)) >> 5);
109
        break;
110
    case FRAMEBUFFER_FORMAT_X1R5G5B5_BE:
111
        result = (((r - (r >> 5)) >> 3) << 10) | (((g - (g >> 5)) >> 3) << 5) | ((b - (b >> 5)) >> 3);
112
        break;
113
    case FRAMEBUFFER_FORMAT_X1R5G5B5_LE:
114
        result = swap16((((r - (r >> 5)) >> 3) << 10) | (((g - (g >> 5)) >> 3) << 5) | ((b - (b >> 5)) >> 3));
115
        break;
116
    case FRAMEBUFFER_FORMAT_R5G6B5_BE:
117
        result = (((r - (r >> 5)) >> 3) << 11) | (((g - (g >> 6)) >> 2) << 5) | ((b - (b >> 5)) >> 3);
118
        break;
119
    case FRAMEBUFFER_FORMAT_R5G6B5_LE:
120
        result = swap16((((r - (r >> 5)) >> 3) << 11) | (((g - (g >> 6)) >> 2) << 5) | ((b - (b >> 5)) >> 3));
121
        break;
122
    case FRAMEBUFFER_FORMAT_R8G8B8_LE:
123
        color <<= 8;
124
    case FRAMEBUFFER_FORMAT_X8R8G8B8_LE:
125
        color = swap32(color);
126
    case FRAMEBUFFER_FORMAT_R8G8B8_BE:
127
    case FRAMEBUFFER_FORMAT_X8R8G8B8_BE:
128
        result = color;
129
        break;
130
    }
131
    return result;
132
}
133
 
134
uint32_t framebuffer_convert_color(enum framebuffer_format from, enum framebuffer_format to, uint32_t color)
135
{
136
    return framebuffer_color_from_rgb888_be(to, framebuffer_color_to_rgb888_be(from, color));
137
}
138
 
139
uint32_t framebuffer_get_pixel(const struct framebuffer_instance* instance, int x, int y)
140
{
141
    int wsize = framebuffer_format_wordsize[instance->format];
142
    int bit = (instance->width * y + x) * wsize;
143
    uint32_t color = (swap32(((uint32_t*)instance->data)[bit >> 5]) >> (32 - (bit & 31) - wsize)) & (0xffffffff >> (32 - wsize));
144
    if (wsize == 16) return swap16(color);
145
    if (wsize == 32) return swap32(color);
146
    return color;
147
}
148
 
149
void framebuffer_set_pixel(const struct framebuffer_instance* instance, int x, int y, uint32_t color)
150
{
151
    int wsize = framebuffer_format_wordsize[instance->format];
152
    if (wsize == 16) color = swap16(color);
153
    else if (wsize == 32) color = swap32(color);
154
    int bit = (instance->width * y + x) * wsize;
155
    int byte = bit >> 5;
156
    bit = 32 - (bit & 31) - wsize;
157
    uint32_t mask = 0xffffffff >> (32 - wsize);
158
    uint32_t data = swap32(((uint32_t*)instance->data)[byte]);
159
    ((uint32_t*)instance->data)[byte] = swap32((data & ~(mask << bit)) | ((color & mask) << bit));
160
}
161
 
162
void framebuffer_fill(const struct framebuffer_instance* instance, int x, int y, int w, int h,
163
                      enum framebuffer_format format, uint32_t color, enum framebuffer_conversion_quality quality)
164
{
165
    int stride = instance->width;
166
    enum framebuffer_format fmt = instance->format;
167
    int wsize = framebuffer_format_wordsize[fmt];
168
    if (format != fmt)
169
    {
170
        if (framebuffer_format_wordsize[format] == 16) color = swap16(color);
171
        else if (framebuffer_format_wordsize[format] == 32) color = swap32(color);
172
        color = framebuffer_convert_color(format, fmt, color);
173
        if (wsize == 16) color = swap16(color);
174
        else if (wsize == 32) color = swap32(color);
175
    }
176
 
177
    if (w == stride)
178
    {
179
        w *= h;
180
        h = 1;
181
    }
182
 
183
    color &= 0xffffffff >> (32 - wsize);
184
    while (wsize < 32 && !(w & 1) && !(x & 1) && !(stride & 1))
185
    {
186
        color |= color << wsize;
187
        wsize <<= 1;
188
        w >>= 1;
189
        x >>= 1;
190
        stride >>= 1;
191
    }
192
    if (wsize >= 8)
193
    {
194
        void* out = instance->data + (y * stride + x) * (wsize >> 3);
195
        while (h--)
196
        {
197
            if (wsize == 32)
198
            {
199
                uint32_t* ptr = out;
200
                int pixels = w;
201
                while (pixels--) *ptr++ = color;
202
            }
203
            else if (wsize == 16)
204
            {
205
                uint16_t* ptr = out;
206
                int pixels = w;
207
                while (pixels--) *ptr++ = color;
208
            }
209
            else memset(out, color, w);
210
            out += stride * (wsize >> 3);
211
        }
212
        return;
213
    }
214
 
215
    int mask = 0xffffffff >> (32 - wsize);
216
    uint32_t* out = instance->data;
217
    int bit = (y * stride + x) * wsize;
218
    out += bit >> 5;
219
    bit &= 31;
220
    while (h--)
221
    {
222
        int pixels = w;
223
        uint32_t data = swap32(*out);
224
        while (pixels--)
225
        {
226
            if (!bit) data = swap32(*out);
227
            data = (data & ~(mask << (32 - bit - wsize))) | (color << (32 - bit - wsize));
228
            bit += wsize;
229
            if (bit == 32)
230
            {
231
                *out++ = swap32(data);
232
                bit = 0;
233
            }
234
        }
235
        if (bit) *out = swap32(data);
236
        bit += (stride - w) * wsize;
237
        out += bit >> 5;
238
        bit &= 31;
239
    }
240
}
241
 
242
void framebuffer_blit(const struct framebuffer_instance* infb, int inx, int iny,
243
                      const struct framebuffer_instance* outfb, int outx, int outy,
244
                      int w, int h, enum framebuffer_conversion_quality quality)
245
{
246
    int instride = infb->width;
247
    int outstride = outfb->width;
248
    enum framebuffer_format infmt = infb->format;
249
    enum framebuffer_format outfmt = outfb->format;
250
    int inwsize = framebuffer_format_wordsize[infmt];
251
    int outwsize = framebuffer_format_wordsize[outfmt];
252
 
253
    if (w == instride && w == outstride)
254
    {
255
        w *= h;
256
        h = 1;
257
    }
258
 
259
    if (infmt == outfmt)
260
    {
261
        while (inwsize < 32 && !(w & 1) && !(inx & 1) && !(outx & 1) && !(instride & 1) && !(outstride & 1))
262
        {
263
            inwsize <<= 1;
264
            outwsize <<= 1;
265
            w >>= 1;
266
            inx >>= 1;
267
            outx >>= 1;
268
            instride >>= 1;
269
            outstride >>= 1;
270
        }
271
        if (inwsize >= 8)
272
        {
273
            void* in = infb->data + (iny * instride + inx) * (inwsize >> 3);
274
            void* out = outfb->data + (outy * outstride + outx) * (outwsize >> 3);
275
            while (h--)
276
            {
277
                memcpy(out, in, w * (outwsize >> 3));
278
                in += (instride - w) * (inwsize >> 3);
279
                out += (outstride - w) * (outwsize >> 3);
280
            }
281
            return;
282
        }
283
    }
284
 
285
    int inmask = 0xffffffff >> (32 - inwsize);
286
    int outmask = 0xffffffff >> (32 - outwsize);
287
    uint32_t* in = infb->data;
288
    uint32_t* out = outfb->data;
289
    int inbit = (iny * instride + inx) * inwsize;
290
    int outbit = (outy * outstride + outx) * outwsize;
291
    in += inbit >> 5;
292
    out += outbit >> 5;
293
    inbit &= 31;
294
    outbit &= 31;
295
    while (h--)
296
    {
297
        int pixels = w;
298
        uint32_t idata = swap32(*in) << inbit;
299
        uint32_t odata = swap32(*out);
300
        while (pixels--)
301
        {
302
            if (inbit == 32)
303
            {
304
                idata = swap32(*++in);
305
                inbit = 0;
306
            }
307
            if (!outbit) odata = swap32(*out);
308
            idata = ((idata << inwsize) | (idata >> (32 - inwsize)));
309
            uint32_t data = idata & inmask;
310
            if (infmt != outfmt) data = framebuffer_convert_color(infmt, outfmt, data);
311
            odata = (odata & ~(outmask << (32 - outbit - outwsize))) | (data << (32 - outbit - outwsize));
312
            inbit += inwsize;
313
            outbit += outwsize;
314
            if (outbit == 32)
315
            {
316
                *out++ = swap32(odata);
317
                outbit = 0;
318
            }
319
        }
320
        if (outbit) *out = swap32(odata);
321
        inbit += (instride - w) * inwsize;
322
        outbit += (outstride - w) * outwsize;
323
        in += inbit >> 5;
324
        out += outbit >> 5;
325
        inbit &= 31;
326
        outbit &= 31;
327
    }
328
}
329
 
330
void framebuffer_update(const struct framebuffer_instance* instance, int x, int y, int w, int h)
331
{
332
    instance->update_handler(instance->update_handler_arg, instance, x, y, w, h);
333
}