diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-03-14 13:18:49 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-03-14 13:18:49 +0000 |
commit | 6f8a81fc296535f73c48cf9563862e088cc71c57 (patch) | |
tree | 1132db2423ed7ce1fcbec9ce6c32dcf07ead6dc7 /hw/display | |
parent | 8e6bc6cdc82d45f203bc9fc4342c0452214c74fe (diff) | |
parent | 6500ac13ff8e5c64ca69f5ef5d456028cfda6139 (diff) |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20210314' into staging
target-arm queue:
* versal: Support XRAMs and XRAM controller
* smmu: Various minor bug fixes
* SVE emulation: fix bugs handling odd vector lengths
* allwinner-sun8i-emac: traverse transmit queue using TX_CUR_DESC register value
* tests/acceptance: fix orangepi-pc acceptance tests
* hw/timer/sse-timer: Propagate eventual error in sse_timer_realize()
* hw/arm/virt: KVM: The IPA lower bound is 32
* npcm7xx: support MFT module
* pl110, pxa2xx_lcd: tidy up template headers
# gpg: Signature made Sun 14 Mar 2021 13:17:43 GMT
# gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg: issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE
* remotes/pmaydell/tags/pull-target-arm-20210314: (39 commits)
hw/display/pxa2xx: Inline template header
hw/display/pxa2xx: Apply whitespace-only coding style fixes to template header
hw/display/pxa2xx: Apply brace-related coding style fixes to template header
hw/display/pxa2xx: Remove use of BITS in pxa2xx_template.h
hw/display/pxa2xx_lcd: Remove dest_width state field
hw/display/pxa2xx_lcd: Remove dead code for non-32-bpp surfaces
hw/display/pl110: Remove use of BITS from pl110_template.h
hw/display/pl110: Pull included-once parts of template header into pl110.c
hw/display/pl110: Remove dead code for non-32-bpp surfaces
tests/qtest: Test PWM fan RPM using MFT in PWM test
hw/arm: Connect PWM fans in NPCM7XX boards
hw/arm: Add MFT device to NPCM7xx Soc
hw/misc: Add NPCM7XX MFT Module
hw/misc: Add GPIOs for duty in NPCM7xx PWM
hw/arm/virt: KVM: The IPA lower bound is 32
accel: kvm: Fix kvm_type invocation
hw/timer/sse-timer: Propagate eventual error in sse_timer_realize()
tests/acceptance: drop ARMBIAN_ARTIFACTS_CACHED condition for orangepi-pc, cubieboard tests
tests/acceptance: update sunxi kernel from armbian to 5.10.16
tests/acceptance/boot_linux_console: change URL for test_arm_orangepi_bionic_20_08
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/display')
-rw-r--r-- | hw/display/pl110.c | 123 | ||||
-rw-r--r-- | hw/display/pl110_template.h | 120 | ||||
-rw-r--r-- | hw/display/pxa2xx_lcd.c | 520 | ||||
-rw-r--r-- | hw/display/pxa2xx_template.h | 447 |
4 files changed, 542 insertions, 668 deletions
diff --git a/hw/display/pl110.c b/hw/display/pl110.c index 02b0d45f06..4bf15c1da5 100644 --- a/hw/display/pl110.c +++ b/hw/display/pl110.c @@ -123,16 +123,84 @@ static const unsigned char *idregs[] = { pl111_id }; -#define BITS 8 +#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0) + +#undef RGB +#define BORDER bgr +#define ORDER 0 +#include "pl110_template.h" +#define ORDER 1 #include "pl110_template.h" -#define BITS 15 +#define ORDER 2 #include "pl110_template.h" -#define BITS 16 +#undef BORDER +#define RGB +#define BORDER rgb +#define ORDER 0 #include "pl110_template.h" -#define BITS 24 +#define ORDER 1 #include "pl110_template.h" -#define BITS 32 +#define ORDER 2 #include "pl110_template.h" +#undef BORDER + +#undef COPY_PIXEL + +static drawfn pl110_draw_fn_32[48] = { + pl110_draw_line1_lblp_bgr, + pl110_draw_line2_lblp_bgr, + pl110_draw_line4_lblp_bgr, + pl110_draw_line8_lblp_bgr, + pl110_draw_line16_555_lblp_bgr, + pl110_draw_line32_lblp_bgr, + pl110_draw_line16_lblp_bgr, + pl110_draw_line12_lblp_bgr, + + pl110_draw_line1_bbbp_bgr, + pl110_draw_line2_bbbp_bgr, + pl110_draw_line4_bbbp_bgr, + pl110_draw_line8_bbbp_bgr, + pl110_draw_line16_555_bbbp_bgr, + pl110_draw_line32_bbbp_bgr, + pl110_draw_line16_bbbp_bgr, + pl110_draw_line12_bbbp_bgr, + + pl110_draw_line1_lbbp_bgr, + pl110_draw_line2_lbbp_bgr, + pl110_draw_line4_lbbp_bgr, + pl110_draw_line8_lbbp_bgr, + pl110_draw_line16_555_lbbp_bgr, + pl110_draw_line32_lbbp_bgr, + pl110_draw_line16_lbbp_bgr, + pl110_draw_line12_lbbp_bgr, + + pl110_draw_line1_lblp_rgb, + pl110_draw_line2_lblp_rgb, + pl110_draw_line4_lblp_rgb, + pl110_draw_line8_lblp_rgb, + pl110_draw_line16_555_lblp_rgb, + pl110_draw_line32_lblp_rgb, + pl110_draw_line16_lblp_rgb, + pl110_draw_line12_lblp_rgb, + + pl110_draw_line1_bbbp_rgb, + pl110_draw_line2_bbbp_rgb, + pl110_draw_line4_bbbp_rgb, + pl110_draw_line8_bbbp_rgb, + pl110_draw_line16_555_bbbp_rgb, + pl110_draw_line32_bbbp_rgb, + pl110_draw_line16_bbbp_rgb, + pl110_draw_line12_bbbp_rgb, + + pl110_draw_line1_lbbp_rgb, + pl110_draw_line2_lbbp_rgb, + pl110_draw_line4_lbbp_rgb, + pl110_draw_line8_lbbp_rgb, + pl110_draw_line16_555_lbbp_rgb, + pl110_draw_line32_lbbp_rgb, + pl110_draw_line16_lbbp_rgb, + pl110_draw_line12_lbbp_rgb, +}; static int pl110_enabled(PL110State *s) { @@ -144,9 +212,7 @@ static void pl110_update_display(void *opaque) PL110State *s = (PL110State *)opaque; SysBusDevice *sbd; DisplaySurface *surface = qemu_console_surface(s->con); - drawfn* fntable; drawfn fn; - int dest_width; int src_width; int bpp_offset; int first; @@ -158,33 +224,6 @@ static void pl110_update_display(void *opaque) sbd = SYS_BUS_DEVICE(s); - switch (surface_bits_per_pixel(surface)) { - case 0: - return; - case 8: - fntable = pl110_draw_fn_8; - dest_width = 1; - break; - case 15: - fntable = pl110_draw_fn_15; - dest_width = 2; - break; - case 16: - fntable = pl110_draw_fn_16; - dest_width = 2; - break; - case 24: - fntable = pl110_draw_fn_24; - dest_width = 3; - break; - case 32: - fntable = pl110_draw_fn_32; - dest_width = 4; - break; - default: - fprintf(stderr, "pl110: Bad color depth\n"); - exit(1); - } if (s->cr & PL110_CR_BGR) bpp_offset = 0; else @@ -218,12 +257,13 @@ static void pl110_update_display(void *opaque) } } - if (s->cr & PL110_CR_BEBO) - fn = fntable[s->bpp + 8 + bpp_offset]; - else if (s->cr & PL110_CR_BEPO) - fn = fntable[s->bpp + 16 + bpp_offset]; - else - fn = fntable[s->bpp + bpp_offset]; + if (s->cr & PL110_CR_BEBO) { + fn = pl110_draw_fn_32[s->bpp + 8 + bpp_offset]; + } else if (s->cr & PL110_CR_BEPO) { + fn = pl110_draw_fn_32[s->bpp + 16 + bpp_offset]; + } else { + fn = pl110_draw_fn_32[s->bpp + bpp_offset]; + } src_width = s->cols; switch (s->bpp) { @@ -247,7 +287,6 @@ static void pl110_update_display(void *opaque) src_width <<= 2; break; } - dest_width *= s->cols; first = 0; if (s->invalidate) { framebuffer_update_memory_section(&s->fbsection, @@ -258,7 +297,7 @@ static void pl110_update_display(void *opaque) framebuffer_update_display(surface, &s->fbsection, s->cols, s->rows, - src_width, dest_width, 0, + src_width, s->cols * 4, 0, s->invalidate, fn, s->palette, &first, &last); diff --git a/hw/display/pl110_template.h b/hw/display/pl110_template.h index 36ba791c6f..877419aa81 100644 --- a/hw/display/pl110_template.h +++ b/hw/display/pl110_template.h @@ -10,118 +10,22 @@ */ #ifndef ORDER - -#if BITS == 8 -#define COPY_PIXEL(to, from) *(to++) = from -#elif BITS == 15 || BITS == 16 -#define COPY_PIXEL(to, from) do { *(uint16_t *)to = from; to += 2; } while (0) -#elif BITS == 24 -#define COPY_PIXEL(to, from) \ - do { \ - *(to++) = from; \ - *(to++) = (from) >> 8; \ - *(to++) = (from) >> 16; \ - } while (0) -#elif BITS == 32 -#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0) -#else -#error unknown bit depth +#error "pl110_template.h is only for inclusion by pl110.c" #endif -#undef RGB -#define BORDER bgr -#define ORDER 0 -#include "pl110_template.h" -#define ORDER 1 -#include "pl110_template.h" -#define ORDER 2 -#include "pl110_template.h" -#undef BORDER -#define RGB -#define BORDER rgb -#define ORDER 0 -#include "pl110_template.h" -#define ORDER 1 -#include "pl110_template.h" -#define ORDER 2 -#include "pl110_template.h" -#undef BORDER - -static drawfn glue(pl110_draw_fn_,BITS)[48] = -{ - glue(pl110_draw_line1_lblp_bgr,BITS), - glue(pl110_draw_line2_lblp_bgr,BITS), - glue(pl110_draw_line4_lblp_bgr,BITS), - glue(pl110_draw_line8_lblp_bgr,BITS), - glue(pl110_draw_line16_555_lblp_bgr,BITS), - glue(pl110_draw_line32_lblp_bgr,BITS), - glue(pl110_draw_line16_lblp_bgr,BITS), - glue(pl110_draw_line12_lblp_bgr,BITS), - - glue(pl110_draw_line1_bbbp_bgr,BITS), - glue(pl110_draw_line2_bbbp_bgr,BITS), - glue(pl110_draw_line4_bbbp_bgr,BITS), - glue(pl110_draw_line8_bbbp_bgr,BITS), - glue(pl110_draw_line16_555_bbbp_bgr,BITS), - glue(pl110_draw_line32_bbbp_bgr,BITS), - glue(pl110_draw_line16_bbbp_bgr,BITS), - glue(pl110_draw_line12_bbbp_bgr,BITS), - - glue(pl110_draw_line1_lbbp_bgr,BITS), - glue(pl110_draw_line2_lbbp_bgr,BITS), - glue(pl110_draw_line4_lbbp_bgr,BITS), - glue(pl110_draw_line8_lbbp_bgr,BITS), - glue(pl110_draw_line16_555_lbbp_bgr,BITS), - glue(pl110_draw_line32_lbbp_bgr,BITS), - glue(pl110_draw_line16_lbbp_bgr,BITS), - glue(pl110_draw_line12_lbbp_bgr,BITS), - - glue(pl110_draw_line1_lblp_rgb,BITS), - glue(pl110_draw_line2_lblp_rgb,BITS), - glue(pl110_draw_line4_lblp_rgb,BITS), - glue(pl110_draw_line8_lblp_rgb,BITS), - glue(pl110_draw_line16_555_lblp_rgb,BITS), - glue(pl110_draw_line32_lblp_rgb,BITS), - glue(pl110_draw_line16_lblp_rgb,BITS), - glue(pl110_draw_line12_lblp_rgb,BITS), - - glue(pl110_draw_line1_bbbp_rgb,BITS), - glue(pl110_draw_line2_bbbp_rgb,BITS), - glue(pl110_draw_line4_bbbp_rgb,BITS), - glue(pl110_draw_line8_bbbp_rgb,BITS), - glue(pl110_draw_line16_555_bbbp_rgb,BITS), - glue(pl110_draw_line32_bbbp_rgb,BITS), - glue(pl110_draw_line16_bbbp_rgb,BITS), - glue(pl110_draw_line12_bbbp_rgb,BITS), - - glue(pl110_draw_line1_lbbp_rgb,BITS), - glue(pl110_draw_line2_lbbp_rgb,BITS), - glue(pl110_draw_line4_lbbp_rgb,BITS), - glue(pl110_draw_line8_lbbp_rgb,BITS), - glue(pl110_draw_line16_555_lbbp_rgb,BITS), - glue(pl110_draw_line32_lbbp_rgb,BITS), - glue(pl110_draw_line16_lbbp_rgb,BITS), - glue(pl110_draw_line12_lbbp_rgb,BITS), -}; - -#undef BITS -#undef COPY_PIXEL - -#else - #if ORDER == 0 -#define NAME glue(glue(lblp_, BORDER), BITS) +#define NAME glue(lblp_, BORDER) #ifdef HOST_WORDS_BIGENDIAN #define SWAP_WORDS 1 #endif #elif ORDER == 1 -#define NAME glue(glue(bbbp_, BORDER), BITS) +#define NAME glue(bbbp_, BORDER) #ifndef HOST_WORDS_BIGENDIAN #define SWAP_WORDS 1 #endif #else #define SWAP_PIXELS 1 -#define NAME glue(glue(lbbp_, BORDER), BITS) +#define NAME glue(lbbp_, BORDER) #ifdef HOST_WORDS_BIGENDIAN #define SWAP_WORDS 1 #endif @@ -270,14 +174,14 @@ static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_ MSB = (data & 0x1f) << 3; data >>= 5; #endif - COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b)); + COPY_PIXEL(d, rgb_to_pixel32(r, g, b)); LSB = (data & 0x1f) << 3; data >>= 5; g = (data & 0x3f) << 2; data >>= 6; MSB = (data & 0x1f) << 3; data >>= 5; - COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b)); + COPY_PIXEL(d, rgb_to_pixel32(r, g, b)); #undef MSB #undef LSB width -= 2; @@ -307,7 +211,7 @@ static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_ g = (data >> 16) & 0xff; MSB = (data >> 8) & 0xff; #endif - COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b)); + COPY_PIXEL(d, rgb_to_pixel32(r, g, b)); #undef MSB #undef LSB width--; @@ -338,14 +242,14 @@ static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const ui data >>= 5; MSB = (data & 0x1f) << 3; data >>= 5; - COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b)); + COPY_PIXEL(d, rgb_to_pixel32(r, g, b)); LSB = (data & 0x1f) << 3; data >>= 5; g = (data & 0x1f) << 3; data >>= 5; MSB = (data & 0x1f) << 3; data >>= 6; - COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b)); + COPY_PIXEL(d, rgb_to_pixel32(r, g, b)); #undef MSB #undef LSB width -= 2; @@ -376,14 +280,14 @@ static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_ data >>= 4; MSB = (data & 0xf) << 4; data >>= 8; - COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b)); + COPY_PIXEL(d, rgb_to_pixel32(r, g, b)); LSB = (data & 0xf) << 4; data >>= 4; g = (data & 0xf) << 4; data >>= 4; MSB = (data & 0xf) << 4; data >>= 8; - COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b)); + COPY_PIXEL(d, rgb_to_pixel32(r, g, b)); #undef MSB #undef LSB width -= 2; @@ -395,5 +299,3 @@ static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_ #undef NAME #undef SWAP_WORDS #undef ORDER - -#endif diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c index dfff994962..2887ce496b 100644 --- a/hw/display/pxa2xx_lcd.c +++ b/hw/display/pxa2xx_lcd.c @@ -45,7 +45,6 @@ struct PXA2xxLCDState { int invalidated; QemuConsole *con; - drawfn *line_fn[2]; int dest_width; int xres, yres; int pal_for; @@ -188,6 +187,435 @@ typedef struct QEMU_PACKED { #define LDCMD_SOFINT (1 << 22) #define LDCMD_PAL (1 << 26) +/* Size of a pixel in the QEMU UI output surface, in bytes */ +#define DEST_PIXEL_WIDTH 4 + +/* Line drawing code to handle the various possible guest pixel formats */ + +# define SKIP_PIXEL(to) do { to += deststep; } while (0) +# define COPY_PIXEL(to, from) \ + do { \ + *(uint32_t *) to = from; \ + SKIP_PIXEL(to); \ + } while (0) + +#ifdef HOST_WORDS_BIGENDIAN +# define SWAP_WORDS 1 +#endif + +#define FN_2(x) FN(x + 1) FN(x) +#define FN_4(x) FN_2(x + 2) FN_2(x) + +static void pxa2xx_draw_line2(void *opaque, uint8_t *dest, const uint8_t *src, + int width, int deststep) +{ + uint32_t *palette = opaque; + uint32_t data; + while (width > 0) { + data = *(uint32_t *) src; +#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]); +#ifdef SWAP_WORDS + FN_4(12) + FN_4(8) + FN_4(4) + FN_4(0) +#else + FN_4(0) + FN_4(4) + FN_4(8) + FN_4(12) +#endif +#undef FN + width -= 16; + src += 4; + } +} + +static void pxa2xx_draw_line4(void *opaque, uint8_t *dest, const uint8_t *src, + int width, int deststep) +{ + uint32_t *palette = opaque; + uint32_t data; + while (width > 0) { + data = *(uint32_t *) src; +#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]); +#ifdef SWAP_WORDS + FN_2(6) + FN_2(4) + FN_2(2) + FN_2(0) +#else + FN_2(0) + FN_2(2) + FN_2(4) + FN_2(6) +#endif +#undef FN + width -= 8; + src += 4; + } +} + +static void pxa2xx_draw_line8(void *opaque, uint8_t *dest, const uint8_t *src, + int width, int deststep) +{ + uint32_t *palette = opaque; + uint32_t data; + while (width > 0) { + data = *(uint32_t *) src; +#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]); +#ifdef SWAP_WORDS + FN(24) + FN(16) + FN(8) + FN(0) +#else + FN(0) + FN(8) + FN(16) + FN(24) +#endif +#undef FN + width -= 4; + src += 4; + } +} + +static void pxa2xx_draw_line16(void *opaque, uint8_t *dest, const uint8_t *src, + int width, int deststep) +{ + uint32_t data; + unsigned int r, g, b; + while (width > 0) { + data = *(uint32_t *) src; +#ifdef SWAP_WORDS + data = bswap32(data); +#endif + b = (data & 0x1f) << 3; + data >>= 5; + g = (data & 0x3f) << 2; + data >>= 6; + r = (data & 0x1f) << 3; + data >>= 5; + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + b = (data & 0x1f) << 3; + data >>= 5; + g = (data & 0x3f) << 2; + data >>= 6; + r = (data & 0x1f) << 3; + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + width -= 2; + src += 4; + } +} + +static void pxa2xx_draw_line16t(void *opaque, uint8_t *dest, const uint8_t *src, + int width, int deststep) +{ + uint32_t data; + unsigned int r, g, b; + while (width > 0) { + data = *(uint32_t *) src; +#ifdef SWAP_WORDS + data = bswap32(data); +#endif + b = (data & 0x1f) << 3; + data >>= 5; + g = (data & 0x1f) << 3; + data >>= 5; + r = (data & 0x1f) << 3; + data >>= 5; + if (data & 1) { + SKIP_PIXEL(dest); + } else { + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + } + data >>= 1; + b = (data & 0x1f) << 3; + data >>= 5; + g = (data & 0x1f) << 3; + data >>= 5; + r = (data & 0x1f) << 3; + data >>= 5; + if (data & 1) { + SKIP_PIXEL(dest); + } else { + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + } + width -= 2; + src += 4; + } +} + +static void pxa2xx_draw_line18(void *opaque, uint8_t *dest, const uint8_t *src, + int width, int deststep) +{ + uint32_t data; + unsigned int r, g, b; + while (width > 0) { + data = *(uint32_t *) src; +#ifdef SWAP_WORDS + data = bswap32(data); +#endif + b = (data & 0x3f) << 2; + data >>= 6; + g = (data & 0x3f) << 2; + data >>= 6; + r = (data & 0x3f) << 2; + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + width -= 1; + src += 4; + } +} + +/* The wicked packed format */ +static void pxa2xx_draw_line18p(void *opaque, uint8_t *dest, const uint8_t *src, + int width, int deststep) +{ + uint32_t data[3]; + unsigned int r, g, b; + while (width > 0) { + data[0] = *(uint32_t *) src; + src += 4; + data[1] = *(uint32_t *) src; + src += 4; + data[2] = *(uint32_t *) src; + src += 4; +#ifdef SWAP_WORDS + data[0] = bswap32(data[0]); + data[1] = bswap32(data[1]); + data[2] = bswap32(data[2]); +#endif + b = (data[0] & 0x3f) << 2; + data[0] >>= 6; + g = (data[0] & 0x3f) << 2; + data[0] >>= 6; + r = (data[0] & 0x3f) << 2; + data[0] >>= 12; + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + b = (data[0] & 0x3f) << 2; + data[0] >>= 6; + g = ((data[1] & 0xf) << 4) | (data[0] << 2); + data[1] >>= 4; + r = (data[1] & 0x3f) << 2; + data[1] >>= 12; + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + b = (data[1] & 0x3f) << 2; + data[1] >>= 6; + g = (data[1] & 0x3f) << 2; + data[1] >>= 6; + r = ((data[2] & 0x3) << 6) | (data[1] << 2); + data[2] >>= 8; + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + b = (data[2] & 0x3f) << 2; + data[2] >>= 6; + g = (data[2] & 0x3f) << 2; + data[2] >>= 6; + r = data[2] << 2; + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + width -= 4; + } +} + +static void pxa2xx_draw_line19(void *opaque, uint8_t *dest, const uint8_t *src, + int width, int deststep) +{ + uint32_t data; + unsigned int r, g, b; + while (width > 0) { + data = *(uint32_t *) src; +#ifdef SWAP_WORDS + data = bswap32(data); +#endif + b = (data & 0x3f) << 2; + data >>= 6; + g = (data & 0x3f) << 2; + data >>= 6; + r = (data & 0x3f) << 2; + data >>= 6; + if (data & 1) { + SKIP_PIXEL(dest); + } else { + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + } + width -= 1; + src += 4; + } +} + +/* The wicked packed format */ +static void pxa2xx_draw_line19p(void *opaque, uint8_t *dest, const uint8_t *src, + int width, int deststep) +{ + uint32_t data[3]; + unsigned int r, g, b; + while (width > 0) { + data[0] = *(uint32_t *) src; + src += 4; + data[1] = *(uint32_t *) src; + src += 4; + data[2] = *(uint32_t *) src; + src += 4; +# ifdef SWAP_WORDS + data[0] = bswap32(data[0]); + data[1] = bswap32(data[1]); + data[2] = bswap32(data[2]); +# endif + b = (data[0] & 0x3f) << 2; + data[0] >>= 6; + g = (data[0] & 0x3f) << 2; + data[0] >>= 6; + r = (data[0] & 0x3f) << 2; + data[0] >>= 6; + if (data[0] & 1) { + SKIP_PIXEL(dest); + } else { + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + } + data[0] >>= 6; + b = (data[0] & 0x3f) << 2; + data[0] >>= 6; + g = ((data[1] & 0xf) << 4) | (data[0] << 2); + data[1] >>= 4; + r = (data[1] & 0x3f) << 2; + data[1] >>= 6; + if (data[1] & 1) { + SKIP_PIXEL(dest); + } else { + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + } + data[1] >>= 6; + b = (data[1] & 0x3f) << 2; + data[1] >>= 6; + g = (data[1] & 0x3f) << 2; + data[1] >>= 6; + r = ((data[2] & 0x3) << 6) | (data[1] << 2); + data[2] >>= 2; + if (data[2] & 1) { + SKIP_PIXEL(dest); + } else { + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + } + data[2] >>= 6; + b = (data[2] & 0x3f) << 2; + data[2] >>= 6; + g = (data[2] & 0x3f) << 2; + data[2] >>= 6; + r = data[2] << 2; + data[2] >>= 6; + if (data[2] & 1) { + SKIP_PIXEL(dest); + } else { + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + } + width -= 4; + } +} + +static void pxa2xx_draw_line24(void *opaque, uint8_t *dest, const uint8_t *src, + int width, int deststep) +{ + uint32_t data; + unsigned int r, g, b; + while (width > 0) { + data = *(uint32_t *) src; +#ifdef SWAP_WORDS + data = bswap32(data); +#endif + b = data & 0xff; + data >>= 8; + g = data & 0xff; + data >>= 8; + r = data & 0xff; + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + width -= 1; + src += 4; + } +} + +static void pxa2xx_draw_line24t(void *opaque, uint8_t *dest, const uint8_t *src, + int width, int deststep) +{ + uint32_t data; + unsigned int r, g, b; + while (width > 0) { + data = *(uint32_t *) src; +#ifdef SWAP_WORDS + data = bswap32(data); +#endif + b = (data & 0x7f) << 1; + data >>= 7; + g = data & 0xff; + data >>= 8; + r = data & 0xff; + data >>= 8; + if (data & 1) { + SKIP_PIXEL(dest); + } else { + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + } + width -= 1; + src += 4; + } +} + +static void pxa2xx_draw_line25(void *opaque, uint8_t *dest, const uint8_t *src, + int width, int deststep) +{ + uint32_t data; + unsigned int r, g, b; + while (width > 0) { + data = *(uint32_t *) src; +#ifdef SWAP_WORDS + data = bswap32(data); +#endif + b = data & 0xff; + data >>= 8; + g = data & 0xff; + data >>= 8; + r = data & 0xff; + data >>= 8; + if (data & 1) { + SKIP_PIXEL(dest); + } else { + COPY_PIXEL(dest, rgb_to_pixel32(r, g, b)); + } + width -= 1; + src += 4; + } +} + +/* Overlay planes disabled, no transparency */ +static drawfn pxa2xx_draw_fn_32[16] = { + [0 ... 0xf] = NULL, + [pxa_lcdc_2bpp] = pxa2xx_draw_line2, + [pxa_lcdc_4bpp] = pxa2xx_draw_line4, + [pxa_lcdc_8bpp] = pxa2xx_draw_line8, + [pxa_lcdc_16bpp] = pxa2xx_draw_line16, + [pxa_lcdc_18bpp] = pxa2xx_draw_line18, + [pxa_lcdc_18pbpp] = pxa2xx_draw_line18p, + [pxa_lcdc_24bpp] = pxa2xx_draw_line24, +}; + +/* Overlay planes enabled, transparency used */ +static drawfn pxa2xx_draw_fn_32t[16] = { + [0 ... 0xf] = NULL, + [pxa_lcdc_4bpp] = pxa2xx_draw_line4, + [pxa_lcdc_8bpp] = pxa2xx_draw_line8, + [pxa_lcdc_16bpp] = pxa2xx_draw_line16t, + [pxa_lcdc_19bpp] = pxa2xx_draw_line19, + [pxa_lcdc_19pbpp] = pxa2xx_draw_line19p, + [pxa_lcdc_24bpp] = pxa2xx_draw_line24t, + [pxa_lcdc_25bpp] = pxa2xx_draw_line25, +}; + +#undef COPY_PIXEL +#undef SKIP_PIXEL + +#ifdef SWAP_WORDS +# undef SWAP_WORDS +#endif + /* Route internal interrupt lines to the global IC */ static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s) { @@ -674,14 +1102,21 @@ static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp) } } +static inline drawfn pxa2xx_drawfn(PXA2xxLCDState *s) +{ + if (s->transp) { + return pxa2xx_draw_fn_32t[s->bpp]; + } else { + return pxa2xx_draw_fn_32[s->bpp]; + } +} + static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s, hwaddr addr, int *miny, int *maxy) { DisplaySurface *surface = qemu_console_surface(s->con); int src_width, dest_width; - drawfn fn = NULL; - if (s->dest_width) - fn = s->line_fn[s->transp][s->bpp]; + drawfn fn = pxa2xx_drawfn(s); if (!fn) return; @@ -693,14 +1128,14 @@ static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s, else if (s->bpp > pxa_lcdc_8bpp) src_width *= 2; - dest_width = s->xres * s->dest_width; + dest_width = s->xres * DEST_PIXEL_WIDTH; *miny = 0; if (s->invalidated) { framebuffer_update_memory_section(&s->fbsection, s->sysmem, addr, s->yres, src_width); } framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres, - src_width, dest_width, s->dest_width, + src_width, dest_width, DEST_PIXEL_WIDTH, s->invalidated, fn, s->dma_ch[0].palette, miny, maxy); } @@ -710,9 +1145,7 @@ static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s, { DisplaySurface *surface = qemu_console_surface(s->con); int src_width, dest_width; - drawfn fn = NULL; - if (s->dest_width) - fn = s->line_fn[s->transp][s->bpp]; + drawfn fn = pxa2xx_drawfn(s); if (!fn) return; @@ -724,14 +1157,14 @@ static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s, else if (s->bpp > pxa_lcdc_8bpp) src_width *= 2; - dest_width = s->yres * s->dest_width; + dest_width = s->yres * DEST_PIXEL_WIDTH; *miny = 0; if (s->invalidated) { framebuffer_update_memory_section(&s->fbsection, s->sysmem, addr, s->yres, src_width); } framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres, - src_width, s->dest_width, -dest_width, + src_width, DEST_PIXEL_WIDTH, -dest_width, s->invalidated, fn, s->dma_ch[0].palette, miny, maxy); @@ -742,10 +1175,7 @@ static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s, { DisplaySurface *surface = qemu_console_surface(s->con); int src_width, dest_width; - drawfn fn = NULL; - if (s->dest_width) { - fn = s->line_fn[s->transp][s->bpp]; - } + drawfn fn = pxa2xx_drawfn(s); if (!fn) { return; } @@ -759,14 +1189,14 @@ static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s, src_width *= 2; } - dest_width = s->xres * s->dest_width; + dest_width = s->xres * DEST_PIXEL_WIDTH; *miny = 0; if (s->invalidated) { framebuffer_update_memory_section(&s->fbsection, s->sysmem, addr, s->yres, src_width); } framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres, - src_width, -dest_width, -s->dest_width, + src_width, -dest_width, -DEST_PIXEL_WIDTH, s->invalidated, fn, s->dma_ch[0].palette, miny, maxy); } @@ -776,10 +1206,7 @@ static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s, { DisplaySurface *surface = qemu_console_surface(s->con); int src_width, dest_width; - drawfn fn = NULL; - if (s->dest_width) { - fn = s->line_fn[s->transp][s->bpp]; - } + drawfn fn = pxa2xx_drawfn(s); if (!fn) { return; } @@ -793,14 +1220,14 @@ static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s, src_width *= 2; } - dest_width = s->yres * s->dest_width; + dest_width = s->yres * DEST_PIXEL_WIDTH; *miny = 0; if (s->invalidated) { framebuffer_update_memory_section(&s->fbsection, s->sysmem, addr, s->yres, src_width); } framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres, - src_width, -s->dest_width, dest_width, + src_width, -DEST_PIXEL_WIDTH, dest_width, s->invalidated, fn, s->dma_ch[0].palette, miny, maxy); @@ -990,17 +1417,6 @@ static const VMStateDescription vmstate_pxa2xx_lcdc = { } }; -#define BITS 8 -#include "pxa2xx_template.h" -#define BITS 15 -#include "pxa2xx_template.h" -#define BITS 16 -#include "pxa2xx_template.h" -#define BITS 24 -#include "pxa2xx_template.h" -#define BITS 32 -#include "pxa2xx_template.h" - static const GraphicHwOps pxa2xx_ops = { .invalidate = pxa2xx_invalidate_display, .gfx_update = pxa2xx_update_display, @@ -1010,7 +1426,6 @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem, hwaddr base, qemu_irq irq) { PXA2xxLCDState *s; - DisplaySurface *surface; s = (PXA2xxLCDState *) g_malloc0(sizeof(PXA2xxLCDState)); s->invalidated = 1; @@ -1024,41 +1439,6 @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem, memory_region_add_subregion(sysmem, base, &s->iomem); s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s); - surface = qemu_console_surface(s->con); - - switch (surface_bits_per_pixel(surface)) { - case 0: - s->dest_width = 0; - break; - case 8: - s->line_fn[0] = pxa2xx_draw_fn_8; - s->line_fn[1] = pxa2xx_draw_fn_8t; - s->dest_width = 1; - break; - case 15: - s->line_fn[0] = pxa2xx_draw_fn_15; - s->line_fn[1] = pxa2xx_draw_fn_15t; - s->dest_width = 2; - break; - case 16: - s->line_fn[0] = pxa2xx_draw_fn_16; - s->line_fn[1] = pxa2xx_draw_fn_16t; - s->dest_width = 2; - break; - case 24: - s->line_fn[0] = pxa2xx_draw_fn_24; - s->line_fn[1] = pxa2xx_draw_fn_24t; - s->dest_width = 3; - break; - case 32: - s->line_fn[0] = pxa2xx_draw_fn_32; - s->line_fn[1] = pxa2xx_draw_fn_32t; - s->dest_width = 4; - break; - default: - fprintf(stderr, "%s: Bad color depth\n", __func__); - exit(1); - } vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s); diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h deleted file mode 100644 index c64eebc4b6..0000000000 --- a/hw/display/pxa2xx_template.h +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Intel XScale PXA255/270 LCDC emulation. - * - * Copyright (c) 2006 Openedhand Ltd. - * Written by Andrzej Zaborowski <balrog@zabor.org> - * - * This code is licensed under the GPLv2. - * - * Framebuffer format conversion routines. - */ - -# define SKIP_PIXEL(to) to += deststep -#if BITS == 8 -# define COPY_PIXEL(to, from) do { *to = from; SKIP_PIXEL(to); } while (0) -#elif BITS == 15 || BITS == 16 -# define COPY_PIXEL(to, from) \ - do { \ - *(uint16_t *) to = from; \ - SKIP_PIXEL(to); \ - } while (0) -#elif BITS == 24 -# define COPY_PIXEL(to, from) \ - do { \ - *(uint16_t *) to = from; \ - *(to + 2) = (from) >> 16; \ - SKIP_PIXEL(to); \ - } while (0) -#elif BITS == 32 -# define COPY_PIXEL(to, from) \ - do { \ - *(uint32_t *) to = from; \ - SKIP_PIXEL(to); \ - } while (0) -#else -# error unknown bit depth -#endif - -#ifdef HOST_WORDS_BIGENDIAN -# define SWAP_WORDS 1 -#endif - -#define FN_2(x) FN(x + 1) FN(x) -#define FN_4(x) FN_2(x + 2) FN_2(x) - -static void glue(pxa2xx_draw_line2_, BITS)(void *opaque, - uint8_t *dest, const uint8_t *src, int width, int deststep) -{ - uint32_t *palette = opaque; - uint32_t data; - while (width > 0) { - data = *(uint32_t *) src; -#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]); -#ifdef SWAP_WORDS - FN_4(12) - FN_4(8) - FN_4(4) - FN_4(0) -#else - FN_4(0) - FN_4(4) - FN_4(8) - FN_4(12) -#endif -#undef FN - width -= 16; - src += 4; - } -} - -static void glue(pxa2xx_draw_line4_, BITS)(void *opaque, - uint8_t *dest, const uint8_t *src, int width, int deststep) -{ - uint32_t *palette = opaque; - uint32_t data; - while (width > 0) { - data = *(uint32_t *) src; -#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]); -#ifdef SWAP_WORDS - FN_2(6) - FN_2(4) - FN_2(2) - FN_2(0) -#else - FN_2(0) - FN_2(2) - FN_2(4) - FN_2(6) -#endif -#undef FN - width -= 8; - src += 4; - } -} - -static void glue(pxa2xx_draw_line8_, BITS)(void *opaque, - uint8_t *dest, const uint8_t *src, int width, int deststep) -{ - uint32_t *palette = opaque; - uint32_t data; - while (width > 0) { - data = *(uint32_t *) src; -#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]); -#ifdef SWAP_WORDS - FN(24) - FN(16) - FN(8) - FN(0) -#else - FN(0) - FN(8) - FN(16) - FN(24) -#endif -#undef FN - width -= 4; - src += 4; - } -} - -static void glue(pxa2xx_draw_line16_, BITS)(void *opaque, - uint8_t *dest, const uint8_t *src, int width, int deststep) -{ - uint32_t data; - unsigned int r, g, b; - while (width > 0) { - data = *(uint32_t *) src; -#ifdef SWAP_WORDS - data = bswap32(data); -#endif - b = (data & 0x1f) << 3; - data >>= 5; - g = (data & 0x3f) << 2; - data >>= 6; - r = (data & 0x1f) << 3; - data >>= 5; - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - b = (data & 0x1f) << 3; - data >>= 5; - g = (data & 0x3f) << 2; - data >>= 6; - r = (data & 0x1f) << 3; - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - width -= 2; - src += 4; - } -} - -static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque, - uint8_t *dest, const uint8_t *src, int width, int deststep) -{ - uint32_t data; - unsigned int r, g, b; - while (width > 0) { - data = *(uint32_t *) src; -#ifdef SWAP_WORDS - data = bswap32(data); -#endif - b = (data & 0x1f) << 3; - data >>= 5; - g = (data & 0x1f) << 3; - data >>= 5; - r = (data & 0x1f) << 3; - data >>= 5; - if (data & 1) - SKIP_PIXEL(dest); - else - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - data >>= 1; - b = (data & 0x1f) << 3; - data >>= 5; - g = (data & 0x1f) << 3; - data >>= 5; - r = (data & 0x1f) << 3; - data >>= 5; - if (data & 1) - SKIP_PIXEL(dest); - else - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - width -= 2; - src += 4; - } -} - -static void glue(pxa2xx_draw_line18_, BITS)(void *opaque, - uint8_t *dest, const uint8_t *src, int width, int deststep) -{ - uint32_t data; - unsigned int r, g, b; - while (width > 0) { - data = *(uint32_t *) src; -#ifdef SWAP_WORDS - data = bswap32(data); -#endif - b = (data & 0x3f) << 2; - data >>= 6; - g = (data & 0x3f) << 2; - data >>= 6; - r = (data & 0x3f) << 2; - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - width -= 1; - src += 4; - } -} - -/* The wicked packed format */ -static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque, - uint8_t *dest, const uint8_t *src, int width, int deststep) -{ - uint32_t data[3]; - unsigned int r, g, b; - while (width > 0) { - data[0] = *(uint32_t *) src; - src += 4; - data[1] = *(uint32_t *) src; - src += 4; - data[2] = *(uint32_t *) src; - src += 4; -#ifdef SWAP_WORDS - data[0] = bswap32(data[0]); - data[1] = bswap32(data[1]); - data[2] = bswap32(data[2]); -#endif - b = (data[0] & 0x3f) << 2; - data[0] >>= 6; - g = (data[0] & 0x3f) << 2; - data[0] >>= 6; - r = (data[0] & 0x3f) << 2; - data[0] >>= 12; - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - b = (data[0] & 0x3f) << 2; - data[0] >>= 6; - g = ((data[1] & 0xf) << 4) | (data[0] << 2); - data[1] >>= 4; - r = (data[1] & 0x3f) << 2; - data[1] >>= 12; - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - b = (data[1] & 0x3f) << 2; - data[1] >>= 6; - g = (data[1] & 0x3f) << 2; - data[1] >>= 6; - r = ((data[2] & 0x3) << 6) | (data[1] << 2); - data[2] >>= 8; - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - b = (data[2] & 0x3f) << 2; - data[2] >>= 6; - g = (data[2] & 0x3f) << 2; - data[2] >>= 6; - r = data[2] << 2; - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - width -= 4; - } -} - -static void glue(pxa2xx_draw_line19_, BITS)(void *opaque, - uint8_t *dest, const uint8_t *src, int width, int deststep) -{ - uint32_t data; - unsigned int r, g, b; - while (width > 0) { - data = *(uint32_t *) src; -#ifdef SWAP_WORDS - data = bswap32(data); -#endif - b = (data & 0x3f) << 2; - data >>= 6; - g = (data & 0x3f) << 2; - data >>= 6; - r = (data & 0x3f) << 2; - data >>= 6; - if (data & 1) - SKIP_PIXEL(dest); - else - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - width -= 1; - src += 4; - } -} - -/* The wicked packed format */ -static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque, - uint8_t *dest, const uint8_t *src, int width, int deststep) -{ - uint32_t data[3]; - unsigned int r, g, b; - while (width > 0) { - data[0] = *(uint32_t *) src; - src += 4; - data[1] = *(uint32_t *) src; - src += 4; - data[2] = *(uint32_t *) src; - src += 4; -# ifdef SWAP_WORDS - data[0] = bswap32(data[0]); - data[1] = bswap32(data[1]); - data[2] = bswap32(data[2]); -# endif - b = (data[0] & 0x3f) << 2; - data[0] >>= 6; - g = (data[0] & 0x3f) << 2; - data[0] >>= 6; - r = (data[0] & 0x3f) << 2; - data[0] >>= 6; - if (data[0] & 1) - SKIP_PIXEL(dest); - else - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - data[0] >>= 6; - b = (data[0] & 0x3f) << 2; - data[0] >>= 6; - g = ((data[1] & 0xf) << 4) | (data[0] << 2); - data[1] >>= 4; - r = (data[1] & 0x3f) << 2; - data[1] >>= 6; - if (data[1] & 1) - SKIP_PIXEL(dest); - else - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - data[1] >>= 6; - b = (data[1] & 0x3f) << 2; - data[1] >>= 6; - g = (data[1] & 0x3f) << 2; - data[1] >>= 6; - r = ((data[2] & 0x3) << 6) | (data[1] << 2); - data[2] >>= 2; - if (data[2] & 1) - SKIP_PIXEL(dest); - else - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - data[2] >>= 6; - b = (data[2] & 0x3f) << 2; - data[2] >>= 6; - g = (data[2] & 0x3f) << 2; - data[2] >>= 6; - r = data[2] << 2; - data[2] >>= 6; - if (data[2] & 1) - SKIP_PIXEL(dest); - else - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - width -= 4; - } -} - -static void glue(pxa2xx_draw_line24_, BITS)(void *opaque, - uint8_t *dest, const uint8_t *src, int width, int deststep) -{ - uint32_t data; - unsigned int r, g, b; - while (width > 0) { - data = *(uint32_t *) src; -#ifdef SWAP_WORDS - data = bswap32(data); -#endif - b = data & 0xff; - data >>= 8; - g = data & 0xff; - data >>= 8; - r = data & 0xff; - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - width -= 1; - src += 4; - } -} - -static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque, - uint8_t *dest, const uint8_t *src, int width, int deststep) -{ - uint32_t data; - unsigned int r, g, b; - while (width > 0) { - data = *(uint32_t *) src; -#ifdef SWAP_WORDS - data = bswap32(data); -#endif - b = (data & 0x7f) << 1; - data >>= 7; - g = data & 0xff; - data >>= 8; - r = data & 0xff; - data >>= 8; - if (data & 1) - SKIP_PIXEL(dest); - else - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - width -= 1; - src += 4; - } -} - -static void glue(pxa2xx_draw_line25_, BITS)(void *opaque, - uint8_t *dest, const uint8_t *src, int width, int deststep) -{ - uint32_t data; - unsigned int r, g, b; - while (width > 0) { - data = *(uint32_t *) src; -#ifdef SWAP_WORDS - data = bswap32(data); -#endif - b = data & 0xff; - data >>= 8; - g = data & 0xff; - data >>= 8; - r = data & 0xff; - data >>= 8; - if (data & 1) - SKIP_PIXEL(dest); - else - COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b)); - width -= 1; - src += 4; - } -} - -/* Overlay planes disabled, no transparency */ -static drawfn glue(pxa2xx_draw_fn_, BITS)[16] = -{ - [0 ... 0xf] = NULL, - [pxa_lcdc_2bpp] = glue(pxa2xx_draw_line2_, BITS), - [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS), - [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS), - [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16_, BITS), - [pxa_lcdc_18bpp] = glue(pxa2xx_draw_line18_, BITS), - [pxa_lcdc_18pbpp] = glue(pxa2xx_draw_line18p_, BITS), - [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24_, BITS), -}; - -/* Overlay planes enabled, transparency used */ -static drawfn glue(glue(pxa2xx_draw_fn_, BITS), t)[16] = -{ - [0 ... 0xf] = NULL, - [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS), - [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS), - [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16t_, BITS), - [pxa_lcdc_19bpp] = glue(pxa2xx_draw_line19_, BITS), - [pxa_lcdc_19pbpp] = glue(pxa2xx_draw_line19p_, BITS), - [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24t_, BITS), - [pxa_lcdc_25bpp] = glue(pxa2xx_draw_line25_, BITS), -}; - -#undef BITS -#undef COPY_PIXEL -#undef SKIP_PIXEL - -#ifdef SWAP_WORDS -# undef SWAP_WORDS -#endif |