Add support for OpenGL on Atari using OSMesa, the offscreen rendering driver from Mesa
authorPatrice Mandin <patmandin@gmail.com>
Wed, 17 Nov 2004 23:13:15 +0000
changeset 978 3b1ba22f5a28
parent 977 9c55b00f8251
child 979 c9d1ade1fb0b
Add support for OpenGL on Atari using OSMesa, the offscreen rendering driver from Mesa
README.MiNT
configure.in
src/video/xbios/SDL_xbios.c
src/video/xbios/SDL_xbios.h
test/configure.in
--- a/README.MiNT	Mon Nov 15 23:34:56 2004 +0000
+++ b/README.MiNT	Wed Nov 17 23:13:15 2004 +0000
@@ -53,13 +53,14 @@
 Threads (Multitasking OS only via GNU pth library)
 Shared object loader (using LDG library from http://ldg.atari.org/)
 Audio CD (MetaDOS)
+OpenGL (using Mesa offscreen rendering driver)
 
 - Driver combinations:
-Video   Kbd     Mouse   Timer   Joysticks Joypads
-xbios   ikbd    ikbd    vbl(2)  ikbd      hardware
-xbios   gemdos  xbios   vbl(2)  xbios     hardware
-xbios   bios    xbios   vbl(2)  xbios     hardware
-gem     gem     gem(1)  vbl(2)  xbios     hardware
+Video   Kbd     Mouse   Timer   Joysticks Joypads	OpenGL
+xbios   ikbd    ikbd    vbl(2)  ikbd      hardware	OSMesa
+xbios   gemdos  xbios   vbl(2)  xbios     hardware	OSMesa
+xbios   bios    xbios   vbl(2)  xbios     hardware	OSMesa
+gem     gem     gem(1)  vbl(2)  xbios     hardware	no
 
 (1) GEM does not report relative mouse motion, so xbios mouse driver is used
 to report this type event.
--- a/configure.in	Mon Nov 15 23:34:56 2004 +0000
+++ b/configure.in	Wed Nov 17 23:13:15 2004 +0000
@@ -1129,6 +1129,19 @@
     fi
 }
 
