qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] sdl shared buffer support


From: Stefano Stabellini
Subject: [Qemu-devel] [PATCH] sdl shared buffer support
Date: Fri, 29 Aug 2008 16:21:30 +0100
User-agent: Thunderbird 2.0.0.14 (X11/20080505)

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.

Obviously this patch depends upon the previous shared buffer patch.

Signed-off-by: Stefano Stabellini <address@hidden>

---

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..8e78323 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,78 @@ 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 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 +132,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 +141,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 +408,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 +708,9 @@ void sdl_display_init(DisplayState *ds, int
full_screen, int no_frame)

     ds->dpy_update = sdl_update;
     ds->dpy_resize = sdl_resize;
+    ds->dpy_resize_shared = sdl_resize_shared;
     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;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]