From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KbFmI-0002aB-Hs for qemu-devel@nongnu.org; Thu, 04 Sep 2008 10:25:42 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KbFmG-0002Yw-Sv for qemu-devel@nongnu.org; Thu, 04 Sep 2008 10:25:41 -0400 Received: from [199.232.76.173] (port=42779 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KbFmG-0002Yk-LM for qemu-devel@nongnu.org; Thu, 04 Sep 2008 10:25:40 -0400 Received: from smtp.eu.citrix.com ([62.200.22.115]:10044) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KbFmG-0004V4-Ek for qemu-devel@nongnu.org; Thu, 04 Sep 2008 10:25:40 -0400 Message-ID: <48BFF045.2030303@eu.citrix.com> Date: Thu, 04 Sep 2008 15:27:17 +0100 From: Stefano Stabellini MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH 4 of 5] sdl shared buffer support Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This patch implements shared buffer support in sdl.c. It also supports paletted 8 bit colour depths using the palette functions provided by the SDL library. Signed-off-by: Stefano Stabellini --- diff --git a/console.h b/console.h index a054d97..7d252b7 100644 --- a/console.h +++ b/console.h @@ -81,6 +81,7 @@ struct DisplayState { int width; int height; void *opaque; + uint32_t *palette; struct QEMUTimer *gui_timer; uint64_t gui_timer_interval; int idle; /* there is nothing to update (window invisible), set by vnc/sdl */ diff --git a/hw/vga.c b/hw/vga.c index 6e40d3d..d5265c0 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -2026,6 +2026,7 @@ void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, s->vram_offset = vga_ram_offset; s->vram_size = vga_ram_size; s->ds = ds; + ds->palette = s->last_palette; s->get_bpp = vga_get_bpp; s->get_offsets = vga_get_offsets; s->get_resolution = vga_get_resolution; diff --git a/sdl.c b/sdl.c index 15427c5..4b104b0 100644 --- a/sdl.c +++ b/sdl.c @@ -32,6 +32,7 @@ #endif static SDL_Surface *screen; +static SDL_Surface *shared; static int gui_grab; /* if true, all keyboard/mouse events are grabbed */ static int last_vm_running; static int gui_saved_grab; @@ -50,21 +51,83 @@ static int guest_cursor = 0; static int guest_x, guest_y; static SDL_Cursor *guest_sprite = 0; +static void sdl_colourdepth(DisplayState *ds, int depth); + static void sdl_update(DisplayState *ds, int x, int y, int w, int h) { // printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h); - SDL_UpdateRect(screen, x, y, w, h); + if (shared) { + SDL_Rect rec; + rec.x = x; + rec.y = y; + rec.w = w; + rec.h = h; + SDL_BlitSurface(shared, &rec, screen, &rec); + } + SDL_Flip(screen); } -static void sdl_resize(DisplayState *ds, int w, int h) +static void sdl_setdata(DisplayState *ds, void *pixels) +{ + uint32_t rmask, gmask, bmask, amask = 0; + switch (ds->depth) { + case 8: + rmask = 0x000000E0; + gmask = 0x0000001C; + bmask = 0x00000003; + break; + case 15: + rmask = 0x0000F800; + gmask = 0x000007C0; + bmask = 0x0000003E; + break; + case 16: + rmask = 0x0000F800; + gmask = 0x000007E0; + bmask = 0x0000001F; + break; + case 24: + rmask = 0x00FF0000; + gmask = 0x0000FF00; + bmask = 0x000000FF; + break; + case 32: + rmask = 0x00FF0000; + gmask = 0x0000FF00; + bmask = 0x000000FF; + break; + default: + return; + } + shared = SDL_CreateRGBSurfaceFrom(pixels, width, height, ds->depth, ds->linesize, rmask , gmask, bmask, amask); + if (ds->depth == 8 && ds->palette != NULL) { + SDL_Color palette[256]; + int i; + for (i = 0; i < 256; i++) { + uint8_t rgb = ds->palette[i] >> 16; + palette[i].r = ((rgb & 0xe0) >> 5) * 255 / 7; + palette[i].g = ((rgb & 0x1c) >> 2) * 255 / 7; + palette[i].b = (rgb & 0x3) * 255 / 3; + } + SDL_SetColors(shared, palette, 0, 256); + } + ds->data = pixels; +} + +static void sdl_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels) { int flags; // printf("resizing to %d %d\n", w, h); - flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL; - if (gui_fullscreen) + sdl_colourdepth(ds, depth); + + flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_DOUBLEBUF|SDL_HWPALETTE; + + if (gui_fullscreen) { flags |= SDL_FULLSCREEN; + flags &= ~SDL_RESIZABLE; + } if (gui_noframe) flags |= SDL_NOFRAME; @@ -74,7 +137,7 @@ static void sdl_resize(DisplayState *ds, int w, int h) again: screen = SDL_SetVideoMode(w, h, 0, flags); if (!screen) { - fprintf(stderr, "Could not open SDL display\n"); + fprintf(stderr, "Could not open SDL display: %s\n", SDL_GetError()); exit(1); } if (!screen->pixels && (flags & SDL_HWSURFACE) && (flags & SDL_FULLSCREEN)) { @@ -83,30 +146,41 @@ static void sdl_resize(DisplayState *ds, int w, int h) } if (!screen->pixels) { - fprintf(stderr, "Could not open SDL display\n"); + fprintf(stderr, "Could not open SDL display: %s\n", SDL_GetError()); exit(1); } - ds->data = screen->pixels; - ds->linesize = screen->pitch; - ds->depth = screen->format->BitsPerPixel; - /* SDL BitsPerPixel never indicates any values other than - multiples of 8, so we need to check for strange depths. */ - if (ds->depth == 16) { - uint32_t mask; - - mask = screen->format->Rmask; - mask |= screen->format->Gmask; - mask |= screen->format->Bmask; - if ((mask & 0x8000) == 0) - ds->depth = 15; - } - if (ds->depth == 32 && screen->format->Rshift == 0) { - ds->bgr = 1; - } else { - ds->bgr = 0; - } ds->width = w; ds->height = h; + if (!ds->shared_buf) { + ds->depth = screen->format->BitsPerPixel; + if (screen->format->Bshift > screen->format->Rshift) { + ds->bgr = 1; + } else { + ds->bgr = 0; + } + shared = NULL; + ds->data = screen->pixels; + ds->linesize = screen->pitch; + } else { + ds->linesize = linesize; + } + if (ds->shared_buf) ds->dpy_setdata(ds, pixels); +} + +static void sdl_resize(DisplayState *ds, int w, int h) +{ + sdl_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL); +} + +static void sdl_colourdepth(DisplayState *ds, int depth) +{ + if (!depth || !ds->depth) { + ds->shared_buf = 0; + ds->dpy_update = sdl_update; + return; + } + ds->shared_buf = 1; + ds->depth = depth; } /* generic keyboard conversion */ @@ -339,7 +413,7 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state static void toggle_full_screen(DisplayState *ds) { gui_fullscreen = !gui_fullscreen; - sdl_resize(ds, screen->w, screen->h); + sdl_resize_shared(ds, ds->width, ds->height, ds->depth, ds->linesize, ds->data); if (gui_fullscreen) { gui_saved_grab = gui_grab; sdl_grab_start(); @@ -639,7 +713,11 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) ds->dpy_update = sdl_update; ds->dpy_resize = sdl_resize; +#if defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) + ds->dpy_resize_shared = sdl_resize_shared; +#endif ds->dpy_refresh = sdl_refresh; + ds->dpy_setdata = sdl_setdata; ds->dpy_fill = sdl_fill; ds->mouse_set = sdl_mouse_warp; ds->cursor_define = sdl_mouse_define;