Add OSMesa OpenGL support to the Atari GEM video driver
authorPatrice Mandin <patmandin@gmail.com>
Sun, 21 Nov 2004 21:59:47 +0000
changeset 98444fd54a0ae5f
parent 983 7f08bd66f1ca
child 985 cec525374267
Add OSMesa OpenGL support to the Atari GEM video driver
README.MiNT
src/video/gem/SDL_gemvideo.c
src/video/gem/SDL_gemvideo.h
     1.1 --- a/README.MiNT	Sun Nov 21 00:57:47 2004 +0000
     1.2 +++ b/README.MiNT	Sun Nov 21 21:59:47 2004 +0000
     1.3 @@ -60,7 +60,7 @@
     1.4  xbios   ikbd    ikbd    vbl(2)  ikbd      hardware	OSMesa
     1.5  xbios   gemdos  xbios   vbl(2)  xbios     hardware	OSMesa
     1.6  xbios   bios    xbios   vbl(2)  xbios     hardware	OSMesa
     1.7 -gem     gem     gem(1)  vbl(2)  xbios     hardware	no
     1.8 +gem     gem     gem(1)  vbl(2)  xbios     hardware	OSMesa
     1.9  
    1.10  (1) GEM does not report relative mouse motion, so xbios mouse driver is used
    1.11  to report this type event.
     2.1 --- a/src/video/gem/SDL_gemvideo.c	Sun Nov 21 00:57:47 2004 +0000
     2.2 +++ b/src/video/gem/SDL_gemvideo.c	Sun Nov 21 21:59:47 2004 +0000
     2.3 @@ -37,6 +37,10 @@
     2.4  #include <stdlib.h>
     2.5  #include <string.h>
     2.6  
     2.7 +#ifdef HAVE_OPENGL
     2.8 +#include <GL/osmesa.h>
     2.9 +#endif
    2.10 +
    2.11  /* Mint includes */
    2.12  #include <gem.h>
    2.13  #include <gemx.h>
    2.14 @@ -63,7 +67,7 @@
    2.15  
    2.16  /* Defines */
    2.17  
    2.18 -/* #define DEBUG_VIDEO_GEM	1 */
    2.19 +/*#define DEBUG_VIDEO_GEM	1*/
    2.20  
    2.21  #define GEM_VID_DRIVER_NAME "gem"
    2.22  
    2.23 @@ -107,6 +111,15 @@
    2.24  static void GEM_UnlockScreen(_THIS);
    2.25  static void refresh_window(_THIS, int winhandle, short *rect);
    2.26  
    2.27 +#ifdef HAVE_OPENGL
    2.28 +/* OpenGL functions */
    2.29 +static int GEM_GL_LoadLibrary(_THIS, const char *path);
    2.30 +static void *GEM_GL_GetProcAddress(_THIS, const char *proc);
    2.31 +static int GEM_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
    2.32 +static int GEM_GL_MakeCurrent(_THIS);
    2.33 +static void GEM_GL_SwapBuffers(_THIS);
    2.34 +#endif
    2.35 +
    2.36  /* GEM driver bootstrap functions */
    2.37  
    2.38  static int GEM_Available(void)
    2.39 @@ -176,6 +189,15 @@
    2.40  	device->WarpWMCursor = NULL /*GEM_WarpWMCursor*/;
    2.41  	device->CheckMouseMode = GEM_CheckMouseMode;
    2.42  
    2.43 +#ifdef HAVE_OPENGL
    2.44 +	/* OpenGL functions */
    2.45 +	device->GL_LoadLibrary = GEM_GL_LoadLibrary;
    2.46 +	device->GL_GetProcAddress = GEM_GL_GetProcAddress;
    2.47 +	device->GL_GetAttribute = GEM_GL_GetAttribute;
    2.48 +	device->GL_MakeCurrent = GEM_GL_MakeCurrent;
    2.49 +	device->GL_SwapBuffers = GEM_GL_SwapBuffers;
    2.50 +#endif
    2.51 +
    2.52  	/* Joystick + Mouse relative motion */
    2.53  	SDL_AtariXbios_InstallVectors(ATARI_XBIOS_MOUSEEVENTS|ATARI_XBIOS_JOYSTICKEVENTS);
    2.54  
    2.55 @@ -452,6 +474,10 @@
    2.56  	printf("sdl:video:gem: VideoInit(): done\n");
    2.57  #endif
    2.58  
    2.59 +#ifdef HAVE_OPENGL
    2.60 +	this->gl_config.driver_loaded = 1;
    2.61 +#endif
    2.62 +
    2.63  	/* We're done! */
    2.64  	return(0);
    2.65  }
    2.66 @@ -471,6 +497,14 @@
    2.67  
    2.68  static void GEM_FreeBuffers(_THIS)
    2.69  {
    2.70 +#ifdef HAVE_OPENGL
    2.71 +	/* Shutdown OpenGL context */
    2.72 +	if (GEM_ctx) {
    2.73 +		OSMesaDestroyContext(GEM_ctx);
    2.74 +		GEM_ctx = NULL;
    2.75 +	}
    2.76 +#endif
    2.77 +
    2.78  	/* Release buffer */
    2.79  	if ( GEM_buffer2 ) {
    2.80  		free( GEM_buffer2 );
    2.81 @@ -703,7 +737,6 @@
    2.82  	}
    2.83  
    2.84  	/* Set up the new mode framebuffer */
    2.85 -	current->flags = modeflags;
    2.86  	current->w = width;
    2.87  	current->h = height;
    2.88  	if (use_shadow1) {
    2.89 @@ -716,6 +749,57 @@
    2.90  		current->pitch = VDI_pitch;
    2.91  	}
    2.92  
    2.93 +#ifdef HAVE_OPENGL
    2.94 +	if (flags & SDL_OPENGL) {
    2.95 +		GLenum format = OSMESA_COLOR_INDEX;
    2.96 +
    2.97 +		/* Init OpenGL context using OSMesa */
    2.98 +		switch (VDI_bpp) {
    2.99 +			case 15:
   2.100 +				/* 1555, big and little endian unsupported */
   2.101 +				format = OSMESA_RGB_565;
   2.102 +				break;
   2.103 +			case 16:
   2.104 +				format = OSMESA_RGB_565;
   2.105 +				/* 565, little endian unsupported */
   2.106 +				break;
   2.107 +			case 24:
   2.108 +				if (VDI_redmask == 255<<16) {
   2.109 +					format = OSMESA_RGB;
   2.110 +				} else {
   2.111 +					format = OSMESA_BGR;
   2.112 +				}
   2.113 +				break;
   2.114 +			case 32:
   2.115 +				if (VDI_redmask == 255<<16) {
   2.116 +					format = OSMESA_ARGB;
   2.117 +				} else if (VDI_redmask == 255<<8) {
   2.118 +					format = OSMESA_BGRA;
   2.119 +				} else if (VDI_redmask == 255<<24) {
   2.120 +					format = OSMESA_RGBA;
   2.121 +				} else {
   2.122 +					/* ABGR format unsupported */
   2.123 +					format = OSMESA_BGRA;
   2.124 +				}
   2.125 +				break;
   2.126 +		}
   2.127 +
   2.128 +		GEM_ctx = OSMesaCreateContextExt( format, this->gl_config.depth_size,
   2.129 +			this->gl_config.stencil_size, this->gl_config.accum_red_size +
   2.130 +			this->gl_config.accum_green_size + this->gl_config.accum_blue_size +
   2.131 +			this->gl_config.accum_alpha_size, NULL );
   2.132 +		if (!GEM_ctx) {
   2.133 +			GEM_FreeBuffers(this);
   2.134 +			SDL_SetError("OSMesaCreateContext failed");
   2.135 +			return(NULL);
   2.136 +		}
   2.137 +
   2.138 +		modeflags |= SDL_OPENGL;
   2.139 +	}
   2.140 +#endif
   2.141 +
   2.142 +	current->flags = modeflags;
   2.143 +
   2.144  #ifdef DEBUG_VIDEO_GEM
   2.145  	printf("sdl:video:gem: surface: %dx%d\n", current->w, current->h);
   2.146  #endif
   2.147 @@ -1248,3 +1332,109 @@
   2.148  
   2.149  	vro_cpyfm( VDI_handle, S_ONLY, pxy, &mfdb_src, &VDI_dst_mfdb);
   2.150  }
   2.151 +
   2.152 +#ifdef HAVE_OPENGL
   2.153 +
   2.154 +static int GEM_GL_LoadLibrary(_THIS, const char *path)
   2.155 +{
   2.156 +	/* Library is always opened */
   2.157 +	this->gl_config.driver_loaded = 1;
   2.158 +
   2.159 +	return 0;
   2.160 +}
   2.161 +
   2.162 +static void *GEM_GL_GetProcAddress(_THIS, const char *proc)
   2.163 +{
   2.164 +	void *func = NULL;
   2.165 +
   2.166 +	if (GEM_ctx != NULL) {
   2.167 +		func = OSMesaGetProcAddress(proc);
   2.168 +	}
   2.169 +
   2.170 +	return func;
   2.171 +}
   2.172 +
   2.173 +static int GEM_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
   2.174 +{
   2.175 +	GLenum mesa_attrib;
   2.176 +
   2.177 +	if (GEM_ctx == NULL) {
   2.178 +		return -1;
   2.179 +	}
   2.180 +
   2.181 +	switch(attrib) {
   2.182 +		case SDL_GL_RED_SIZE:
   2.183 +			mesa_attrib = GL_RED_BITS;
   2.184 +			break;
   2.185 +		case SDL_GL_GREEN_SIZE:
   2.186 +			mesa_attrib = GL_GREEN_BITS;
   2.187 +			break;
   2.188 +		case SDL_GL_BLUE_SIZE:
   2.189 +			mesa_attrib = GL_BLUE_BITS;
   2.190 +			break;
   2.191 +		case SDL_GL_ALPHA_SIZE:
   2.192 +			mesa_attrib = GL_ALPHA_BITS;
   2.193 +			break;
   2.194 +		case SDL_GL_DOUBLEBUFFER:
   2.195 +			mesa_attrib = GL_DOUBLEBUFFER;
   2.196 +			break;
   2.197 +		case SDL_GL_DEPTH_SIZE:
   2.198 +			mesa_attrib = GL_DEPTH_BITS;
   2.199 +			break;
   2.200 +		case SDL_GL_STENCIL_SIZE:
   2.201 +			mesa_attrib = GL_STENCIL_BITS;
   2.202 +			break;
   2.203 +		case SDL_GL_ACCUM_RED_SIZE:
   2.204 +			mesa_attrib = GL_ACCUM_RED_BITS;
   2.205 +			break;
   2.206 +		case SDL_GL_ACCUM_GREEN_SIZE:
   2.207 +			mesa_attrib = GL_ACCUM_GREEN_BITS;
   2.208 +			break;
   2.209 +		case SDL_GL_ACCUM_BLUE_SIZE:
   2.210 +			mesa_attrib = GL_ACCUM_BLUE_BITS;
   2.211 +			break;
   2.212 +		case SDL_GL_ACCUM_ALPHA_SIZE:
   2.213 +			mesa_attrib = GL_ACCUM_ALPHA_BITS;
   2.214 +			break;
   2.215 +		default :
   2.216 +			return -1;
   2.217 +	}
   2.218 +
   2.219 +	glGetIntegerv(mesa_attrib, value);
   2.220 +	return 0;
   2.221 +}
   2.222 +
   2.223 +static int GEM_GL_MakeCurrent(_THIS)
   2.224 +{
   2.225 +	SDL_Surface *surface;
   2.226 +	GLenum type;
   2.227 +
   2.228 +	if (GEM_ctx == NULL) {
   2.229 +		return -1;
   2.230 +	}
   2.231 +
   2.232 +	surface = this->screen;
   2.233 +	
   2.234 +	if ((surface->format->BitsPerPixel == 15) || (surface->format->BitsPerPixel == 16)) {
   2.235 +		type = GL_UNSIGNED_SHORT_5_6_5;
   2.236 +	} else {
   2.237 +		type = GL_UNSIGNED_BYTE;
   2.238 +	}
   2.239 +
   2.240 +	if (!OSMesaMakeCurrent(GEM_ctx, surface->pixels, type, surface->w, surface->h)) {
   2.241 +		SDL_SetError("Can not make OpenGL context current");
   2.242 +		return -1;
   2.243 +	}
   2.244 +
   2.245 +	/* OSMesa draws upside down */
   2.246 +	OSMesaPixelStore(OSMESA_Y_UP, 0);
   2.247 +
   2.248 +	return 0;
   2.249 +}
   2.250 +
   2.251 +static void GEM_GL_SwapBuffers(_THIS)
   2.252 +{
   2.253 +	GEM_FlipHWSurface(this, this->screen);
   2.254 +}
   2.255 +
   2.256 +#endif
     3.1 --- a/src/video/gem/SDL_gemvideo.h	Sun Nov 21 00:57:47 2004 +0000
     3.2 +++ b/src/video/gem/SDL_gemvideo.h	Sun Nov 21 21:59:47 2004 +0000
     3.3 @@ -28,6 +28,10 @@
     3.4  #ifndef _SDL_gemvideo_h
     3.5  #define _SDL_gemvideo_h
     3.6  
     3.7 +#ifdef HAVE_OPENGL
     3.8 +#include <GL/osmesa.h>
     3.9 +#endif
    3.10 +
    3.11  #include "SDL_sysvideo.h"
    3.12  #include "SDL_mutex.h"
    3.13  
    3.14 @@ -85,6 +89,10 @@
    3.15  	SDL_bool fullscreen;		/* Fullscreen or windowed mode ? */
    3.16  	SDL_Rect *SDL_modelist[SDL_NUMMODES+1];	/* Mode list */
    3.17  	SDL_Surface *icon;			/* The icon */
    3.18 +
    3.19 +#ifdef HAVE_OPENGL
    3.20 +	OSMesaContext	ctx;		/* OSMesa OpenGL context */
    3.21 +#endif
    3.22  };
    3.23  
    3.24  /* Hidden structure -> variables names */
    3.25 @@ -131,6 +139,8 @@
    3.26  #define GEM_buffer2			(this->hidden->buffer2)
    3.27  #define GEM_bufops			(this->hidden->buf2scr_ops)
    3.28  
    3.29 +#define GEM_ctx				(this->hidden->ctx)
    3.30 +
    3.31  #define VDI_FBMASK(amask, rmask, gmask, bmask) \
    3.32  	VDI_alphamask = (amask); \
    3.33  	VDI_redmask = (rmask); \