static void sdl_resize(DisplayState *ds) { if (!scaling_active) { do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0); } else if (real_screen->format->BitsPerPixel != ds_get_bits_per_pixel(ds)) { do_sdl_resize(real_screen->w, real_screen->h, ds_get_bits_per_pixel(ds)); } sdl_setdata(ds); }
static void sdl_resize(DisplayState *ds) { if (!allocator) { if (!scaling_active) do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0); else if (real_screen->format->BitsPerPixel != ds_get_bits_per_pixel(ds)) do_sdl_resize(real_screen->w, real_screen->h, ds_get_bits_per_pixel(ds)); sdl_setdata(ds); } else { if (guest_screen != NULL) { SDL_FreeSurface(guest_screen); guest_screen = NULL; } } }
static void g364fb_draw_graphic8(G364State *s) { int i, w; uint8_t *vram; uint8_t *data_display, *dd; ram_addr_t page, page_min, page_max; int x, y; int xmin, xmax; int ymin, ymax; int xcursor, ycursor; unsigned int (*rgb_to_pixel)(unsigned int r, unsigned int g, unsigned int b); switch (ds_get_bits_per_pixel(s->ds)) { case 8: rgb_to_pixel = rgb_to_pixel8; w = 1; break; case 15: rgb_to_pixel = rgb_to_pixel15; w = 2; break; case 16: rgb_to_pixel = rgb_to_pixel16; w = 2; break; case 32: rgb_to_pixel = rgb_to_pixel32; w = 4; break; default: BADF("unknown host depth %d\n", ds_get_bits_per_pixel(s->ds)); return; } page = s->vram_offset; page_min = (ram_addr_t)-1; page_max = 0; x = y = 0; xmin = s->width; xmax = 0; ymin = s->height; ymax = 0; if (!(s->ctla & CTLA_NO_CURSOR)) { xcursor = s->cursor_position >> 12; ycursor = s->cursor_position & 0xfff; } else {
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 toggle_full_screen(DisplayState *ds) { gui_fullscreen = !gui_fullscreen; if (gui_fullscreen) { gui_saved_width = real_screen->w; gui_saved_height = real_screen->h; gui_saved_scaling = scaling_active; do_sdl_resize(ds_get_width(ds), ds_get_height(ds), ds_get_bits_per_pixel(ds)); scaling_active = 0; gui_saved_grab = gui_grab; sdl_grab_start(); } else { if (gui_saved_scaling) { sdl_scale(ds, gui_saved_width, gui_saved_height); } else { do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0); } if (!gui_saved_grab || !is_graphic_console()) { sdl_grab_end(); } } vga_hw_invalidate(); vga_hw_update(); }
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++; } }
PXA2xxLCDState *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq) { int iomemtype; PXA2xxLCDState *s; s = (PXA2xxLCDState *) qemu_mallocz(sizeof(PXA2xxLCDState)); s->invalidated = 1; s->irq = irq; pxa2xx_lcdc_orientation(s, graphic_rotate); iomemtype = cpu_register_io_memory(pxa2xx_lcdc_readfn, pxa2xx_lcdc_writefn, s); cpu_register_physical_memory(base, 0x00100000, iomemtype); s->ds = graphic_console_init(pxa2xx_update_display, pxa2xx_invalidate_display, pxa2xx_screen_dump, NULL, s); switch (ds_get_bits_per_pixel(s->ds)) { 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", __FUNCTION__); exit(1); } register_savevm("pxa2xx_lcdc", 0, 0, pxa2xx_lcdc_save, pxa2xx_lcdc_load, s); return s; }
static void vgafb_update_display(void *opaque) { MilkymistVgafbState *s = opaque; int first = 0; int last = 0; drawfn fn; if (!vgafb_enabled(s)) { return; } int dest_width = s->regs[R_HRES]; switch (ds_get_bits_per_pixel(s->ds)) { case 0: return; case 8: fn = draw_line_8; break; case 15: fn = draw_line_15; dest_width *= 2; break; case 16: fn = draw_line_16; dest_width *= 2; break; case 24: fn = draw_line_24; dest_width *= 3; break; case 32: fn = draw_line_32; dest_width *= 4; break; default: hw_error("milkymist_vgafb: bad color depth\n"); break; } framebuffer_update_display(s->ds, s->regs[R_BASEADDRESS] + s->fb_offset, s->regs[R_HRES], s->regs[R_VRES], s->regs[R_HRES] * 2, dest_width, 0, s->invalidate, fn, NULL, &first, &last); if (first >= 0) { dpy_update(s->ds, 0, first, s->regs[R_HRES], last - first + 1); } s->invalidate = 0; }
static void sdl_setdata(DisplayState *ds) { if (guest_screen != NULL) SDL_FreeSurface(guest_screen); guest_screen = SDL_CreateRGBSurfaceFrom(ds_get_data(ds), ds_get_width(ds), ds_get_height(ds), ds_get_bits_per_pixel(ds), ds_get_linesize(ds), ds->surface->pf.rmask, ds->surface->pf.gmask, ds->surface->pf.bmask, ds->surface->pf.amask); }
static void opengl_setdata(DisplayState *ds) { glEnable(GL_TEXTURE_RECTANGLE_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glClearColor(0, 0, 0, 0); glDisable(GL_BLEND); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glDisable(GL_CULL_FACE); glViewport( 0, 0, real_screen->w, real_screen->h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, real_screen->w, real_screen->h, 0, -1,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT); if (texture_ref) { glDeleteTextures(1, &texture_ref); texture_ref = 0; } glGenTextures(1, &texture_ref); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_ref); glPixelStorei(GL_UNPACK_LSB_FIRST, 1); switch (ds_get_bits_per_pixel(ds)) { case 16: tex_format = GL_RGB; tex_type = GL_UNSIGNED_SHORT_5_6_5; break; case 24: tex_format = GL_BGR; tex_type = GL_UNSIGNED_BYTE; break; case 32: if (bgr == (ds->surface->pf.rshift < ds->surface->pf.bshift)) { tex_format = GL_BGRA; tex_type = GL_UNSIGNED_BYTE; } else { tex_format = GL_RGBA; tex_type = GL_UNSIGNED_BYTE; } break; } glPixelStorei(GL_UNPACK_ROW_LENGTH, (ds_get_linesize(ds) / ds_get_bytes_per_pixel(ds))); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, gl_format, ds_get_width(ds), ds_get_height(ds), 0, tex_format, tex_type, ds_get_data(ds)); glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_PRIORITY, 1.0); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); }
/* * This copies data from the guest framebuffer region, into QEMU's * displaysurface. qemu uses 16 or 32 bpp. In case the pv framebuffer * uses something else we must convert and copy, otherwise we can * supply the buffer directly and no thing here. */ static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h) { int line, oops = 0; int bpp = ds_get_bits_per_pixel(xenfb->c.ds); int linesize = ds_get_linesize(xenfb->c.ds); uint8_t *data = ds_get_data(xenfb->c.ds); if (!is_buffer_shared(xenfb->c.ds->surface)) { switch (xenfb->depth) { case 8: if (bpp == 16) { BLT(uint8_t, uint16_t, 3, 3, 2, 5, 6, 5); } else if (bpp == 32) { BLT(uint8_t, uint32_t, 3, 3, 2, 8, 8, 8); } else { oops = 1; } break; case 24: if (bpp == 16) { BLT(uint32_t, uint16_t, 8, 8, 8, 5, 6, 5); } else if (bpp == 32) { BLT(uint32_t, uint32_t, 8, 8, 8, 8, 8, 8); } else { oops = 1; } break; default: oops = 1; } } if (oops) /* should not happen */ xen_be_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n", __FUNCTION__, xenfb->depth, bpp); dpy_update(xenfb->c.ds, x, y, w, h); }
static void tcx24_update_display(void *opaque) { TCXState *ts = opaque; ram_addr_t page, page_min, page_max, cpage, page24; int y, y_start, dd, ds; uint8_t *d, *s; uint32_t *cptr, *s24; if (ds_get_bits_per_pixel(ts->ds) != 32) return; page = 0; page24 = ts->vram24_offset; cpage = ts->cplane_offset; y_start = -1; page_min = -1; page_max = 0; d = ds_get_data(ts->ds); s = ts->vram; s24 = ts->vram24; cptr = ts->cplane; dd = ds_get_linesize(ts->ds); ds = 1024; for(y = 0; y < ts->height; y += 4, page += TARGET_PAGE_SIZE, page24 += TARGET_PAGE_SIZE, cpage += TARGET_PAGE_SIZE) { if (check_dirty(ts, page, page24, cpage)) { if (y_start < 0) y_start = y; if (page < page_min) page_min = page; if (page > page_max) page_max = page; tcx24_draw_line32(ts, d, s, ts->width, cptr, s24); d += dd; s += ds; cptr += ds; s24 += ds; tcx24_draw_line32(ts, d, s, ts->width, cptr, s24); d += dd; s += ds; cptr += ds; s24 += ds; tcx24_draw_line32(ts, d, s, ts->width, cptr, s24); d += dd; s += ds; cptr += ds; s24 += ds; tcx24_draw_line32(ts, d, s, ts->width, cptr, s24); d += dd; s += ds; cptr += ds; s24 += ds; } else { if (y_start >= 0) { /* flush to display */ dpy_update(ts->ds, 0, y_start, ts->width, y - y_start); y_start = -1; } d += dd * 4; s += ds * 4; cptr += ds * 4; s24 += ds * 4; } } if (y_start >= 0) { /* flush to display */ dpy_update(ts->ds, 0, y_start, ts->width, y - y_start); } /* reset modified pages */ if (page_max >= page_min) { reset_dirty(ts, page_min, page_max, page24, cpage); } }
/* Fixed line length 1024 allows us to do nice tricks not possible on VGA... */ static void tcx_update_display(void *opaque) { TCXState *ts = opaque; ram_addr_t page, page_min, page_max; int y, y_start, dd, ds; uint8_t *d, *s; void (*f)(TCXState *s1, uint8_t *dst, const uint8_t *src, int width); if (ds_get_bits_per_pixel(ts->ds) == 0) return; page = 0; y_start = -1; page_min = -1; page_max = 0; d = ds_get_data(ts->ds); s = ts->vram; dd = ds_get_linesize(ts->ds); ds = 1024; switch (ds_get_bits_per_pixel(ts->ds)) { case 32: f = tcx_draw_line32; break; case 15: case 16: f = tcx_draw_line16; break; default: case 8: f = tcx_draw_line8; break; case 0: return; } for(y = 0; y < ts->height; y += 4, page += TARGET_PAGE_SIZE) { if (memory_region_get_dirty(&ts->vram_mem, page, TARGET_PAGE_SIZE, DIRTY_MEMORY_VGA)) { if (y_start < 0) y_start = y; if (page < page_min) page_min = page; if (page > page_max) page_max = page; f(ts, d, s, ts->width); d += dd; s += ds; f(ts, d, s, ts->width); d += dd; s += ds; f(ts, d, s, ts->width); d += dd; s += ds; f(ts, d, s, ts->width); d += dd; s += ds; } else { if (y_start >= 0) { /* flush to display */ dpy_update(ts->ds, 0, y_start, ts->width, y - y_start); y_start = -1; } d += dd * 4; s += ds * 4; } } if (y_start >= 0) { /* flush to display */ dpy_update(ts->ds, 0, y_start, ts->width, y - y_start); } /* reset modified pages */ if (page_max >= page_min) { memory_region_reset_dirty(&ts->vram_mem, page_min, page_max + TARGET_PAGE_SIZE, DIRTY_MEMORY_VGA); } }
static void pl110_update_display(void *opaque) { pl110_state *s = (pl110_state *)opaque; drawfn* fntable; drawfn fn; int dest_width; int src_width; int bpp_offset; int first; int last; if (!pl110_enabled(s)) return; switch (ds_get_bits_per_pixel(s->ds)) { 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 bpp_offset = 18; if (s->cr & PL110_CR_BEBO) fn = fntable[s->bpp + 6 + bpp_offset]; else if (s->cr & PL110_CR_BEPO) fn = fntable[s->bpp + 12 + bpp_offset]; else fn = fntable[s->bpp + bpp_offset]; src_width = s->cols; switch (s->bpp) { case BPP_1: src_width >>= 3; break; case BPP_2: src_width >>= 2; break; case BPP_4: src_width >>= 1; break; case BPP_8: break; case BPP_16: src_width <<= 1; break; case BPP_32: src_width <<= 2; break; } dest_width *= s->cols; first = 0; framebuffer_update_display(s->ds, s->upbase, s->cols, s->rows, src_width, dest_width, 0, s->invalidate, fn, s->pallette, &first, &last); if (first >= 0) { dpy_update(s->ds, 0, first, s->cols, last - first + 1); } s->invalidate = 0; }
static void bcm2708_fb_update(void *_opaque) { struct bcm2708_vc *vc = _opaque; drawfn* fntable; drawfn fn; int dest_width; int src_width; int bpp_offset; int first; int last; switch (ds_get_bits_per_pixel(vc->disp)) { 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, "bcm2708: Bad color depth\n"); exit(1); } bpp_offset = 0; fn = fntable[vc->fb_bpp + bpp_offset]; src_width = vc->fb.xres; switch (vc->fb_bpp) { case BPP_1: src_width >>= 3; break; case BPP_2: src_width >>= 2; break; case BPP_4: src_width >>= 1; break; case BPP_8: break; case BPP_16: case BPP_16_565: case BPP_12: src_width <<= 1; break; case BPP_32: src_width <<= 2; break; } dest_width *= vc->fb.xres; first = 0; framebuffer_update_display(vc->disp, get_system_memory(), vc->fb.base, vc->fb.xres, vc->fb.yres, src_width, dest_width, 0, vc->fb_invalidate, fn, NULL, &first, &last); if (first >= 0) { dpy_update(vc->disp, 0, first, vc->fb.xres, last - first + 1); } vc->fb_invalidate = 0; }
/* Load new palette for a given DMA channel, convert to internal format */ static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp) { 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 = *(uint16_t *) src & (1 << 24); 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 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 & 0xf80000) >> 16; g = (*(uint32_t *) src & 0x00fc00) >> 8; b = (*(uint32_t *) src & 0x0000f8); } 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 (ds_get_bits_per_pixel(s->ds)) { 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 ++; } }