Final touches to OSMesa OpenGL support on Atari, using loadable libraries. Hope SDL 1.2.8 is out soon.
authorPatrice Mandin <patmandin@gmail.com>
Fri, 26 Nov 2004 16:16:50 +0000
changeset 991 12b13601a544
parent 990 8e20c48a9c13
child 992 0324ce32b2d9
Final touches to OSMesa OpenGL support on Atari, using loadable libraries. Hope SDL 1.2.8 is out soon.
configure.in
src/video/ataricommon/SDL_atarigl.c
src/video/ataricommon/SDL_atarigl_c.h
src/video/gem/SDL_gemvideo.c
src/video/xbios/SDL_xbios.c
test/configure.in
--- a/configure.in	Fri Nov 26 16:13:24 2004 +0000
+++ b/configure.in	Fri Nov 26 16:16:50 2004 +0000
@@ -1133,20 +1133,34 @@
 CheckAtariOSMesa()
 {
     if test "x$enable_video" = "xyes" -a "x$enable_video_opengl" = "xyes"; then
+        AC_CHECK_HEADER(GL/osmesa.h, have_osmesa_hdr=yes)
+        AC_CHECK_LIB(OSMesa, OSMesaCreateContext, have_osmesa_lib=yes, have_osmesa_lib=no, -lm)
+
+        # Static linking to -lOSMesa
         AC_PATH_PROG(OSMESA_CONFIG, osmesa-config, no)
         if test "x$OSMESA_CONFIG" = "xno" -o "x$enable_atari_ldg" = "xno"; then
-            AC_CHECK_HEADER(GL/osmesa.h, have_osmesa_hdr=yes)
-            AC_CHECK_LIB(OSMesa, OSMesaCreateContext, have_osmesa_lib=yes, have_osmesa_lib=no, -lm)
+            # -lOSMesa is really the static library
             if test "x$have_osmesa_hdr" = "xyes" -a "x$have_osmesa_lib" = "xyes"; then
     	        CFLAGS="$CFLAGS -DHAVE_OPENGL"
 		    	SYSTEM_LIBS="$SYSTEM_LIBS -lOSMesa"
             fi
         else
+            # -lOSMesa is a loader for OSMesa.ldg
             OSMESA_CFLAGS=`$OSMESA_CONFIG --cflags`
             OSMESA_LIBS=`$OSMESA_CONFIG --libs`
-        	CFLAGS="$CFLAGS -DHAVE_OPENGL $OSMESA_CFLAGS"
+            CFLAGS="$CFLAGS -DHAVE_OPENGL $OSMESA_CFLAGS"
             SYSTEM_LIBS="$SYSTEM_LIBS $OSMESA_LIBS"
         fi
+
+        AC_ARG_ENABLE(osmesa-shared,
+[  --enable-osmesa-shared  dynamically load OSMesa OpenGL support [default=yes]],
+                              , enable_osmesa_shared=yes)
+        if test "x$enable_osmesa_shared" = "xyes" -a "x$enable_atari_ldg" = "xyes"; then
+            # Dynamic linking
+            if test "x$have_osmesa_hdr" = "xyes"; then
+                CFLAGS="$CFLAGS -DENABLE_OSMESA_SHARED"
+            fi
+		fi
     fi
 }
 
--- a/src/video/ataricommon/SDL_atarigl.c	Fri Nov 26 16:13:24 2004 +0000
+++ b/src/video/ataricommon/SDL_atarigl.c	Fri Nov 26 16:16:50 2004 +0000
@@ -24,125 +24,198 @@
 
 /*--- Includes ---*/
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #ifdef HAVE_OPENGL
 #include <GL/osmesa.h>
 #endif
 
+#include <mint/osbind.h>
+
 #include "SDL_video.h"
 #include "SDL_error.h"
 #include "SDL_endian.h"
 #include "SDL_atarigl_c.h"
+#ifdef ENABLE_OSMESA_SHARED
+#include "SDL_loadso.h"
+#endif
 
-/*--- Variables ---*/
+/*--- Defines ---*/
+
+#define PATH_OSMESA_LDG	"osmesa.ldg"
+#define PATH_MESAGL_LDG	"mesa_gl.ldg"
+#define PATH_TINYGL_LDG	"tiny_gl.ldg"
 
 /*--- Functions prototypes ---*/
 