+dnl Check for Mesa offscreen rendering
+CheckOSMesa()
+{
+    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)
+        if test x$have_osmesa_hdr = xyes -a x$have_osmesa_lib = xyes; then
+    	    CFLAGS="$CFLAGS -DHAVE_OPENGL"
+			SYSTEM_LIBS="$SYSTEM_LIBS -lOSMesa"
+        fi
+    fi
+}
+
 dnl See if we can use the new unified event interface in Linux 2.4
 CheckInputEvents()
 {
@@ -2572,6 +2585,7 @@
         CheckAtariAudio
         CheckAtariLdg
         CheckPTH
+		CheckOSMesa
         # Set up files for the audio library
         if test x$enable_threads = xyes -a x$enable_pth = xyes; then
             if test x$enable_audio = xyes; then
--- a/src/video/xbios/SDL_xbios.c	Mon Nov 15 23:34:56 2004 +0000
+++ b/src/video/xbios/SDL_xbios.c	Wed Nov 17 23:13:15 2004 +0000
@@ -37,6 +37,10 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#ifdef HAVE_OPENGL
+#include <GL/osmesa.h>
+#endif
+
 /* Mint includes */
 #include <mint/cookie.h>
 #include <mint/osbind.h>
@@ -74,6 +78,15 @@
 static void XBIOS_FreeHWSurface(_THIS, SDL_Surface *surface);
 static void XBIOS_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
 
+#ifdef HAVE_OPENGL
+/* OpenGL functions */
+static int XBIOS_GL_LoadLibrary(_THIS, const char *path);
+static void *XBIOS_GL_GetProcAddress(_THIS, const char *proc);
+static int XBIOS_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
+static int XBIOS_GL_MakeCurrent(_THIS);
+static void XBIOS_GL_SwapBuffers(_THIS);
+#endif
+
 /* List of video modes */
 
 /* ST modes */
@@ -93,21 +106,21 @@
 static int xbiosnummodes_f30rvb=16;
 static xbiosmode_t xbiosmodelist_f30rvb[]={
 	{BPS16|COL80|OVERSCAN|VERTFLAG,768,480,16,SDL_FALSE},
+	{BPS16|OVERSCAN|VERTFLAG,384,480,16,SDL_FALSE},
+	{BPS16|COL80|VERTFLAG,640,400,16,SDL_FALSE},
+	{BPS16|VERTFLAG,320,400,16,SDL_FALSE},
 	{BPS16|COL80|OVERSCAN,768,240,16,SDL_FALSE},
-	{BPS16|COL80|VERTFLAG,640,400,16,SDL_FALSE},
+	{BPS16|OVERSCAN,384,240,16,SDL_FALSE},
 	{BPS16|COL80,640,200,16,SDL_FALSE},
-	{BPS16|OVERSCAN|VERTFLAG,384,480,16,SDL_FALSE},
-	{BPS16|OVERSCAN,384,240,16,SDL_FALSE},
-	{BPS16|VERTFLAG,320,400,16,SDL_FALSE},
 	{BPS16,320,200,16,SDL_FALSE},
 
 	{BPS8|COL80|OVERSCAN|VERTFLAG,768,480,8,SDL_FALSE},
+	{BPS8|OVERSCAN|VERTFLAG,384,480,8,SDL_FALSE},
+	{BPS8|COL80|VERTFLAG,640,400,8,SDL_FALSE},
+	{BPS8|VERTFLAG,320,400,8,SDL_FALSE},
 	{BPS8|COL80|OVERSCAN,768,240,8,SDL_FALSE},
-	{BPS8|COL80|VERTFLAG,640,400,8,SDL_FALSE},
+	{BPS8|OVERSCAN,384,240,8,SDL_FALSE},
 	{BPS8|COL80,640,200,8,SDL_FALSE},
-	{BPS8|OVERSCAN|VERTFLAG,384,480,8,SDL_FALSE},
-	{BPS8|OVERSCAN,384,240,8,SDL_FALSE},
-	{BPS8|VERTFLAG,320,400,8,SDL_FALSE},
 	{BPS8,320,200,8,SDL_FALSE}
 };
 
@@ -118,8 +131,8 @@
 	{BPS16|VERTFLAG,320,240,16,SDL_FALSE},
 
 	{BPS8|COL80,640,480,8,SDL_FALSE},	
+	{BPS8,320,480,8,SDL_FALSE},
 	{BPS8|COL80|VERTFLAG,640,240,8,SDL_FALSE},
-	{BPS8,320,480,8,SDL_FALSE},
 	{BPS8|VERTFLAG,320,240,8,SDL_FALSE}
 };
 
@@ -206,6 +219,15 @@
 	device->FlipHWSurface = XBIOS_FlipHWSurface;
 	device->FreeHWSurface = XBIOS_FreeHWSurface;
 
+#ifdef HAVE_OPENGL
+	/* OpenGL functions */
+	device->GL_LoadLibrary = XBIOS_GL_LoadLibrary;
+	device->GL_GetProcAddress = XBIOS_GL_GetProcAddress;
+	device->GL_GetAttribute = XBIOS_GL_GetAttribute;
+	device->GL_MakeCurrent = XBIOS_GL_MakeCurrent;
+	device->GL_SwapBuffers = XBIOS_GL_SwapBuffers;
+#endif
+
 	/* Events */
 	device->InitOSKeymap = Atari_InitOSKeymap;
 	device->PumpEvents = Atari_PumpEvents;
@@ -393,6 +415,10 @@
 	/* Init chunky to planar routine */
 	SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8;
 
+#ifdef HAVE_OPENGL
+	this->gl_config.driver_loaded = 1;
+#endif
+
 	/* We're done! */
 	return(0);
 }
