qemu/hw/display/pl110_template.h
<<
>>
Prefs
   1/*
   2 * Arm PrimeCell PL110 Color LCD Controller
   3 *
   4 * Copyright (c) 2005 CodeSourcery, LLC.
   5 * Written by Paul Brook
   6 *
   7 * This code is licensed under the GNU LGPL
   8 *
   9 * Framebuffer format conversion routines.
  10 */
  11
  12#ifndef ORDER
  13
  14#if BITS == 8
  15#define COPY_PIXEL(to, from) *(to++) = from
  16#elif BITS == 15 || BITS == 16
  17#define COPY_PIXEL(to, from) do { *(uint16_t *)to = from; to += 2; } while (0)
  18#elif BITS == 24
  19#define COPY_PIXEL(to, from)    \
  20    do {                        \
  21        *(to++) = from;         \
  22        *(to++) = (from) >> 8;  \
  23        *(to++) = (from) >> 16; \
  24    } while (0)
  25#elif BITS == 32
  26#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
  27#else
  28#error unknown bit depth
  29#endif
  30
  31#undef RGB
  32#define BORDER bgr
  33#define ORDER 0
  34#include "pl110_template.h"
  35#define ORDER 1
  36#include "pl110_template.h"
  37#define ORDER 2
  38#include "pl110_template.h"
  39#undef BORDER
  40#define RGB
  41#define BORDER rgb
  42#define ORDER 0
  43#include "pl110_template.h"
  44#define ORDER 1
  45#include "pl110_template.h"
  46#define ORDER 2
  47#include "pl110_template.h"
  48#undef BORDER
  49
  50static drawfn glue(pl110_draw_fn_,BITS)[48] =
  51{
  52    glue(pl110_draw_line1_lblp_bgr,BITS),
  53    glue(pl110_draw_line2_lblp_bgr,BITS),
  54    glue(pl110_draw_line4_lblp_bgr,BITS),
  55    glue(pl110_draw_line8_lblp_bgr,BITS),
  56    glue(pl110_draw_line16_555_lblp_bgr,BITS),
  57    glue(pl110_draw_line32_lblp_bgr,BITS),
  58    glue(pl110_draw_line16_lblp_bgr,BITS),
  59    glue(pl110_draw_line12_lblp_bgr,BITS),
  60
  61    glue(pl110_draw_line1_bbbp_bgr,BITS),
  62    glue(pl110_draw_line2_bbbp_bgr,BITS),
  63    glue(pl110_draw_line4_bbbp_bgr,BITS),
  64    glue(pl110_draw_line8_bbbp_bgr,BITS),
  65    glue(pl110_draw_line16_555_bbbp_bgr,BITS),
  66    glue(pl110_draw_line32_bbbp_bgr,BITS),
  67    glue(pl110_draw_line16_bbbp_bgr,BITS),
  68    glue(pl110_draw_line12_bbbp_bgr,BITS),
  69
  70    glue(pl110_draw_line1_lbbp_bgr,BITS),
  71    glue(pl110_draw_line2_lbbp_bgr,BITS),
  72    glue(pl110_draw_line4_lbbp_bgr,BITS),
  73    glue(pl110_draw_line8_lbbp_bgr,BITS),
  74    glue(pl110_draw_line16_555_lbbp_bgr,BITS),
  75    glue(pl110_draw_line32_lbbp_bgr,BITS),
  76    glue(pl110_draw_line16_lbbp_bgr,BITS),
  77    glue(pl110_draw_line12_lbbp_bgr,BITS),
  78
  79    glue(pl110_draw_line1_lblp_rgb,BITS),
  80    glue(pl110_draw_line2_lblp_rgb,BITS),
  81    glue(pl110_draw_line4_lblp_rgb,BITS),
  82    glue(pl110_draw_line8_lblp_rgb,BITS),
  83    glue(pl110_draw_line16_555_lblp_rgb,BITS),
  84    glue(pl110_draw_line32_lblp_rgb,BITS),
  85    glue(pl110_draw_line16_lblp_rgb,BITS),
  86    glue(pl110_draw_line12_lblp_rgb,BITS),
  87
  88    glue(pl110_draw_line1_bbbp_rgb,BITS),
  89    glue(pl110_draw_line2_bbbp_rgb,BITS),
  90    glue(pl110_draw_line4_bbbp_rgb,BITS),
  91    glue(pl110_draw_line8_bbbp_rgb,BITS),
  92    glue(pl110_draw_line16_555_bbbp_rgb,BITS),
  93    glue(pl110_draw_line32_bbbp_rgb,BITS),
  94    glue(pl110_draw_line16_bbbp_rgb,BITS),
  95    glue(pl110_draw_line12_bbbp_rgb,BITS),
  96
  97    glue(pl110_draw_line1_lbbp_rgb,BITS),
  98    glue(pl110_draw_line2_lbbp_rgb,BITS),
  99    glue(pl110_draw_line4_lbbp_rgb,BITS),
 100    glue(pl110_draw_line8_lbbp_rgb,BITS),
 101    glue(pl110_draw_line16_555_lbbp_rgb,BITS),
 102    glue(pl110_draw_line32_lbbp_rgb,BITS),
 103    glue(pl110_draw_line16_lbbp_rgb,BITS),
 104    glue(pl110_draw_line12_lbbp_rgb,BITS),
 105};
 106
 107#undef BITS
 108#undef COPY_PIXEL
 109
 110#else
 111
 112#if ORDER == 0
 113#define NAME glue(glue(lblp_, BORDER), BITS)
 114#ifdef HOST_WORDS_BIGENDIAN
 115#define SWAP_WORDS 1
 116#endif
 117#elif ORDER == 1
 118#define NAME glue(glue(bbbp_, BORDER), BITS)
 119#ifndef HOST_WORDS_BIGENDIAN
 120#define SWAP_WORDS 1
 121#endif
 122#else
 123#define SWAP_PIXELS 1
 124#define NAME glue(glue(lbbp_, BORDER), BITS)
 125#ifdef HOST_WORDS_BIGENDIAN
 126#define SWAP_WORDS 1
 127#endif
 128#endif
 129
 130#define FN_2(x, y) FN(x, y) FN(x+1, y)
 131#define FN_4(x, y) FN_2(x, y) FN_2(x+2, y)
 132#define FN_8(y) FN_4(0, y) FN_4(4, y)
 133
 134static void glue(pl110_draw_line1_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
 135{
 136    uint32_t *palette = opaque;
 137    uint32_t data;
 138    while (width > 0) {
 139        data = *(uint32_t *)src;
 140#ifdef SWAP_PIXELS
 141#define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 7 - (x))) & 1]);
 142#else
 143#define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x) + y)) & 1]);
 144#endif
 145#ifdef SWAP_WORDS
 146        FN_8(24)
 147        FN_8(16)
 148        FN_8(8)
 149        FN_8(0)
 150#else
 151        FN_8(0)
 152        FN_8(8)
 153        FN_8(16)
 154        FN_8(24)
 155#endif
 156#undef FN
 157        width -= 32;
 158        src += 4;
 159    }
 160}
 161
 162static void glue(pl110_draw_line2_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
 163{
 164    uint32_t *palette = opaque;
 165    uint32_t data;
 166    while (width > 0) {
 167        data = *(uint32_t *)src;
 168#ifdef SWAP_PIXELS
 169#define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 6 - (x)*2)) & 3]);
 170#else
 171#define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*2 + y)) & 3]);
 172#endif
 173#ifdef SWAP_WORDS
 174        FN_4(0, 24)
 175        FN_4(0, 16)
 176        FN_4(0, 8)
 177        FN_4(0, 0)
 178#else
 179        FN_4(0, 0)
 180        FN_4(0, 8)
 181        FN_4(0, 16)
 182        FN_4(0, 24)
 183#endif
 184#undef FN
 185        width -= 16;
 186        src += 4;
 187    }
 188}
 189
 190static void glue(pl110_draw_line4_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
 191{
 192    uint32_t *palette = opaque;
 193    uint32_t data;
 194    while (width > 0) {
 195        data = *(uint32_t *)src;
 196#ifdef SWAP_PIXELS
 197#define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 4 - (x)*4)) & 0xf]);
 198#else
 199#define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*4 + y)) & 0xf]);
 200#endif
 201#ifdef SWAP_WORDS
 202        FN_2(0, 24)
 203        FN_2(0, 16)
 204        FN_2(0, 8)
 205        FN_2(0, 0)
 206#else
 207        FN_2(0, 0)
 208        FN_2(0, 8)
 209        FN_2(0, 16)
 210        FN_2(0, 24)
 211#endif
 212#undef FN
 213        width -= 8;
 214        src += 4;
 215    }
 216}
 217
 218static void glue(pl110_draw_line8_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
 219{
 220    uint32_t *palette = opaque;
 221    uint32_t data;
 222    while (width > 0) {
 223        data = *(uint32_t *)src;
 224#define FN(x) COPY_PIXEL(d, palette[(data >> (x)) & 0xff]);
 225#ifdef SWAP_WORDS
 226        FN(24)
 227        FN(16)
 228        FN(8)
 229        FN(0)
 230#else
 231        FN(0)
 232        FN(8)
 233        FN(16)
 234        FN(24)
 235#endif
 236#undef FN
 237        width -= 4;
 238        src += 4;
 239    }
 240}
 241
 242static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
 243{
 244    uint32_t data;
 245    unsigned int r, g, b;
 246    while (width > 0) {
 247        data = *(uint32_t *)src;
 248#ifdef SWAP_WORDS
 249        data = bswap32(data);
 250#endif
 251#ifdef RGB
 252#define LSB r
 253#define MSB b
 254#else
 255#define LSB b
 256#define MSB r
 257#endif
 258#if 0
 259        LSB = data & 0x1f;
 260        data >>= 5;
 261        g = data & 0x3f;
 262        data >>= 6;
 263        MSB = data & 0x1f;
 264        data >>= 5;
 265#else
 266        LSB = (data & 0x1f) << 3;
 267        data >>= 5;
 268        g = (data & 0x3f) << 2;
 269        data >>= 6;
 270        MSB = (data & 0x1f) << 3;
 271        data >>= 5;
 272#endif
 273        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
 274        LSB = (data & 0x1f) << 3;
 275        data >>= 5;
 276        g = (data & 0x3f) << 2;
 277        data >>= 6;
 278        MSB = (data & 0x1f) << 3;
 279        data >>= 5;
 280        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
 281#undef MSB
 282#undef LSB
 283        width -= 2;
 284        src += 4;
 285    }
 286}
 287
 288static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
 289{
 290    uint32_t data;
 291    unsigned int r, g, b;
 292    while (width > 0) {
 293        data = *(uint32_t *)src;
 294#ifdef RGB
 295#define LSB r
 296#define MSB b
 297#else
 298#define LSB b
 299#define MSB r
 300#endif
 301#ifndef SWAP_WORDS
 302        LSB = data & 0xff;
 303        g = (data >> 8) & 0xff;
 304        MSB = (data >> 16) & 0xff;
 305#else
 306        LSB = (data >> 24) & 0xff;
 307        g = (data >> 16) & 0xff;
 308        MSB = (data >> 8) & 0xff;
 309#endif
 310        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
 311#undef MSB
 312#undef LSB
 313        width--;
 314        src += 4;
 315    }
 316}
 317
 318static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
 319{
 320    /* RGB 555 plus an intensity bit (which we ignore) */
 321    uint32_t data;
 322    unsigned int r, g, b;
 323    while (width > 0) {
 324        data = *(uint32_t *)src;
 325#ifdef SWAP_WORDS
 326        data = bswap32(data);
 327#endif
 328#ifdef RGB
 329#define LSB r
 330#define MSB b
 331#else
 332#define LSB b
 333#define MSB r
 334#endif
 335        LSB = (data & 0x1f) << 3;
 336        data >>= 5;
 337        g = (data & 0x1f) << 3;
 338        data >>= 5;
 339        MSB = (data & 0x1f) << 3;
 340        data >>= 5;
 341        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
 342        LSB = (data & 0x1f) << 3;
 343        data >>= 5;
 344        g = (data & 0x1f) << 3;
 345        data >>= 5;
 346        MSB = (data & 0x1f) << 3;
 347        data >>= 6;
 348        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
 349#undef MSB
 350#undef LSB
 351        width -= 2;
 352        src += 4;
 353    }
 354}
 355
 356static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
 357{
 358    /* RGB 444 with 4 bits of zeroes at the top of each halfword */
 359    uint32_t data;
 360    unsigned int r, g, b;
 361    while (width > 0) {
 362        data = *(uint32_t *)src;
 363#ifdef SWAP_WORDS
 364        data = bswap32(data);
 365#endif
 366#ifdef RGB
 367#define LSB r
 368#define MSB b
 369#else
 370#define LSB b
 371#define MSB r
 372#endif
 373        LSB = (data & 0xf) << 4;
 374        data >>= 4;
 375        g = (data & 0xf) << 4;
 376        data >>= 4;
 377        MSB = (data & 0xf) << 4;
 378        data >>= 8;
 379        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
 380        LSB = (data & 0xf) << 4;
 381        data >>= 4;
 382        g = (data & 0xf) << 4;
 383        data >>= 4;
 384        MSB = (data & 0xf) << 4;
 385        data >>= 8;
 386        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
 387#undef MSB
 388#undef LSB
 389        width -= 2;
 390        src += 4;
 391    }
 392}
 393
 394#undef SWAP_PIXELS
 395#undef NAME
 396#undef SWAP_WORDS
 397#undef ORDER
 398
 399#endif
 400