* [Qemu-devel] [PATCH 5 of 6] [UPDATE] sdl shared buffer support
@ 2008-09-08 16:11 Stefano Stabellini
0 siblings, 0 replies; only message in thread
From: Stefano Stabellini @ 2008-09-08 16:11 UTC (permalink / raw)
To: qemu-devel
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 <stefano.stabellini@eu.citrix.com>
---
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..40b6c5a 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_colordepth(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_colordepth(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_colordepth(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;
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2008-09-08 16:14 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-08 16:11 [Qemu-devel] [PATCH 5 of 6] [UPDATE] sdl shared buffer support Stefano Stabellini
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.