From 0b07ba0ea30b2dd1f4b2d63d6b9adb2a76234c5a Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 17 Nov 2004 23:13:15 +0000 Subject: [PATCH] Add support for OpenGL on Atari using OSMesa, the offscreen rendering driver from Mesa --- README.MiNT | 11 +- configure.in | 14 +++ src/video/xbios/SDL_xbios.c | 205 +++++++++++++++++++++++++++++++++--- src/video/xbios/SDL_xbios.h | 10 ++ test/configure.in | 9 +- 5 files changed, 224 insertions(+), 25 deletions(-) diff --git a/README.MiNT b/README.MiNT index b55ea88bf..fb08fb564 100644 --- a/README.MiNT +++ b/README.MiNT @@ -53,13 +53,14 @@ Audio (Hardware, XBIOS, GSXB, MCSN, STFA, /dev/audio if threads enabled) 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. diff --git a/configure.in b/configure.in index c93bb12cd..7b809adc0 100644 --- a/configure.in +++ b/configure.in @@ -1129,6 +1129,19 @@ CheckMacGL() 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 @@ case "$target" in 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 diff --git a/src/video/xbios/SDL_xbios.c b/src/video/xbios/SDL_xbios.c index 4a7ed5624..826bb4395 100644 --- a/src/video/xbios/SDL_xbios.c +++ b/src/video/xbios/SDL_xbios.c @@ -37,6 +37,10 @@ static char rcsid = #include #include +#ifdef HAVE_OPENGL +#include +#endif + /* Mint includes */ #include #include @@ -74,6 +78,15 @@ static void XBIOS_UnlockHWSurface(_THIS, SDL_Surface *surface); 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 xbiosmode_t xbiosmodelist_tt[]={ static int xbiosnummodes_f30rvb=16; static xbiosmode_t xbiosmodelist_f30rvb[]={ {BPS16|COL80|OVERSCAN|VERTFLAG,768,480,16,SDL_FALSE}, - {BPS16|COL80|OVERSCAN,768,240,16,SDL_FALSE}, - {BPS16|COL80|VERTFLAG,640,400,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|COL80|VERTFLAG,640,400,16,SDL_FALSE}, {BPS16|VERTFLAG,320,400,16,SDL_FALSE}, + {BPS16|COL80|OVERSCAN,768,240,16,SDL_FALSE}, + {BPS16|OVERSCAN,384,240,16,SDL_FALSE}, + {BPS16|COL80,640,200,16,SDL_FALSE}, {BPS16,320,200,16,SDL_FALSE}, {BPS8|COL80|OVERSCAN|VERTFLAG,768,480,8,SDL_FALSE}, - {BPS8|COL80|OVERSCAN,768,240,8,SDL_FALSE}, - {BPS8|COL80|VERTFLAG,640,400,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|COL80|VERTFLAG,640,400,8,SDL_FALSE}, {BPS8|VERTFLAG,320,400,8,SDL_FALSE}, + {BPS8|COL80|OVERSCAN,768,240,8,SDL_FALSE}, + {BPS8|OVERSCAN,384,240,8,SDL_FALSE}, + {BPS8|COL80,640,200,8,SDL_FALSE}, {BPS8,320,200,8,SDL_FALSE} }; @@ -118,8 +131,8 @@ static xbiosmode_t xbiosmodelist_f30vga[]={ {BPS16|VERTFLAG,320,240,16,SDL_FALSE}, {BPS8|COL80,640,480,8,SDL_FALSE}, - {BPS8|COL80|VERTFLAG,640,240,8,SDL_FALSE}, {BPS8,320,480,8,SDL_FALSE}, + {BPS8|COL80|VERTFLAG,640,240,8,SDL_FALSE}, {BPS8|VERTFLAG,320,240,8,SDL_FALSE} }; @@ -206,6 +219,15 @@ static SDL_VideoDevice *XBIOS_CreateDevice(int devindex) 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 @@ static int XBIOS_VideoInit(_THIS, SDL_PixelFormat *vformat) /* 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 @@ static void XBIOS_FreeBuffers(_THIS) { 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 @@ static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current, 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 @@ static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current, 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 @@ static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current, 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 @@ static int XBIOS_FlipHWSurface(_THIS, SDL_Surface *surface) 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 @@ static void XBIOS_VideoQuit(_THIS) 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 diff --git a/src/video/xbios/SDL_xbios.h b/src/video/xbios/SDL_xbios.h index 5120d8af9..395c45e10 100644 --- a/src/video/xbios/SDL_xbios.h +++ b/src/video/xbios/SDL_xbios.h @@ -28,6 +28,10 @@ static char rcsid = #ifndef _SDL_xbios_h #define _SDL_xbios_h +#ifdef HAVE_OPENGL +#include +#endif + #include "SDL_types.h" #include "SDL_sysvideo.h" @@ -69,6 +73,9 @@ struct SDL_PrivateVideoData { 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 @@ enum { #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 */ diff --git a/test/configure.in b/test/configure.in index bf331ce19..5143f4c6a 100644 --- a/test/configure.in +++ b/test/configure.in @@ -5,8 +5,7 @@ dnl Setup for automake 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 @@ case "$target" in *-*-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