WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] ioemu: SDL rendering using OpenGL

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] ioemu: SDL rendering using OpenGL
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 20 Mar 2008 05:40:39 -0700
Delivery-date: Thu, 20 Mar 2008 05:43:37 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1205840878 0
# Node ID cbb0dffdc07a222666780f9a6055b23f39a736ff
# Parent  ef85eeaf439a352e5ca4107876cbb4dd27c4930e
ioemu: SDL rendering using OpenGL

Add opengl support for rendering the guest framebuffer in the SDL
window. SDL is needed anyway to open the window and handle the
events. Opengl rendering is optional and can be turned off at both
compile time and in the vm configuration file.

Some of the benefits of using opengl are:

 - faster rendering, less CPU intensive, especially with good graphic
   cards;
 - makes the window resizing possible and hardware accelerated, thus
   very efficient and smooth;
 - allows other optimizations like sharing directly a buffer in vram
   with the guest (not yet implemented).

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
 tools/examples/xmexample.hvm        |    5 +
 tools/ioemu/configure               |   32 ++++++
 tools/ioemu/sdl.c                   |  166 +++++++++++++++++++++++++++++++++---
 tools/ioemu/vl.c                    |   15 +++
 tools/ioemu/vl.h                    |    2 
 tools/python/xen/xend/XendConfig.py |    1 
 tools/python/xen/xend/image.py      |    3 
 tools/python/xen/xm/create.py       |    6 +
 8 files changed, 216 insertions(+), 14 deletions(-)

diff -r ef85eeaf439a -r cbb0dffdc07a tools/examples/xmexample.hvm
--- a/tools/examples/xmexample.hvm      Tue Mar 18 11:40:30 2008 +0000
+++ b/tools/examples/xmexample.hvm      Tue Mar 18 11:47:58 2008 +0000
@@ -135,6 +135,11 @@ sdl=0
 sdl=0
 
 #----------------------------------------------------------------------------
+# enable OpenGL for texture rendering inside the SDL window, default = 1
+# valid only if sdl is enabled.
+opengl=1
+
+#----------------------------------------------------------------------------
 # enable VNC library for graphics, default = 1
 vnc=1
 
diff -r ef85eeaf439a -r cbb0dffdc07a tools/ioemu/configure
--- a/tools/ioemu/configure     Tue Mar 18 11:40:30 2008 +0000
+++ b/tools/ioemu/configure     Tue Mar 18 11:47:58 2008 +0000
@@ -189,6 +189,8 @@ for opt do
   --static) static="yes"
   ;;
   --disable-sdl) sdl="no"
+  ;;
+  --disable-opengl) opengl="no"
   ;;
   --enable-coreaudio) coreaudio="yes"
   ;;
@@ -539,6 +541,26 @@ fi # -z $sdl
 fi # -z $sdl
 
 ##########################################
+# OpenGL test
+
+if test -z "$opengl" && test "$sdl" = "yes"
+then
+cat > $TMPC << EOF
+#include <GL/gl.h>
+#ifndef GL_TEXTURE_RECTANGLE_ARB
+#error "Opengl doesn't support GL_TEXTURE_RECTANGLE_ARB"
+#endif
+int main( void ) { return (int) glGetString(GL_EXTENSIONS); }
+EOF
+if $cc -o $TMPE $TMPC -lGL 2> /dev/null
+then
+opengl="yes"
+else
+opengl="no"
+fi
+fi
+
+##########################################
 # alsa sound support libraries
 
 if test "$alsa" = "yes" ; then
@@ -612,6 +634,7 @@ if test "$sdl" != "no" ; then
 if test "$sdl" != "no" ; then
     echo "SDL static link   $sdl_static"
 fi
+echo "OpenGL support    $opengl"
 echo "mingw32 support   $mingw32"
 echo "Adlib support     $adlib"
 echo "CoreAudio support $coreaudio"
@@ -995,6 +1018,15 @@ if test "$target_user_only" = "no"; then
     fi
 fi
 
+if test $opengl = "yes"
+then
+    echo "#define CONFIG_OPENGL 1" >> $config_h
+    echo "CONFIG_OPENGL=yes" >> $config_mak
+    echo "SDL_CFLAGS+=-I/usr/include/GL" >> $config_mak
+    echo "SDL_LIBS+=-lXext" >> $config_mak
+    echo "SDL_LIBS+=-lGL" >> $config_mak
+fi
+
 if test "$cocoa" = "yes" ; then
     echo "#define CONFIG_COCOA 1" >> $config_h
     echo "CONFIG_COCOA=yes" >> $config_mak
