sdl shared buffer support
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
@@ -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
@@ -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;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.
Signed-off-by Stefano Stabellini <[email protected]>
sorry, thunderbird blew the layout of the previous email.
---
console.h +1 -0
@@ -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
@@ -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
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.
Signed-off-by Stefano Stabellini <[email protected]>
Ian.
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.
Signed-off-by Stefano Stabellini <[email protected]>---
diff --git
a/console.hb/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.cb/sdl.c
index 15427c5..8e78323 100644
---a/sdl.c
+++b/sdl.c
@@ -32,6 +32,7 @@
#endifstatic
SDL_Surface*screen;
+staticSDL_Surface*shared;
static intgui_grab; /* if true, all keyboard/mouse events are grabbed */ static intlast_vm_running;
static intgui_saved_grab;
@@ -50,21 +51,78 @@ static intguest_cursor= 0;
static intguest_x,guest_y;
staticSDL_Cursor*guest_sprite= 0;+static void
sdl_colourdepth(DisplayState *ds, int depth); +
static voidsdl_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 voidsdl_setdata(DisplayState *ds, void *pixels)+{
+uint32_trmask, 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.
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.
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.
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.candvga_template.hagain 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 insdl_setdata, because if there is any difference in depth or subpixel ordering between host and guest, is up toSDL_BlitSurfaceto 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 :|