-static void ConvertNull(SDL_Surface *surface);
-static void Convert565To555be(SDL_Surface *surface);
-static void Convert565To555le(SDL_Surface *surface);
-static void Convert565le(SDL_Surface *surface);
-static void ConvertBGRAToABGR(SDL_Surface *surface);
+static void SDL_AtariGL_UnloadLibrary(_THIS);
+
+static void CopyShadowNull(_THIS, SDL_Surface *surface);
+static void CopyShadowDirect(_THIS, SDL_Surface *surface);
+static void CopyShadow8888To555(_THIS, SDL_Surface *surface);
+static void CopyShadow8888To565(_THIS, SDL_Surface *surface);
+
+static void ConvertNull(_THIS, SDL_Surface *surface);
+static void Convert565To555be(_THIS, SDL_Surface *surface);
+static void Convert565To555le(_THIS, SDL_Surface *surface);
+static void Convert565le(_THIS, SDL_Surface *surface);
+static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface);
+
+static int InitNew(_THIS, SDL_Surface *current);
+static int InitOld(_THIS, SDL_Surface *current);
 
 /*--- Public functions ---*/
 
 int SDL_AtariGL_Init(_THIS, SDL_Surface *current)
 {
 #ifdef HAVE_OPENGL
-	GLenum osmesa_format;
-	SDL_PixelFormat *pixel_format;
-	Uint32	redmask;
-
-	SDL_AtariGL_Quit(this);	/* Destroy previous context if exist */
-
-	/* Init OpenGL context using OSMesa */
-	gl_convert = ConvertNull;
+	if (gl_oldmesa) {
+		gl_active = InitOld(this, current);		
+	} else {
+		gl_active = InitNew(this, current);		
+	}
+#endif
 
-	pixel_format = current->format;
-	redmask = pixel_format->Rmask;
-	switch (pixel_format->BitsPerPixel) {
-		case 15:
-			/* 1555, big and little endian, unsupported */
-			osmesa_format = OSMESA_RGB_565;
-			if (redmask == 31<<10) {
-				gl_convert = Convert565To555be;
-			} else {
-				gl_convert = Convert565To555le;
-			}
-			break;
-		case 16:
-			if (redmask == 31<<11) {
-				osmesa_format = OSMESA_RGB_565;
-			} else {
-				/* 565, little endian, unsupported */
-				osmesa_format = OSMESA_RGB_565;
-				gl_convert = Convert565le;
-			}
-			break;
-		case 24:
-			if (redmask == 255<<16) {
-				osmesa_format = OSMESA_RGB;
-			} else {
-				osmesa_format = OSMESA_BGR;
-			}
-			break;
-		case 32:
-			if (redmask == 255<<16) {
-				osmesa_format = OSMESA_ARGB;
-			} else if (redmask == 255<<8) {
-				osmesa_format = OSMESA_BGRA;
-			} else if (redmask == 255<<24) {
-				osmesa_format = OSMESA_RGBA;
-			} else {
-				/* ABGR format unsupported */
-				osmesa_format = OSMESA_BGRA;
-				gl_convert = ConvertBGRAToABGR;
-			}
-			break;
-		default:
-			osmesa_format = OSMESA_COLOR_INDEX;
-			break;
-	}
-
-	gl_ctx = OSMesaCreateContextExt( osmesa_format, this->gl_config.depth_size,
-		this->gl_config.stencil_size, this->gl_config.accum_red_size +
-		this->gl_config.accum_green_size + this->gl_config.accum_blue_size +
-		this->gl_config.accum_alpha_size, NULL );
-
-	gl_active = (gl_ctx != NULL);
 	return (gl_active);
-#else
-	return 0;
-#endif
 }
 
 void SDL_AtariGL_Quit(_THIS)
 {
 #ifdef HAVE_OPENGL
-	/* Shutdown OpenGL context */
-	if (gl_ctx) {
-		OSMesaDestroyContext(gl_ctx);
-		gl_ctx = NULL;
+	if (!gl_active) {
+		return;
 	}
-#endif
+
+	if (gl_oldmesa) {
+		/* Old mesa implementations */
+		if (this->gl_data->OSMesaDestroyLDG) {
+			this->gl_data->OSMesaDestroyLDG();
+		}
+		if (gl_shadow) {
+			Mfree(gl_shadow);
+			gl_shadow = NULL;
+		}
+	} else {
+		/* New mesa implementation */
+		if (gl_ctx) {
+			if (this->gl_data->OSMesaDestroyContext) {
+				this->gl_data->OSMesaDestroyContext(gl_ctx);
+			}
+			gl_ctx = NULL;
+		}
+	}
+
+	SDL_AtariGL_UnloadLibrary(this);
+
+#endif /* HAVE_OPENGL */
 	gl_active = 0;
 }
 
 int SDL_AtariGL_LoadLibrary(_THIS, const char *path)
 {
 #ifdef HAVE_OPENGL
-	/* Library is always opened */
+
+#ifdef ENABLE_OSMESA_SHARED
+	void *handle;
+
+	if (gl_active) {
+		SDL_SetError("OpenGL context already created");
+		return -1;
+	}
+
+	/* Unload previous driver */
+	SDL_AtariGL_UnloadLibrary(this);
+
+	/* Load library given by path */
+	handle = SDL_LoadObject(path);
+	if (handle == NULL) {
+		/* Try to load another one */
+		path = getenv("SDL_VIDEO_GL_DRIVER");
+		if ( path != NULL ) {
+			handle = SDL_LoadObject(path);
+		}
+
+		/* If it does not work, try some other */
+		if (handle == NULL) {
+			path = PATH_OSMESA_LDG;
+			handle = SDL_LoadObject(path);
+		}
+
+		if (handle == NULL) {
+			path = PATH_MESAGL_LDG;
+			handle = SDL_LoadObject(path);
+		}
+
+		if (handle == NULL) {
+			path = PATH_TINYGL_LDG;
+			handle = SDL_LoadObject(path);
+		}
+	}
+
+	if (handle == NULL) {
+		SDL_SetError("Could not load OpenGL library");
+		return -1;
+	}
+
+	/* Load functions pointers (osmesa.ldg) */
+	this->gl_data->OSMesaCreateContextExt = SDL_LoadFunction(handle, "OSMesaCreateContextExt");
+	this->gl_data->OSMesaDestroyContext = SDL_LoadFunction(handle, "OSMesaDestroyContext");
+	this->gl_data->OSMesaMakeCurrent = SDL_LoadFunction(handle, "OSMesaMakeCurrent");
+	this->gl_data->OSMesaPixelStore = SDL_LoadFunction(handle, "OSMesaPixelStore");
+	this->gl_data->OSMesaGetProcAddress = SDL_LoadFunction(handle, "OSMesaGetProcAddress");
+	this->gl_data->glGetIntegerv = SDL_LoadFunction(handle, "glGetIntegerv");
+
+	/* Load old functions pointers (mesa_gl.ldg, tiny_gl.ldg) */
+	this->gl_data->OSMesaCreateLDG = SDL_LoadFunction(handle, "OSMesaCreateLDG");
+	this->gl_data->OSMesaDestroyLDG = SDL_LoadFunction(handle, "OSMesaDestroyLDG");
+
+	gl_oldmesa = 0;
+
+	if ( (this->gl_data->OSMesaCreateContextExt == NULL) || 
+	     (this->gl_data->OSMesaDestroyContext == NULL) ||
+	     (this->gl_data->OSMesaMakeCurrent == NULL) ||
+	     (this->gl_data->OSMesaPixelStore == NULL) ||
+	     (this->gl_data->glGetIntegerv == NULL) ||
+	     (this->gl_data->OSMesaGetProcAddress == NULL)) {
+		/* Hum, maybe old library ? */
+		if ( (this->gl_data->OSMesaCreateLDG == NULL) || 
+		     (this->gl_data->OSMesaDestroyLDG == NULL)) {
+			SDL_SetError("Could not retrieve OpenGL functions");
+			return -1;
+		} else {
+			gl_oldmesa = 1;
+		}
+	}
+
+	this->gl_config.dll_handle = handle;
+	if ( path ) {
+		strncpy(this->gl_config.driver_path, path,
+			sizeof(this->gl_config.driver_path)-1);
+	} else {
+		strcpy(this->gl_config.driver_path, "");
+	}
+
+#endif
 	this->gl_config.driver_loaded = 1;
+
+	return 0;
+#else
+	return -1;
 #endif
-	return 0;
 }
 
 void *SDL_AtariGL_GetProcAddress(_THIS, const char *proc)
 {
 	void *func = NULL;
 #ifdef HAVE_OPENGL
-	if (gl_ctx != NULL) {
-		func = OSMesaGetProcAddress(proc);
+
+	if (this->gl_config.dll_handle) {
+		func = SDL_LoadFunction(this->gl_config.dll_handle, (void *)proc);
+	} else if (this->gl_data->OSMesaGetProcAddress) {
+		func = this->gl_data->OSMesaGetProcAddress(proc);
 	}
+
 #endif
 	return func;
 }
@@ -153,7 +226,13 @@
 	GLenum mesa_attrib;
 	SDL_Surface *surface;
 
-	if (gl_ctx == NULL) {
+	if (this->gl_config.dll_handle) {
+		if (this->gl_data->glGetIntegerv == NULL) {
+			return -1;
+		}
+	}
+
+	if (!gl_active) {
 		return -1;
 	}
 
@@ -196,7 +275,7 @@
 			return -1;
 	}
 
-	glGetIntegerv(mesa_attrib, value);
+	this->gl_data->glGetIntegerv(mesa_attrib, value);
 	return 0;
 #else
 	return -1;
@@ -209,7 +288,18 @@
 	SDL_Surface *surface;
 	GLenum type;
 
-	if (gl_ctx == NULL) {
+	if (gl_oldmesa && gl_active) {
+		return 0;
+	}
+
+	if (this->gl_config.dll_handle) {
+		if ((this->gl_data->OSMesaMakeCurrent == NULL) ||
+			(this->gl_data->OSMesaPixelStore == NULL)) {
+			return -1;
+		}
+	}
+
+	if (!gl_active) {
 		SDL_SetError("Invalid OpenGL context");
 		return -1;
 	}
@@ -222,13 +312,13 @@
 		type = GL_UNSIGNED_BYTE;
 	}
 
-	if (!OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w, surface->h)) {
+	if (!(this->gl_data->OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w, surface->h))) {
 		SDL_SetError("Can not make OpenGL context current");
 		return -1;
 	}
 
 	/* OSMesa draws upside down */
-	OSMesaPixelStore(OSMESA_Y_UP, 0);
+	this->gl_data->OSMesaPixelStore(OSMESA_Y_UP, 0);
 
 	return 0;
 #else
@@ -239,21 +329,296 @@
 void SDL_AtariGL_SwapBuffers(_THIS)
 {
 #ifdef HAVE_OPENGL
-	if (gl_ctx == NULL) {
-		return;
+	if (gl_active) {
+		gl_copyshadow(this, this->screen);
+		gl_convert(this, this->screen);
 	}
+#endif
+}
 
-	gl_convert(this->screen);
+void SDL_AtariGL_InitPointers(_THIS)
+{
+#if defined(HAVE_OPENGL)
+	this->gl_data->OSMesaCreateContextExt = OSMesaCreateContextExt;
+	this->gl_data->OSMesaDestroyContext = OSMesaDestroyContext;
+	this->gl_data->OSMesaMakeCurrent = OSMesaMakeCurrent;
+	this->gl_data->OSMesaPixelStore = OSMesaPixelStore;
+	this->gl_data->OSMesaGetProcAddress = OSMesaGetProcAddress;
+	this->gl_data->glGetIntegerv = glGetIntegerv;
 #endif
 }
 
 /*--- Private functions ---*/
 
-static void ConvertNull(SDL_Surface *surface)
+static void SDL_AtariGL_UnloadLibrary(_THIS)
+{
+#if defined(HAVE_OPENGL)
+	if (this->gl_config.dll_handle) {
+		SDL_UnloadObject(this->gl_config.dll_handle);
+		this->gl_config.dll_handle = NULL;
+
+		/* Restore pointers to static library */
+		this->gl_data->OSMesaCreateContextExt = OSMesaCreateContextExt;
+		this->gl_data->OSMesaDestroyContext = OSMesaDestroyContext;
+		this->gl_data->OSMesaMakeCurrent = OSMesaMakeCurrent;
+		this->gl_data->OSMesaPixelStore = OSMesaPixelStore;
+		this->gl_data->OSMesaGetProcAddress = OSMesaGetProcAddress;
+		this->gl_data->glGetIntegerv = glGetIntegerv;
+
+		this->gl_data->OSMesaCreateLDG = NULL;
+		this->gl_data->OSMesaDestroyLDG = NULL;
+	}
+#endif
+}
+
+/*--- Creation of an OpenGL context using new/old functions ---*/
+
+static int InitNew(_THIS, SDL_Surface *current)
+{
+	GLenum osmesa_format;
+	SDL_PixelFormat *pixel_format;
+	Uint32	redmask;
+
+	if (this->gl_config.dll_handle) {
+		if (this->gl_data->OSMesaCreateContextExt == NULL) {
+			return 0;
+		}
+	}
+
+	/* Init OpenGL context using OSMesa */
+	gl_convert = ConvertNull;
+	gl_copyshadow = CopyShadowNull;
+
+	pixel_format = current->format;
+	redmask = pixel_format->Rmask;
+	switch (pixel_format->BitsPerPixel) {
+		case 15:
+			/* 1555, big and little endian, unsupported */
+			gl_pixelsize = 2;
+			osmesa_format = OSMESA_RGB_565;
+			if (redmask == 31<<10) {
+				gl_convert = Convert565To555be;
+			} else {
+				gl_convert = Convert565To555le;
+			}
+			break;
+		case 16:
+			gl_pixelsize = 2;
+			if (redmask == 31<<11) {
+				osmesa_format = OSMESA_RGB_565;
+			} else {
+				/* 565, little endian, unsupported */
+				osmesa_format = OSMESA_RGB_565;
+				gl_convert = Convert565le;
+			}
+			break;
+		case 24:
+			gl_pixelsize = 3;
+			if (redmask == 255<<16) {
+				osmesa_format = OSMESA_RGB;
+			} else {
+				osmesa_format = OSMESA_BGR;
+			}
+			break;
+		case 32:
+			gl_pixelsize = 4;
+			if (redmask == 255<<16) {
+				osmesa_format = OSMESA_ARGB;
+			} else if (redmask == 255<<8) {
+				osmesa_format = OSMESA_BGRA;
+			} else if (redmask == 255<<24) {
+				osmesa_format = OSMESA_RGBA;
+			} else {
+				/* ABGR format unsupported */
+				osmesa_format = OSMESA_BGRA;
+				gl_convert = ConvertBGRAToABGR;
+			}
+			break;
+		default:
+			gl_pixelsize = 1;
+			osmesa_format = OSMESA_COLOR_INDEX;
+			break;
+	}
+
+	gl_ctx = this->gl_data->OSMesaCreateContextExt(
+		osmesa_format, this->gl_config.depth_size,
+		this->gl_config.stencil_size, this->gl_config.accum_red_size +
+		this->gl_config.accum_green_size + this->gl_config.accum_blue_size +
+		this->gl_config.accum_alpha_size, NULL );
+
+	return (gl_ctx != NULL);
+}
+
+static int InitOld(_THIS, SDL_Surface *current)
+{
+	GLenum osmesa_format;
+	SDL_PixelFormat *pixel_format;
+	Uint32	redmask;
+
+	if (this->gl_config.dll_handle) {
+		if (this->gl_data->OSMesaCreateLDG == NULL) {
+			return 0;
+		}
+	}
+
+	/* Init OpenGL context using OSMesa */
+	gl_convert = ConvertNull;
+	gl_copyshadow = CopyShadowNull;
+
+	pixel_format = current->format;
+	redmask = pixel_format->Rmask;
+	switch (pixel_format->BitsPerPixel) {
+		case 15:
+			/* 15 bits unsupported */
+			gl_pixelsize = 2;
+			osmesa_format = OSMESA_ARGB;
+			if (redmask == 31<<10) {
+				gl_copyshadow = CopyShadow8888To555;
+			} else {
+				gl_copyshadow = CopyShadow8888To565;
+				gl_convert = Convert565To555le;
+			}
+			break;
+		case 16:
+			/* 16 bits unsupported */
+			gl_pixelsize = 2;
+			osmesa_format = OSMESA_ARGB;
+			gl_copyshadow = CopyShadow8888To565;
+			if (redmask != 31<<11) {
+				/* 565, little endian, unsupported */
+				gl_convert = Convert565le;
+			}
+			break;
+		case 24:
+			gl_pixelsize = 3;
+			gl_copyshadow = CopyShadowDirect;
+			if (redmask == 255<<16) {
+				osmesa_format = OSMESA_RGB;
+			} else {
+				osmesa_format = OSMESA_BGR;
+			}
+			break;
+		case 32:
+			gl_pixelsize = 4;
+			gl_copyshadow = CopyShadowDirect;
+			if (redmask == 255<<16) {
+				osmesa_format = OSMESA_ARGB;
+			} else if (redmask == 255<<8) {
+				osmesa_format = OSMESA_BGRA;
+			} else if (redmask == 255<<24) {
+				osmesa_format = OSMESA_RGBA;
+			} else {
+				/* ABGR format unsupported */
+				osmesa_format = OSMESA_BGRA;
+				gl_convert = ConvertBGRAToABGR;
+			}
+			break;
+		default:
+			gl_pixelsize = 1;
+			gl_copyshadow = CopyShadowDirect;
+			osmesa_format = OSMESA_COLOR_INDEX;
+			break;
+	}
+
+	gl_shadow = this->gl_data->OSMesaCreateLDG(
+		osmesa_format, GL_UNSIGNED_BYTE, current->w, current->h
+	);
+
+	return (gl_shadow != NULL);
+}
+
+/*--- Conversions routines from shadow buffer to the screen ---*/
+
+static void CopyShadowNull(_THIS, SDL_Surface *surface)
 {
 }
 
-static void Convert565To555be(SDL_Surface *surface)
+static void CopyShadowDirect(_THIS, SDL_Surface *surface)
+{
+	int y, srcpitch, dstpitch;
+	Uint8 *srcline, *dstline;
+
+	srcline = gl_shadow;
+	srcpitch = surface->w * gl_pixelsize;
+	dstline = surface->pixels;
+	dstpitch = surface->pitch;
+
+	for (y=0; y<surface->h; y++) {
+		memcpy(dstline, srcline, srcpitch);
+
+		srcline += srcpitch;
+		dstline += dstpitch;
+	}
+}
+
+static void CopyShadow8888To555(_THIS, SDL_Surface *surface)
+{
+	int x,y, srcpitch, dstpitch;
+	Uint16 *dstline, *dstcol;
+	Uint32 *srcline, *srccol;
+
+	srcline = (Uint32 *)gl_shadow;
+	srcpitch = surface->w;
+	dstline = surface->pixels;
+	dstpitch = surface->pitch >>1;
+
+	for (y=0; y<surface->h; y++) {
+		srccol = srcline;
+		dstcol = dstline;
+		for (x=0; x<surface->w; x++) {
+			Uint32 srccolor;
+			Uint16 dstcolor;
+			
+			srccolor = *srccol++;
+			dstcolor = (srccolor>>9) & (31<<10);
+			dstcolor |= (srccolor>>6) & (31<<5);
+			dstcolor |= (srccolor>>3) & 31;
+			*dstcol++ = dstcolor;
+		}
+
+		srcline += srcpitch;
+		dstline += dstpitch;
+	}
+}
+
+static void CopyShadow8888To565(_THIS, SDL_Surface *surface)
+{
+	int x,y, srcpitch, dstpitch;
+	Uint16 *dstline, *dstcol;
+	Uint32 *srcline, *srccol;
+
+	srcline = (Uint32 *)gl_shadow;
+	srcpitch = surface->w;
+	dstline = surface->pixels;
+	dstpitch = surface->pitch >>1;
+
+	for (y=0; y<surface->h; y++) {
+		srccol = srcline;
+		dstcol = dstline;
+
+		for (x=0; x<surface->w; x++) {
+			Uint32 srccolor;
+			Uint16 dstcolor;
+			
+			srccolor = *srccol++;
+			dstcolor = (srccolor>>8) & (31<<11);
+			dstcolor |= (srccolor>>5) & (63<<5);
+			dstcolor |= (srccolor>>3) & 31;
+			*dstcol++ = dstcolor;
+		}
+
+		srcline += srcpitch;
+		dstline += dstpitch;
+	}
+}
+
+/*--- Conversions routines in the screen ---*/
+
+static void ConvertNull(_THIS, SDL_Surface *surface)
+{
+}
+
+static void Convert565To555be(_THIS, SDL_Surface *surface)
 {
 	int x,y, pitch;
 	unsigned short *line, *pixel;
@@ -272,7 +637,7 @@
 	}
 }
 
-static void Convert565To555le(SDL_Surface *surface)
+static void Convert565To555le(_THIS, SDL_Surface *surface)
 {
 	int x,y, pitch;
 	unsigned short *line, *pixel;
@@ -292,7 +657,7 @@
 	}
 }
 