diff -r ef85eeaf439a -r cbb0dffdc07a tools/ioemu/sdl.c
--- a/tools/ioemu/sdl.c Tue Mar 18 11:40:30 2008 +0000
+++ b/tools/ioemu/sdl.c Tue Mar 18 11:47:58 2008 +0000
@@ -29,6 +29,10 @@
 #include <signal.h>
 #endif
 
+#ifdef CONFIG_OPENGL
+#include <SDL_opengl.h>
+#endif
+
 static SDL_Surface *screen;
 static SDL_Surface *shared = NULL;
 static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
@@ -44,6 +48,99 @@ static SDL_Cursor *sdl_cursor_normal;
 static SDL_Cursor *sdl_cursor_normal;
 static SDL_Cursor *sdl_cursor_hidden;
 static int absolute_enabled = 0;
+static int opengl_enabled;
+
+#ifdef CONFIG_OPENGL
+static GLint tex_format;
+static GLint tex_type;
+static GLuint texture_ref = 0;
+static GLint gl_format;
+
+static void opengl_setdata(DisplayState *ds, void *pixels)
+{
+    glEnable(GL_TEXTURE_RECTANGLE_ARB);
+    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    glClearColor(0, 0, 0, 0);
+    glDisable(GL_BLEND);
+    glDisable(GL_LIGHTING);
+    glDisable(GL_DEPTH_TEST);
+    glDepthMask(GL_FALSE);
+    glDisable(GL_CULL_FACE);
+    glViewport( 0, 0, screen->w, screen->h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrtho(0, screen->w, screen->h, 0, -1,1);
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    glClear(GL_COLOR_BUFFER_BIT);
+    ds->data = pixels;
+
+    if (texture_ref) {
+        glDeleteTextures(1, &texture_ref);
+        texture_ref = 0;
+    }
+
+    glGenTextures(1, &texture_ref);
+    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_ref);
+    glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
+    switch (ds->depth) {
+        case 8:
+            tex_format = GL_RGB;
+            tex_type = GL_UNSIGNED_BYTE_3_3_2;
+            glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+            break;
+        case 16:
+            tex_format = GL_RGB;
+            tex_type = GL_UNSIGNED_SHORT_5_6_5;
+            glPixelStorei (GL_UNPACK_ALIGNMENT, 2);
+            break;
+        case 24:
+            tex_format = GL_BGR;
+            tex_type = GL_UNSIGNED_BYTE;
+            glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+            break;
+        case 32:
+            if (!ds->bgr) {
+                tex_format = GL_BGRA;
+                tex_type = GL_UNSIGNED_BYTE;
+            } else {
+                tex_format = GL_RGBA;
+                tex_type = GL_UNSIGNED_BYTE;                
+            }
+            glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
+            break;
+    }   
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, (ds->linesize * 8 / ds->depth) - 
ds->width);
+    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, gl_format, ds->width, 
ds->height, 0, tex_format, tex_type, pixels);
+    glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_PRIORITY, 1.0);
+    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, 
GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, 
GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, 
GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, 
GL_CLAMP_TO_EDGE);
+    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
+}
+
+static void opengl_update(DisplayState *ds, int x, int y, int w, int h)
+{  
+    int bpp = ds->depth / 8;
+    GLvoid *pixels = ds->data + y * ds->linesize + x * bpp;
+    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_ref);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, (ds->linesize / bpp) - w);
+    glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, x, y, w, h, tex_format, 
tex_type, pixels);
+    glBegin(GL_QUADS);
+        glTexCoord2d(0, 0);
+        glVertex2d(0, 0);
+        glTexCoord2d(ds->width, 0);
+        glVertex2d(screen->w, 0);
+        glTexCoord2d(ds->width, ds->height);
+        glVertex2d(screen->w, screen->h);
+        glTexCoord2d(0, ds->height);
+        glVertex2d(0, screen->h);
+    glEnd();
+    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
+    SDL_GL_SwapBuffers();
+}
+#endif
 
 static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
 {
@@ -96,17 +193,26 @@ static void sdl_resize(DisplayState *ds,
 
     //    printf("resizing to %d %d\n", w, h);
 
-    flags = 
SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_DOUBLEBUF|SDL_HWPALETTE;
-    if (gui_fullscreen)
+#ifdef CONFIG_OPENGL
+    if (ds->shared_buf && opengl_enabled)
+        flags = SDL_OPENGL|SDL_RESIZABLE;
+    else
+#endif
+        flags = 
SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_DOUBLEBUF|SDL_HWPALETTE;
+
+    if (gui_fullscreen) {
         flags |= SDL_FULLSCREEN;
-
+        flags &= ~SDL_RESIZABLE;
+    }
+    
     width = w;
     height = h;
 
  again:
     screen = SDL_SetVideoMode(w, h, 0, flags);
+#ifndef CONFIG_OPENGL
     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)) {
@@ -115,9 +221,10 @@ static void sdl_resize(DisplayState *ds,
     }
 
     if (!screen->pixels) {
-        fprintf(stderr, "Could not open SDL display\n");
+        fprintf(stderr, "Could not open SDL display: %s\n", SDL_GetError());
         exit(1);
     }
+#endif
     ds->width = w;
     ds->height = h;
     if (!ds->shared_buf) {
@@ -131,6 +238,25 @@ static void sdl_resize(DisplayState *ds,
         ds->linesize = screen->pitch;
     } else {
         ds->linesize = linesize;
+#ifdef CONFIG_OPENGL
+        switch(screen->format->BitsPerPixel) {
+        case 8:
+            gl_format = GL_RGB;
+            break;
+        case 16:
+            gl_format = GL_RGB;
+            break;
+        case 24:
+            gl_format = GL_RGB;
+            break;
+        case 32:
+            if (!screen->format->Rshift)
+                gl_format = GL_BGRA;
+            else
+                gl_format = GL_RGBA;
+            break;
+        };
+#endif
     }
 }
 
@@ -139,7 +265,13 @@ static void sdl_colourdepth(DisplayState
     if (!depth || !ds->depth) return;
     ds->shared_buf = 1;
     ds->depth = depth;
-    ds->linesize = width * depth / 8; 
+    ds->linesize = width * depth / 8;
+#ifdef CONFIG_OPENGL
+    if (opengl_enabled) {
+        ds->dpy_update = opengl_update;
+        ds->dpy_setdata = opengl_setdata;
+    }
+#endif
 }
 
 /* generic keyboard conversion */
@@ -331,8 +463,8 @@ static void sdl_send_mouse_event(int dx,
        }
 
        SDL_GetMouseState(&dx, &dy);
-        dx = dx * 0x7FFF / (width - 1);
-        dy = dy * 0x7FFF / (height - 1);
+        dx = dx * 0x7FFF / (screen->w - 1);
+        dy = dy * 0x7FFF / (screen->h - 1);
     } else if (absolute_enabled) {
        sdl_show_cursor();
        absolute_enabled = 0;
@@ -371,7 +503,7 @@ static void sdl_refresh(DisplayState *ds
     while (SDL_PollEvent(ev)) {
         switch (ev->type) {
         case SDL_VIDEOEXPOSE:
-            sdl_update(ds, 0, 0, screen->w, screen->h);
+            sdl_update(ds, 0, 0, ds->width, ds->height);
             break;
         case SDL_KEYDOWN:
         case SDL_KEYUP:
@@ -528,6 +660,16 @@ static void sdl_refresh(DisplayState *ds
                }
            }
             break;
+#ifdef CONFIG_OPENGL
+        case SDL_VIDEORESIZE:
+        {
+            SDL_ResizeEvent *rev = &ev->resize;
+            screen = SDL_SetVideoMode(rev->w, rev->h, 0, 
SDL_OPENGL|SDL_RESIZABLE);
+            opengl_setdata(ds, ds->data);
+            opengl_update(ds, 0, 0, ds->width, ds->height);
+            break;
+        }
+#endif
         default:
             break;
         }
@@ -536,13 +678,17 @@ static void sdl_refresh(DisplayState *ds
 
 static void sdl_cleanup(void) 
 {
+#ifdef CONFIG_OPENGL
+    if (texture_ref) glDeleteTextures(1, &texture_ref);
+#endif
     SDL_Quit();
 }
 
-void sdl_display_init(DisplayState *ds, int full_screen)
+void sdl_display_init(DisplayState *ds, int full_screen, int opengl)
 {
     int flags;
     uint8_t data = 0;
+    opengl_enabled = opengl;
 
 #if defined(__APPLE__)
     /* always use generic keymaps */
diff -r ef85eeaf439a -r cbb0dffdc07a tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Mar 18 11:40:30 2008 +0000
+++ b/tools/ioemu/vl.c  Tue Mar 18 11:47:58 2008 +0000
@@ -174,6 +174,11 @@ int graphic_height = 600;
 #endif
 int graphic_depth = 15;
 int full_screen = 0;
+#ifdef CONFIG_OPENGL
+int opengl_enabled = 1;
+#else
+int opengl_enabled = 0;
+#endif
 int no_quit = 0;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
@@ -6488,6 +6493,9 @@ void help(void)
 #ifdef CONFIG_SDL
            "-no-quit        disable SDL window close capability\n"
 #endif
+#ifdef CONFIG_OPENGL
+           "-disable-opengl disable OpenGL rendering, using SDL"
+#endif
 #ifdef TARGET_I386
            "-no-fd-bootchk  disable boot signature checking for floppy disks\n"
 #endif
@@ -6666,6 +6674,7 @@ enum {
     QEMU_OPTION_loadvm,
     QEMU_OPTION_full_screen,
     QEMU_OPTION_no_quit,
+    QEMU_OPTION_disable_opengl,
     QEMU_OPTION_pidfile,
     QEMU_OPTION_no_kqemu,
     QEMU_OPTION_kernel_kqemu,
@@ -6763,6 +6772,7 @@ const QEMUOption qemu_options[] = {
 #ifdef CONFIG_SDL
     { "no-quit", 0, QEMU_OPTION_no_quit },
 #endif
+    { "disable-opengl", 0, QEMU_OPTION_disable_opengl },
     { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
     { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
     { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
@@ -7534,6 +7544,9 @@ int main(int argc, char **argv)
                 no_quit = 1;
                 break;
 #endif
+            case QEMU_OPTION_disable_opengl:
+                opengl_enabled = 0;
+                break;
             case QEMU_OPTION_pidfile:
                 create_pidfile(optarg);
                 break;
@@ -7860,7 +7873,7 @@ int main(int argc, char **argv)
        xenstore_write_vncport(vnc_display_port);
     } else {
 #if defined(CONFIG_SDL)
-        sdl_display_init(ds, full_screen);
+        sdl_display_init(ds, full_screen, opengl_enabled);
 #elif defined(CONFIG_COCOA)
         cocoa_display_init(ds, full_screen);
 #else
diff -r ef85eeaf439a -r cbb0dffdc07a tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Tue Mar 18 11:40:30 2008 +0000
+++ b/tools/ioemu/vl.h  Tue Mar 18 11:47:58 2008 +0000
@@ -982,7 +982,7 @@ void isa_cirrus_vga_init(DisplayState *d
                          unsigned long vga_ram_offset, int vga_ram_size);
 
 /* sdl.c */
-void sdl_display_init(DisplayState *ds, int full_screen);
+void sdl_display_init(DisplayState *ds, int full_screen, int opengl_enable);
 
 /* cocoa.m */
 void cocoa_display_init(DisplayState *ds, int full_screen);
diff -r ef85eeaf439a -r cbb0dffdc07a tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Tue Mar 18 11:40:30 2008 +0000
+++ b/tools/python/xen/xend/XendConfig.py       Tue Mar 18 11:47:58 2008 +0000
@@ -142,6 +142,7 @@ XENAPI_PLATFORM_CFG_TYPES = {
     'rtc_timeoffset': int,
     'serial': str,
     'sdl': int,
+    'opengl': int,
     'soundhw': str,
     'stdvga': int,
     'usb': int,
diff -r ef85eeaf439a -r cbb0dffdc07a tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Tue Mar 18 11:40:30 2008 +0000
+++ b/tools/python/xen/xend/image.py    Tue Mar 18 11:47:58 2008 +0000
@@ -263,7 +263,8 @@ class ImageHandler:
 
         elif has_sdl:
             # SDL is default in QEMU.
-            pass
+            if int(vmConfig['platform'].get('opengl', 1)) != 1 :
+                ret.append('-disable-opengl')
         else:
             ret.append('-nographic')
 
diff -r ef85eeaf439a -r cbb0dffdc07a tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py     Tue Mar 18 11:40:30 2008 +0000
+++ b/tools/python/xen/xm/create.py     Tue Mar 18 11:47:58 2008 +0000
@@ -503,6 +503,10 @@ gopts.var('sdl', val='',
 gopts.var('sdl', val='',
           fn=set_value, default=None,
           use="""Should the device model use SDL?""")
+
+gopts.var('opengl', val='',
+          fn=set_value, default=None,
+          use="""Enable\Disable OpenGL""")
 
 gopts.var('display', val='DISPLAY',
           fn=set_value, default=None,
@@ -745,7 +749,7 @@ def configure_hvm(config_image, vals):
              'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten',
              'sdl', 'display', 'xauthority', 'rtc_timeoffset', 'monitor',
              'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci', 'hpet',
-             'guest_os_type', 'hap']
+             'guest_os_type', 'hap', 'opengl']
 
     for a in args:
         if a in vals.__dict__ and vals.__dict__[a] is not None:

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] ioemu: SDL rendering using OpenGL, Xen patchbot-unstable <=