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

[Xen-changelog] [xen-unstable] ioemu: sdl blitting



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1204542391 0
# Node ID 69bb0c4af952485fdf5fed06a62693e9052259d0
# Parent  be143a3a90c693cc2df743004abb83932d668f1d
ioemu: sdl blitting

Right now qemu takes care of converting pixels between the guest pixel
format and the sdl pixel format, after that qemu also memcpy the
converted pixels to the sdl buffer in video ram. This process can be
improved using the SDL blit capabilities: the patch I am attaching
creates an SDL Surface from the Cirrus VGA framebuffer and uses SDL
blitting functions to convert and write pixels to video ram. SDL
blitting functions are optimized and can even be hardware accelerated
on some platforms.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
 tools/ioemu/hw/vga.c |   17 ++++++-----
 tools/ioemu/sdl.c    |   75 +++++++++++++++++++++++++++++++++++++++++++--------
 tools/ioemu/vl.h     |    1 
 tools/ioemu/vnc.c    |    7 ++++
 4 files changed, 82 insertions(+), 18 deletions(-)

diff -r be143a3a90c6 -r 69bb0c4af952 tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c      Mon Mar 03 11:05:18 2008 +0000
+++ b/tools/ioemu/hw/vga.c      Mon Mar 03 11:06:31 2008 +0000
@@ -1481,7 +1481,7 @@ static void vga_draw_graphic(VGAState *s
 static void vga_draw_graphic(VGAState *s, int full_update)
 {
     int y1, y, update, linesize, y_start, double_scan, mask, depth;
-    int width, height, shift_control, line_offset, bwidth;
+    int width, height, shift_control, line_offset, bwidth, changed_flag;
     ram_addr_t page0, page1;
     int disp_width, multi_scan, multi_run;
     uint8_t *d;
@@ -1554,10 +1554,12 @@ static void vga_draw_graphic(VGAState *s
     }
     vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + 
get_depth_index(s->ds)];
 
+    changed_flag = 0;
     depth = s->get_bpp(s);
-    if (s->ds->dpy_colourdepth != NULL && s->ds->depth != depth) {
-        if (depth != 24 || s->ds->depth != 32)
-            s->ds->dpy_colourdepth(s->ds, depth);
+    if (s->ds->dpy_colourdepth != NULL && 
+            (s->ds->depth != depth || !s->ds->shared_buf)) {
+        s->ds->dpy_colourdepth(s->ds, depth);
+        changed_flag = 1;
     }
     if (disp_width != s->last_width ||
         height != s->last_height) {
@@ -1567,9 +1569,10 @@ static void vga_draw_graphic(VGAState *s
         s->last_width = disp_width;
         s->last_height = height;
         full_update = 1;
-    }
-    if (s->ds->shared_buf && s->ds->data != s->vram_ptr + (s->start_addr * 4))
-        s->ds->data = s->vram_ptr + (s->start_addr * 4);
+        changed_flag = 1;
+    }
+    if (s->ds->shared_buf && (changed_flag || s->ds->data != s->vram_ptr + 
(s->start_addr * 4)))
+        s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));
     if (!s->ds->shared_buf && s->cursor_invalidate)
         s->cursor_invalidate(s);
     
diff -r be143a3a90c6 -r 69bb0c4af952 tools/ioemu/sdl.c
--- a/tools/ioemu/sdl.c Mon Mar 03 11:05:18 2008 +0000
+++ b/tools/ioemu/sdl.c Mon Mar 03 11:06:31 2008 +0000
@@ -30,6 +30,7 @@
 #endif
 
 static SDL_Surface *screen;
+static SDL_Surface *shared = NULL;
 static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
 static int last_vm_running;
 static int gui_saved_grab;
@@ -47,7 +48,46 @@ static void sdl_update(DisplayState *ds,
 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_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);
+    ds->data = pixels;
 }
 
 static void sdl_resize(DisplayState *ds, int w, int h)
@@ -56,7 +96,7 @@ static void sdl_resize(DisplayState *ds,
 
     //    printf("resizing to %d %d\n", w, h);
 
-    flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
+    flags = 
SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_DOUBLEBUF|SDL_HWPALETTE;
     if (gui_fullscreen)
         flags |= SDL_FULLSCREEN;
 
@@ -78,16 +118,28 @@ static void sdl_resize(DisplayState *ds,
         fprintf(stderr, "Could not open SDL display\n");
         exit(1);
     }
-    ds->data = screen->pixels;
-    ds->linesize = screen->pitch;
-    ds->depth = screen->format->BitsPerPixel;
-    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 (ds->depth == 32 && screen->format->Rshift == 0) {
+            ds->bgr = 1;
+        } else {
+            ds->bgr = 0;
+        }
+        ds->data = screen->pixels;
+        ds->linesize = screen->pitch;
+    } else {
+        ds->linesize = (ds->depth / 8) * w;
+    }
+}
+
+static void sdl_colourdepth(DisplayState *ds, int depth)
+{
+    if (!depth || !ds->depth) return;
+    ds->shared_buf = 1;
+    ds->depth = depth;
+    ds->linesize = width * depth / 8; 
 }
 
 /* generic keyboard conversion */
@@ -508,7 +560,8 @@ void sdl_display_init(DisplayState *ds, 
     ds->dpy_update = sdl_update;
     ds->dpy_resize = sdl_resize;
     ds->dpy_refresh = sdl_refresh;
-    ds->dpy_colourdepth = NULL;
+    ds->dpy_colourdepth = sdl_colourdepth;
+    ds->dpy_setdata = sdl_setdata;
 
     sdl_resize(ds, 640, 400);
     sdl_update_caption();
diff -r be143a3a90c6 -r 69bb0c4af952 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Mon Mar 03 11:05:18 2008 +0000
+++ b/tools/ioemu/vl.h  Mon Mar 03 11:06:31 2008 +0000
@@ -942,6 +942,7 @@ struct DisplayState {
     void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
     void (*dpy_resize)(struct DisplayState *s, int w, int h);
     void (*dpy_colourdepth)(struct DisplayState *s, int depth);
+    void (*dpy_setdata)(DisplayState *ds, void *pixels);
     void (*dpy_refresh)(struct DisplayState *s);
     void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y, int dst_x, 
int dst_y, int w, int h);
 };
diff -r be143a3a90c6 -r 69bb0c4af952 tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c Mon Mar 03 11:05:18 2008 +0000
+++ b/tools/ioemu/vnc.c Mon Mar 03 11:06:31 2008 +0000
@@ -1621,6 +1621,11 @@ static void pixel_format_message (VncSta
     vnc_write(vs, pad, 3);           /* padding */
 }
 
+static void vnc_dpy_setdata(DisplayState *ds, void *pixels)
+{
+    ds->data = pixels;
+}
+
 static void vnc_dpy_colourdepth(DisplayState *ds, int depth)
 {
     int host_big_endian_flag;
@@ -1628,6 +1633,7 @@ static void vnc_dpy_colourdepth(DisplayS
 
     switch (depth) {
         case 24:
+            if (ds->depth == 32) return;
             ds->shared_buf = 0;
             depth = 32;
             break;
@@ -2480,6 +2486,7 @@ void vnc_display_init(DisplayState *ds)
     vs->ds->dpy_update = vnc_dpy_update;
     vs->ds->dpy_resize = vnc_dpy_resize;
     vs->ds->dpy_colourdepth = vnc_dpy_colourdepth;
+    vs->ds->dpy_setdata = vnc_dpy_setdata;
     vs->ds->dpy_refresh = vnc_dpy_refresh;
 
     vs->ds->width = 640;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.