-static void Convert565le(SDL_Surface *surface)
+static void Convert565le(_THIS, SDL_Surface *surface)
 {
 	int x,y, pitch;
 	unsigned short *line, *pixel;
@@ -311,7 +676,7 @@
 	}
 }
 
-static void ConvertBGRAToABGR(SDL_Surface *surface)
+static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface)
 {
 	int x,y, pitch;
 	unsigned long *line, *pixel;
--- a/src/video/ataricommon/SDL_atarigl_c.h	Fri Nov 26 16:13:24 2004 +0000
+++ b/src/video/ataricommon/SDL_atarigl_c.h	Fri Nov 26 16:16:50 2004 +0000
@@ -33,25 +33,49 @@
 #define _THIS   SDL_VideoDevice *this
 
 struct SDL_PrivateGLData {
-	/* to stop switching drivers while we have a valid context */
-    int gl_active; 
+
+    int gl_active; 	/* to stop switching drivers while we have a valid context */
+	
+	int gl_oldmesa;	/* Old OpenGL support ? */
+
+	int	gl_pixelsize;	/* for CopyShadow functions */
+
+	Uint8 *gl_shadow;	/* Shadow buffer for old implementations */
 
 	/* for unsupported OSMesa buffer formats */
-	void (*ConvertSurface)(SDL_Surface *surface);	
+	void (*ConvertSurface)(_THIS, SDL_Surface *surface);	
+
+	/* to convert the shadow buffer to the screen format */
+	void (*CopyShadow)(_THIS, SDL_Surface *surface);	
+
+	OSMesaContext	ctx;
 
-#ifdef HAVE_OPENGL
-	OSMesaContext	ctx;
-#endif
+	/* osmesa.ldg */
+	OSMesaContext (*OSMesaCreateContextExt)( GLenum format, GLint depthBits, GLint stencilBits, GLint accumBits, OSMesaContext sharelist);
+	void (*OSMesaDestroyContext)( OSMesaContext ctx );
+	GLboolean (*OSMesaMakeCurrent)( OSMesaContext ctx, void *buffer, GLenum type, GLsizei width, GLsizei height );
+	void (*OSMesaPixelStore)( GLint pname, GLint value );
+	void * (*OSMesaGetProcAddress)( const char *funcName );
+	void (*glGetIntegerv)( GLenum pname, GLint *value );
+
+	/* mesa_gl.ldg, tiny_gl.ldg */
+	void *(*OSMesaCreateLDG)( long format, long type, long width, long height );
+	void (*OSMesaDestroyLDG)(void);
 };
 
-/* Old variable names */
+/* Variable names */
 #define gl_active	(this->gl_data->gl_active)
 #define gl_ctx		(this->gl_data->ctx)
+#define gl_oldmesa	(this->gl_data->gl_oldmesa)
+#define gl_pixelsize	(this->gl_data->gl_pixelsize)
+#define gl_shadow	(this->gl_data->gl_shadow)
 #define gl_convert	(this->gl_data->ConvertSurface)
+#define gl_copyshadow	(this->gl_data->CopyShadow)
 
 /* OpenGL functions */
 extern int SDL_AtariGL_Init(_THIS, SDL_Surface *current);
 extern void SDL_AtariGL_Quit(_THIS);
+extern void SDL_AtariGL_InitPointers(_THIS);
 
 extern int SDL_AtariGL_LoadLibrary(_THIS, const char *path);
 extern void *SDL_AtariGL_GetProcAddress(_THIS, const char *proc);
--- a/src/video/gem/SDL_gemvideo.c	Fri Nov 26 16:13:24 2004 +0000
+++ b/src/video/gem/SDL_gemvideo.c	Fri Nov 26 16:16:50 2004 +0000
@@ -313,27 +313,11 @@
 	if (GEM_version >= 0x0410) {
 		short ap_gout[4], errorcode;
 		
-#ifdef DEBUG_VIDEO_GEM
-		printf("sdl:video:gem: AES %02x.%02x\n", (GEM_version>>8) & 0xff, GEM_version & 0xff);
-#endif
-
 		GEM_wfeatures=0;
 		errorcode=appl_getinfo(AES_WINDOW, &ap_gout[0], &ap_gout[1], &ap_gout[2], &ap_gout[3]);
-#ifdef DEBUG_VIDEO_GEM
-		printf("sdl:video:gem: appl_getinfo() returned 0x%04x\n", errorcode);
-#endif
 
 		if (errorcode==0) {
 			GEM_wfeatures=ap_gout[0];			
-
-#ifdef DEBUG_VIDEO_GEM
-			printf("sdl:video:gem: AES wind_*() modes: 0x%04x\n", GEM_wfeatures);
-			printf("sdl:video:gem: AES window behaviours: 0x%04x\n", ap_gout[3]);
-		} else {
-			printf("sdl:video:gem: apgout[]={0x%04x,0x%04x,0x%04x,0x%04x}\n",
-				ap_gout[0], ap_gout[1], ap_gout[1], ap_gout[3]
-			);
-#endif
 		}
 	}	
 
@@ -468,8 +452,8 @@
 
 	SDL_modelist[1] = NULL;
 
-#ifdef DEBUG_VIDEO_GEM
-	printf("sdl:video:gem: VideoInit(): done\n");
+#ifdef HAVE_OPENGL
+	SDL_AtariGL_InitPointers(this);
 #endif
 
 	/* We're done! */
@@ -492,7 +476,9 @@
 static void GEM_FreeBuffers(_THIS)
 {
 #ifdef HAVE_OPENGL
-	SDL_AtariGL_Quit(this);
+	if (gl_active) {
+		SDL_AtariGL_Quit(this);
+	}
 #endif
 
 	/* Release buffer */
@@ -1290,12 +1276,11 @@
 
 static void GEM_GL_SwapBuffers(_THIS)
 {
-	if (gl_ctx == NULL) {
-		return;
+	if (gl_active) {
+		gl_copyshadow(this, this->screen);
+		gl_convert(this, this->screen);
+		GEM_FlipHWSurface(this, this->screen);
 	}
-
-	gl_convert(this->screen);
-	GEM_FlipHWSurface(this, this->screen);
 }
 
 #endif
--- a/src/video/xbios/SDL_xbios.c	Fri Nov 26 16:13:24 2004 +0000
+++ b/src/video/xbios/SDL_xbios.c	Fri Nov 26 16:16:50 2004 +0000
@@ -411,6 +411,10 @@
 	/* Init chunky to planar routine */
 	SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8;
 
+#ifdef HAVE_OPENGL
+	SDL_AtariGL_InitPointers(this);
+#endif
+
 	/* We're done! */
 	return(0);
 }
@@ -431,7 +435,9 @@
 	int i;
 
 #ifdef HAVE_OPENGL
-	SDL_AtariGL_Quit(this);
+	if (gl_active) {
+		SDL_AtariGL_Quit(this);
+	}
 #endif
 
 	for (i=0;i<2;i++) {
@@ -876,12 +882,12 @@
 
 static void XBIOS_GL_SwapBuffers(_THIS)
 {
-	if (gl_ctx == NULL) {
-		return;
+	if (gl_active) {
+		gl_copyshadow(this, this->screen);
+		gl_convert(this, this->screen);
+		XBIOS_FlipHWSurface(this, this->screen);
+		SDL_AtariGL_MakeCurrent(this);
 	}
-
-	XBIOS_FlipHWSurface(this, this->screen);
-	SDL_AtariGL_MakeCurrent(this);
 }
 
 #endif
--- a/test/configure.in	Fri Nov 26 16:13:24 2004 +0000
+++ b/test/configure.in	Fri Nov 26 16:16:50 2004 +0000
@@ -28,7 +28,7 @@
         MATHLIB=""
         SYS_GL_LIBS="-lGL"
         ;;
-    *-*-darwin* | *-*-mint* )
+    *-*-darwin* )
         MATHLIB=""
         SYS_GL_LIBS=""
         ;;
@@ -38,6 +38,18 @@
         fi
         SYS_GL_LIBS=""
         ;;
+    *-*-mint*)
+        MATHLIB=""
+        AC_PATH_PROG(OSMESA_CONFIG, osmesa-config, no)
+        if test "x$OSMESA_CONFIG" = "xyes"; then
+            OSMESA_CFLAGS=`$OSMESA_CONFIG --cflags`
+            OSMESA_LIBS=`$OSMESA_CONFIG --libs`
+            CFLAGS="$CFLAGS $OSMESA_CFLAGS"
+            SYS_GL_LIBS="$OSMESA_LIBS"
+        else
+            SYS_GL_LIBS="-lOSMesa"
+        fi
+		;;
     *)
         MATHLIB="-lm"
         AC_PATH_X