Skip to contentSkip to conversation

sdl shared buffer support

PATCH In review Stefano Stabellini 4 participants 7 messages Aug 29, 2008 – Sep 3, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 sdl shared buffer support

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.

---

console.h +1 -0
index a054d97..7d252b7 100644
@@ -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 */

hw/vga.c +0 -0
index 6e40d3d..d5265c0 100644
@@ -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;
sdl.c +40 -2

56 lines not on this page · raw message

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;
#1 lore raw
Quoted 7 lines · Stefano Stabellini

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.

sorry, thunderbird blew the layout of the previous email.

---

console.h +1 -0
index a054d97..7d252b7 100644
@@ -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 */
hw/vga.c +1 -0
index 6e40d3d..d5265c0 100644
@@ -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;
sdl.c +97 -26

175 lines not on this page · raw message

Acked-by on v1 1/1
#2 lore raw
In reply to Stefano Stabellini

Stefano Stabellini writes ("[Qemu-devel] [PATCH] sdl shared buffer support"):

Quoted 7 lines

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.

Ian.

#3 lore raw
In reply to Stefano Stabellini
Quoted 94 lines · Stefano Stabellini

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.

---

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;
Quoted 3 lines

+ default:
+ return;
+ }

This function is broken if BGR-ness of the display is not equal to emulated device BGR-ness.

#4 lore raw
Quoted 3 lines · Blue Swirl

This function is broken if BGR-ness of the display is not equal to emulated device BGR-ness.

good catch!
I am going to send an updated version of this and the opengl patch soon to fix the issue.

#5 lore raw
Quoted 10 lines · Stefano Stabellini
Quoted 3 lines · Blue Swirl

This function is broken if BGR-ness of the display is not equal to emulated device BGR-ness.

good catch!
I am going to send an updated version of this and the opengl patch soon to fix the issue.

I replied to this email a little too fast: reading vga.c and vga_template.h again more carefully it occurred to me that the guest is always RGB, only the host can set the sdl display to BGR. Hence we don't need to handle this case in sdl_setdata, because if there is any difference in depth or subpixel ordering between host and guest, is up to SDL_BlitSurface to solve it.

But there is a similar issue that I wasn't handling: guest big endian and host little endian or vice versa.
In fact I need to set different colour masks in sdl setdata according to the guest endianness.

#6 lore raw
Quoted 20 lines · Stefano Stabellini
Quoted 10 lines · Stefano Stabellini
Quoted 3 lines · Blue Swirl

This function is broken if BGR-ness of the display is not equal to emulated device BGR-ness.

good catch!
I am going to send an updated version of this and the opengl patch soon to fix the issue.

I replied to this email a little too fast: reading vga.c and vga_template.h again more carefully it occurred to me that the guest is always RGB, only the host can set the sdl display to BGR. Hence we don't need to handle this case in sdl_setdata, because if there is any difference in depth or subpixel ordering between host and guest, is up to SDL_BlitSurface to solve it.

Quoted 4 lines

But there is a similar issue that I wasn't handling: guest big endian and host little endian or vice versa.
In fact I need to set different colour masks in sdl setdata according to the guest endianness.

Just to complicate things still further, the endianness of the host running QEMU may not be the same as the endianness of the X server display.

Daniel

Signature · 4 lines
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|