qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 4 of 5] sdl shared buffer support


From: Stefano Stabellini
Subject: [Qemu-devel] [PATCH 4 of 5] sdl shared buffer support
Date: Thu, 04 Sep 2008 15:27:17 +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.

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..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;




reply via email to

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