@@ -412,6 +438,14 @@
 {
 	int i;
 
+#ifdef HAVE_OPENGL
+	/* Shutdown OpenGL context */
+	if (XBIOS_ctx) {
+		OSMesaDestroyContext(XBIOS_ctx);
+		XBIOS_ctx = NULL;
+	}
+#endif
+
 	for (i=0;i<2;i++) {
 		if (XBIOS_screensmem[i]!=NULL) {
 			Mfree(XBIOS_screensmem[i]);
@@ -503,6 +537,14 @@
 
 	XBIOS_screens[0]=(void *) (( (long) XBIOS_screensmem[0]+256) & 0xFFFFFF00UL);
 
+#ifdef HAVE_OPENGL
+	if (flags & SDL_OPENGL) {
+		if (this->gl_config.double_buffer) {
+			flags |= SDL_DOUBLEBUF;
+		}
+	}
+#endif
+
 	/* Double buffer ? */
 	if (flags & SDL_DOUBLEBUF) {
 		XBIOS_screensmem[1] = Atari_SysMalloc(new_screen_size, MX_STRAM);
@@ -525,7 +567,6 @@
 		return(NULL);
 	}
 
-	current->flags = modeflags;
 	current->w = XBIOS_width = width;
 	current->h = XBIOS_height = height;
 	current->pitch = (width * new_depth)>>3;
@@ -540,6 +581,33 @@
 
 	XBIOS_fbnum = 0;
 
+#ifdef HAVE_OPENGL
+	if (flags & SDL_OPENGL) {
+		GLenum format;
+
+		/* Init OpenGL context using OSMesa */
+		if (new_depth == 8) {
+			format = OSMESA_COLOR_INDEX;
+		} else {
+			format = OSMESA_RGB_565;
+		}
+
+		XBIOS_ctx = OSMesaCreateContextExt( 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 );
+		if (!XBIOS_ctx) {
+			XBIOS_FreeBuffers(this);
+			SDL_SetError("OSMesaCreateContext failed");
+			return(NULL);
+		}
+
+		modeflags |= SDL_OPENGL;
+	}
+#endif
+
+	current->flags = modeflags;
+
 	/* Now set the video mode */
 #ifndef DEBUG_VIDEO_XBIOS
 	Setscreen(-1,XBIOS_screens[0],-1);
@@ -698,13 +766,6 @@
 		destscr += destx;
 
 		/* Convert chunky to planar screen */
-#ifdef DEBUG_VIDEO_XBIOS
-		printf("C2p:\n");
-		printf(" Source: Adr=0x%08x, Pitch=%d\n", surface->pixels, surface->pitch);
-		printf(" Dest: Adr=0x%08x, Pitch=%d\n", destscr, XBIOS_pitch);
-		printf(" Size: %dx%d, dblline=%d\n", surface->w, surface->h, XBIOS_doubleline);
-		fflush(stdout);
-#endif
 		SDL_Atari_C2pConvert(
 			surface->pixels,
 			destscr,
@@ -835,3 +896,113 @@
 
 	this->screen->pixels = NULL;	
 }
+
+#ifdef HAVE_OPENGL
+
+/* OpenGL functions */
+static int XBIOS_GL_LoadLibrary(_THIS, const char *path)
+{
+	/* Library is always opened */
+	this->gl_config.driver_loaded = 1;
+
+	return 0;
+}
+
+static void *XBIOS_GL_GetProcAddress(_THIS, const char *proc)
+{
+	void *func = NULL;
+
+	if (XBIOS_ctx != NULL) {
+		func = OSMesaGetProcAddress(proc);
+	}
+
+	return func;
+}
+
+static int XBIOS_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
+{
+	GLenum mesa_attrib;
+	SDL_Surface *surface;
+
+	if (XBIOS_ctx == NULL) {
+		return -1;
+	}
+
+	switch(attrib) {
+		case SDL_GL_RED_SIZE:
+			mesa_attrib = GL_RED_BITS;
+			break;
+		case SDL_GL_GREEN_SIZE:
+			mesa_attrib = GL_GREEN_BITS;
+			break;
+		case SDL_GL_BLUE_SIZE:
+			mesa_attrib = GL_BLUE_BITS;
+			break;
+		case SDL_GL_ALPHA_SIZE:
+			mesa_attrib = GL_ALPHA_BITS;
+			break;
+		case SDL_GL_DOUBLEBUFFER:
+			surface = this->screen;
+			*value = ((surface->flags & SDL_DOUBLEBUF)==SDL_DOUBLEBUF);
+			return 0;
+		case SDL_GL_DEPTH_SIZE:
+			mesa_attrib = GL_DEPTH_BITS;
+			break;
+		case SDL_GL_STENCIL_SIZE:
+			mesa_attrib = GL_STENCIL_BITS;
+			break;
+		case SDL_GL_ACCUM_RED_SIZE:
+			mesa_attrib = GL_ACCUM_RED_BITS;
+			break;
+		case SDL_GL_ACCUM_GREEN_SIZE:
+			mesa_attrib = GL_ACCUM_GREEN_BITS;
+			break;
+		case SDL_GL_ACCUM_BLUE_SIZE:
+			mesa_attrib = GL_ACCUM_BLUE_BITS;
+			break;
+		case SDL_GL_ACCUM_ALPHA_SIZE:
+			mesa_attrib = GL_ACCUM_ALPHA_BITS;
+			break;
+		default :
+			return -1;
+	}
+
+	glGetIntegerv(mesa_attrib, value);
+	return 0;
+}
+
+static int XBIOS_GL_MakeCurrent(_THIS)
+{
+	SDL_Surface *surface;
+	GLenum type;
+
+	if (XBIOS_ctx == NULL) {
+		return -1;
+	}
+
+	surface = this->screen;
+	if ((surface->format->BitsPerPixel) == 8) {
+		type = GL_UNSIGNED_BYTE;
+	} else {
+		type = GL_UNSIGNED_SHORT_5_6_5;
+	}
+
+	if (!OSMesaMakeCurrent(XBIOS_ctx, surface->pixels, type, surface->w, surface->h)) {
+		SDL_SetError("Can not make OpenGL context current");
+		return -1;
+	}
+
+	return 0;
+}
+
+static void XBIOS_GL_SwapBuffers(_THIS)
+{
+	if (XBIOS_ctx == NULL) {
+		return;
+	}
+
+	XBIOS_FlipHWSurface(this, this->screen);
+	XBIOS_GL_MakeCurrent(this);
+}
+
+#endif
--- a/src/video/xbios/SDL_xbios.h	Mon Nov 15 23:34:56 2004 +0000
+++ b/src/video/xbios/SDL_xbios.h	Wed Nov 17 23:13:15 2004 +0000
@@ -28,6 +28,10 @@
 #ifndef _SDL_xbios_h
 #define _SDL_xbios_h
 
+#ifdef HAVE_OPENGL
+#include <GL/osmesa.h>
+#endif
+
 #include "SDL_types.h"
 #include "SDL_sysvideo.h"
 
@@ -69,6 +73,9 @@
 	int frame_number;		/* Number of frame for double buffer */
 	int pitch;				/* Destination line width for C2P */
 	int width, height;		/* Screen size for centered C2P */
+#ifdef HAVE_OPENGL
+	OSMesaContext ctx;		/* OpenGL OSMesa context */
+#endif
 
 	SDL_Rect *SDL_modelist[NUM_MODELISTS][SDL_NUMMODES+1];
 	xbiosmode_t *videomodes[NUM_MODELISTS][SDL_NUMMODES+1];
@@ -123,5 +130,8 @@
 #define XBIOS_pitch			(this->hidden->pitch)
 #define XBIOS_width			(this->hidden->width)
 #define XBIOS_height		(this->hidden->height)
+#ifdef HAVE_OPENGL
+#define XBIOS_ctx			(this->hidden->ctx)
+#endif
 
 #endif /* _SDL_xbios_h */
--- a/test/configure.in	Mon Nov 15 23:34:56 2004 +0000
+++ b/test/configure.in	Wed Nov 17 23:13:15 2004 +0000
@@ -5,8 +5,7 @@
 SDL_VERSION=1.2.7
 
 dnl Detect the canonical host and target build environment
-AC_CANONICAL_HOST
-AC_CANONICAL_TARGET
+AC_CANONICAL_SYSTEM
 
 dnl Setup for automake
 AM_INIT_AUTOMAKE(SDL_tests, $SDL_VERSION)
@@ -36,9 +35,13 @@
     *-*-aix*)
         if test x$ac_cv_prog_gcc = xyes; then
             CFLAGS="-mthreads"
-	fi
+        fi
         SYS_GL_LIBS=""
         ;;
+    *-*-mint*)
+        MATHLIB="-lm"
+        SYS_GL_LIBS="-lOSMesa"
+        ;;
     *)
         MATHLIB="-lm"
         AC_PATH_X