/* XXX Could be much more optimal: * detect if line/page/whole screen is in 24 bit mode * if destination is also BGR, use memcpy */ static inline void tcx24_draw_line32(TCXState *s1, uint8_t *d, const uint8_t *s, int width, const uint32_t *cplane, const uint32_t *s24) { int x, bgr, r, g, b; uint8_t val, *p8; uint32_t *p = (uint32_t *)d; uint32_t dval; bgr = is_surface_bgr(s1->ds->surface); for(x = 0; x < width; x++, s++, s24++) { if ((be32_to_cpu(*cplane++) & 0xff000000) == 0x03000000) { // 24-bit direct, BGR order p8 = (uint8_t *)s24; p8++; b = *p8++; g = *p8++; r = *p8; if (bgr) dval = rgb_to_pixel32bgr(r, g, b); else dval = rgb_to_pixel32(r, g, b); } else { val = *s; dval = s1->palette[val]; } *p++ = dval; } }
static void update_palette_entries(TCXState *s, int start, int end) { int i; for(i = start; i < end; i++) { switch(ds_get_bits_per_pixel(s->ds)) { default: case 8: s->palette[i] = rgb_to_pixel8(s->r[i], s->g[i], s->b[i]); break; case 15: s->palette[i] = rgb_to_pixel15(s->r[i], s->g[i], s->b[i]); break; case 16: s->palette[i] = rgb_to_pixel16(s->r[i], s->g[i], s->b[i]); break; case 32: if (is_surface_bgr(s->ds->surface)) s->palette[i] = rgb_to_pixel32bgr(s->r[i], s->g[i], s->b[i]); else s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]); break; } } if (s->depth == 24) { tcx24_set_dirty(s); } else { tcx_set_dirty(s); } }
static void pl110_update_pallette(pl110_state *s, int n) { int i; uint32_t raw; unsigned int r, g, b; raw = s->raw_pallette[n]; n <<= 1; for (i = 0; i < 2; i++) { r = (raw & 0x1f) << 3; raw >>= 5; g = (raw & 0x1f) << 3; raw >>= 5; b = (raw & 0x1f) << 3; /* The I bit is ignored. */ raw >>= 6; switch (ds_get_bits_per_pixel(s->ds)) { case 8: s->pallette[n] = rgb_to_pixel8(r, g, b); break; case 15: s->pallette[n] = rgb_to_pixel15(r, g, b); break; case 16: s->pallette[n] = rgb_to_pixel16(r, g, b); break; case 24: case 32: s->pallette[n] = rgb_to_pixel32(r, g, b); break; } n++; } }
/* Note: This function must be called with state lock held */ static void __pl110_palette_update(struct pl110_state *s, int bpp, int n) { int i; u32 raw; unsigned int r, g, b; raw = s->raw_palette[n]; n <<= 1; for (i = 0; i < 2; i++) { r = (raw & 0x1f) << 3; raw >>= 5; g = (raw & 0x1f) << 3; raw >>= 5; b = (raw & 0x1f) << 3; /* The I bit is ignored. */ raw >>= 6; switch (bpp) { case 8: s->palette8[n] = rgb_to_pixel8(r, g, b); break; case 15: s->palette15[n] = rgb_to_pixel15(r, g, b); break; case 16: s->palette16[n] = rgb_to_pixel16(r, g, b); break; case 24: case 32: s->palette32[n] = rgb_to_pixel32(r, g, b); break; }; n++; } }
static void update_palette_entries(TCXState *s, int start, int end) { DisplaySurface *surface = qemu_console_surface(s->con); int i; for (i = start; i < end; i++) { switch (surface_bits_per_pixel(surface)) { default: case 8: s->palette[i] = rgb_to_pixel8(s->r[i], s->g[i], s->b[i]); break; case 15: s->palette[i] = rgb_to_pixel15(s->r[i], s->g[i], s->b[i]); break; case 16: s->palette[i] = rgb_to_pixel16(s->r[i], s->g[i], s->b[i]); break; case 32: if (is_surface_bgr(surface)) { s->palette[i] = rgb_to_pixel32bgr(s->r[i], s->g[i], s->b[i]); } else { s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]); } break; } } if (s->depth == 24) { tcx24_set_dirty(s); } else { tcx_set_dirty(s); } }
/* Load new palette for a given DMA channel, convert to internal format */ static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp) { DisplaySurface *surface = qemu_console_surface(s->con); int i, n, format, r, g, b, alpha; uint32_t *dest; uint8_t *src; s->pal_for = LCCR4_PALFOR(s->control[4]); format = s->pal_for; switch (bpp) { case pxa_lcdc_2bpp: n = 4; break; case pxa_lcdc_4bpp: n = 16; break; case pxa_lcdc_8bpp: n = 256; break; default: format = 0; return; } src = (uint8_t *) s->dma_ch[ch].pbuffer; dest = (uint32_t *) s->dma_ch[ch].palette; alpha = r = g = b = 0; for (i = 0; i < n; i ++) { switch (format) { case 0: /* 16 bpp, no transparency */ alpha = 0; if (s->control[0] & LCCR0_CMS) { r = g = b = *(uint16_t *) src & 0xff; } else { r = (*(uint16_t *) src & 0xf800) >> 8; g = (*(uint16_t *) src & 0x07e0) >> 3; b = (*(uint16_t *) src & 0x001f) << 3; } src += 2; break; case 1: /* 16 bpp plus transparency */ alpha = *(uint32_t *) src & (1 << 24); if (s->control[0] & LCCR0_CMS) r = g = b = *(uint32_t *) src & 0xff; else { r = (*(uint32_t *) src & 0xf80000) >> 16; g = (*(uint32_t *) src & 0x00fc00) >> 8; b = (*(uint32_t *) src & 0x0000f8); } src += 4; break; case 2: /* 18 bpp plus transparency */ alpha = *(uint32_t *) src & (1 << 24); if (s->control[0] & LCCR0_CMS) r = g = b = *(uint32_t *) src & 0xff; else { r = (*(uint32_t *) src & 0xfc0000) >> 16; g = (*(uint32_t *) src & 0x00fc00) >> 8; b = (*(uint32_t *) src & 0x0000fc); } src += 4; break; case 3: /* 24 bpp plus transparency */ alpha = *(uint32_t *) src & (1 << 24); if (s->control[0] & LCCR0_CMS) r = g = b = *(uint32_t *) src & 0xff; else { r = (*(uint32_t *) src & 0xff0000) >> 16; g = (*(uint32_t *) src & 0x00ff00) >> 8; b = (*(uint32_t *) src & 0x0000ff); } src += 4; break; } switch (surface_bits_per_pixel(surface)) { case 8: *dest = rgb_to_pixel8(r, g, b) | alpha; break; case 15: *dest = rgb_to_pixel15(r, g, b) | alpha; break; case 16: *dest = rgb_to_pixel16(r, g, b) | alpha; break; case 24: *dest = rgb_to_pixel24(r, g, b) | alpha; break; case 32: *dest = rgb_to_pixel32(r, g, b) | alpha; break; } dest ++; } }
static void sm_lcd_update_display(void *arg) { lcd_state *s = arg; uint8_t *d; uint32_t colour_on, colour_off, colour; int x, y, bpp; DisplaySurface *surface = qemu_console_surface(s->con); bpp = surface_bits_per_pixel(surface); d = surface_data(surface); // If vibrate is on, simply jiggle the display if (s->vibrate_on) { if (s->vibrate_offset == 0) { s->vibrate_offset = 2; } int bytes_per_pixel; switch (bpp) { case 8: bytes_per_pixel = 1; break; case 15: case 16: bytes_per_pixel = 2; break; case 32: bytes_per_pixel = 4; break; default: abort(); } int total_bytes = NUM_ROWS * NUM_COLS * bytes_per_pixel - abs(s->vibrate_offset) * bytes_per_pixel; if (s->vibrate_offset > 0) { memmove(d, d + s->vibrate_offset * bytes_per_pixel, total_bytes); } else { memmove(d - s->vibrate_offset * bytes_per_pixel, d, total_bytes); } s->vibrate_offset *= -1; dpy_gfx_update(s->con, 0, 0, NUM_COLS, NUM_ROWS); return; } if (!s->redraw) { return; } // Adjust the white level to compensate for the set brightness. // brightness = 0: 255 in maps to 170 out // brightness = 1.0: 255 in maps to 255 out float brightness = s->backlight_enabled ? s->brightness : 0.0; int max_val = 170 + (255 - 170) * brightness; /* set colours according to bpp */ switch (bpp) { case 8: colour_on = rgb_to_pixel8(max_val, max_val, max_val); colour_off = rgb_to_pixel8(0x00, 0x00, 0x00); break; case 15: colour_on = rgb_to_pixel15(max_val, max_val, max_val); colour_off = rgb_to_pixel15(0x00, 0x00, 0x00); break; case 16: colour_on = rgb_to_pixel16(max_val, max_val, max_val); colour_off = rgb_to_pixel16(0x00, 0x00, 0x00); case 24: colour_on = rgb_to_pixel24(max_val, max_val, max_val); colour_off = rgb_to_pixel24(0x00, 0x00, 0x00); break; case 32: colour_on = rgb_to_pixel32(max_val, max_val, max_val); colour_off = rgb_to_pixel32(0x00, 0x00, 0x00); break; default: return; } for (y = 0; y < NUM_ROWS; y++) { for (x = 0; x < NUM_COLS; x++) { /* Rotate display - installed 'upside-down' in pebble. */ int xr = NUM_COLS - 1 - x; int yr = NUM_ROWS - 1 - y; bool on = s->framebuffer[yr * NUM_COL_BYTES + xr / 8] & 1 << (xr % 8); colour = on ? colour_on : colour_off; switch(bpp) { case 8: *((uint8_t *)d) = colour; d++; break; case 15: case 16: *((uint16_t *)d) = colour; d += 2; break; case 24: abort(); case 32: *((uint32_t *)d) = colour; d += 4; break; } } } dpy_gfx_update(s->con, 0, 0, NUM_COLS, NUM_ROWS); s->redraw = false; }