src/video/ataricommon/SDL_atarigl.c
author Patrice Mandin
Fri, 26 Nov 2004 22:11:30 +0000
changeset 992 0324ce32b2d9
parent 991 12b13601a544
child 993 2662da16d668
permissions -rw-r--r--
Keep current OpenGL context when possible
patmandin@989
     1
/*
patmandin@989
     2
    SDL - Simple DirectMedia Layer
patmandin@989
     3
    Copyright (C) 1997-2004 Sam Lantinga
patmandin@989
     4
patmandin@989
     5
    This library is free software; you can redistribute it and/or
patmandin@989
     6
    modify it under the terms of the GNU Library General Public
patmandin@989
     7
    License as published by the Free Software Foundation; either
patmandin@989
     8
    version 2 of the License, or (at your option) any later version.
patmandin@989
     9
patmandin@989
    10
    This library is distributed in the hope that it will be useful,
patmandin@989
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
patmandin@989
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
patmandin@989
    13
    Library General Public License for more details.
patmandin@989
    14
patmandin@989
    15
    You should have received a copy of the GNU Library General Public
patmandin@989
    16
    License along with this library; if not, write to the Free
patmandin@989
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
patmandin@989
    18
patmandin@989
    19
    Sam Lantinga
patmandin@989
    20
    slouken@libsdl.org
patmandin@989
    21
*/
patmandin@989
    22
patmandin@989
    23
/* Atari OSMesa.ldg implementation of SDL OpenGL support */
patmandin@989
    24
patmandin@989
    25
/*--- Includes ---*/
patmandin@989
    26
patmandin@991
    27
#include <stdio.h>
patmandin@991
    28
#include <stdlib.h>
patmandin@991
    29
#include <string.h>
patmandin@989
    30
#ifdef HAVE_OPENGL
patmandin@989
    31
#include <GL/osmesa.h>
patmandin@989
    32
#endif
patmandin@989
    33
patmandin@991
    34
#include <mint/osbind.h>
patmandin@991
    35
patmandin@989
    36
#include "SDL_video.h"
patmandin@989
    37
#include "SDL_error.h"
patmandin@989
    38
#include "SDL_endian.h"
patmandin@989
    39
#include "SDL_atarigl_c.h"
patmandin@991
    40
#ifdef ENABLE_OSMESA_SHARED
patmandin@991
    41
#include "SDL_loadso.h"
patmandin@991
    42
#endif
patmandin@989
    43
patmandin@991
    44
/*--- Defines ---*/
patmandin@991
    45
patmandin@991
    46
#define PATH_OSMESA_LDG	"osmesa.ldg"
patmandin@991
    47
#define PATH_MESAGL_LDG	"mesa_gl.ldg"
patmandin@991
    48
#define PATH_TINYGL_LDG	"tiny_gl.ldg"
patmandin@989
    49
patmandin@989
    50
/*--- Functions prototypes ---*/
patmandin@989
    51
patmandin@991
    52
static void SDL_AtariGL_UnloadLibrary(_THIS);
patmandin@991
    53
patmandin@991
    54
static void CopyShadowNull(_THIS, SDL_Surface *surface);
patmandin@991
    55
static void CopyShadowDirect(_THIS, SDL_Surface *surface);
patmandin@991
    56
static void CopyShadow8888To555(_THIS, SDL_Surface *surface);
patmandin@991
    57
static void CopyShadow8888To565(_THIS, SDL_Surface *surface);
patmandin@991
    58
patmandin@991
    59
static void ConvertNull(_THIS, SDL_Surface *surface);
patmandin@991
    60
static void Convert565To555be(_THIS, SDL_Surface *surface);
patmandin@991
    61
static void Convert565To555le(_THIS, SDL_Surface *surface);
patmandin@991
    62
static void Convert565le(_THIS, SDL_Surface *surface);
patmandin@991
    63
static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface);
patmandin@991
    64
patmandin@991
    65
static int InitNew(_THIS, SDL_Surface *current);
patmandin@991
    66
static int InitOld(_THIS, SDL_Surface *current);
patmandin@989
    67
patmandin@989
    68
/*--- Public functions ---*/
patmandin@989
    69
patmandin@989
    70
int SDL_AtariGL_Init(_THIS, SDL_Surface *current)
patmandin@989
    71
{
patmandin@989
    72
#ifdef HAVE_OPENGL
patmandin@991
    73
	if (gl_oldmesa) {
patmandin@991
    74
		gl_active = InitOld(this, current);		
patmandin@991
    75
	} else {
patmandin@991
    76
		gl_active = InitNew(this, current);		
patmandin@991
    77
	}
patmandin@991
    78
#endif
patmandin@989
    79
patmandin@989
    80
	return (gl_active);
patmandin@989
    81
}
patmandin@989
    82
patmandin@992
    83
void SDL_AtariGL_Quit(_THIS, SDL_bool unload)
patmandin@989
    84
{
patmandin@989
    85
#ifdef HAVE_OPENGL
patmandin@991
    86
	if (gl_oldmesa) {
patmandin@991
    87
		/* Old mesa implementations */
patmandin@991
    88
		if (this->gl_data->OSMesaDestroyLDG) {
patmandin@991
    89
			this->gl_data->OSMesaDestroyLDG();
patmandin@991
    90
		}
patmandin@991
    91
		if (gl_shadow) {
patmandin@991
    92
			Mfree(gl_shadow);
patmandin@991
    93
			gl_shadow = NULL;
patmandin@991
    94
		}
patmandin@991
    95
	} else {
patmandin@991
    96
		/* New mesa implementation */
patmandin@991
    97
		if (gl_ctx) {
patmandin@991
    98
			if (this->gl_data->OSMesaDestroyContext) {
patmandin@991
    99
				this->gl_data->OSMesaDestroyContext(gl_ctx);
patmandin@991
   100
			}
patmandin@991
   101
			gl_ctx = NULL;
patmandin@991
   102
		}
patmandin@991
   103
	}
patmandin@991
   104
patmandin@992
   105
	if (unload) {
patmandin@992
   106
		SDL_AtariGL_UnloadLibrary(this);
patmandin@992
   107
	}
patmandin@991
   108
patmandin@991
   109
#endif /* HAVE_OPENGL */
patmandin@989
   110
	gl_active = 0;
patmandin@989
   111
}
patmandin@989
   112
patmandin@989
   113
int SDL_AtariGL_LoadLibrary(_THIS, const char *path)
patmandin@989
   114
{
patmandin@989
   115
#ifdef HAVE_OPENGL
patmandin@991
   116
patmandin@991
   117
#ifdef ENABLE_OSMESA_SHARED
patmandin@991
   118
	void *handle;
patmandin@991
   119
patmandin@991
   120
	if (gl_active) {
patmandin@991
   121
		SDL_SetError("OpenGL context already created");
patmandin@991
   122
		return -1;
patmandin@991
   123
	}
patmandin@991
   124
patmandin@991
   125
	/* Unload previous driver */
patmandin@991
   126
	SDL_AtariGL_UnloadLibrary(this);
patmandin@991
   127
patmandin@991
   128
	/* Load library given by path */
patmandin@991
   129
	handle = SDL_LoadObject(path);
patmandin@991
   130
	if (handle == NULL) {
patmandin@991
   131
		/* Try to load another one */
patmandin@991
   132
		path = getenv("SDL_VIDEO_GL_DRIVER");
patmandin@991
   133
		if ( path != NULL ) {
patmandin@991
   134
			handle = SDL_LoadObject(path);
patmandin@991
   135
		}
patmandin@991
   136
patmandin@991
   137
		/* If it does not work, try some other */
patmandin@991
   138
		if (handle == NULL) {
patmandin@991
   139
			path = PATH_OSMESA_LDG;
patmandin@991
   140
			handle = SDL_LoadObject(path);
patmandin@991
   141
		}
patmandin@991
   142
patmandin@991
   143
		if (handle == NULL) {
patmandin@991
   144
			path = PATH_MESAGL_LDG;
patmandin@991
   145
			handle = SDL_LoadObject(path);
patmandin@991
   146
		}
patmandin@991
   147
patmandin@991
   148
		if (handle == NULL) {
patmandin@991
   149
			path = PATH_TINYGL_LDG;
patmandin@991
   150
			handle = SDL_LoadObject(path);
patmandin@991
   151
		}
patmandin@991
   152
	}
patmandin@991
   153
patmandin@991
   154
	if (handle == NULL) {
patmandin@991
   155
		SDL_SetError("Could not load OpenGL library");
patmandin@991
   156
		return -1;
patmandin@991
   157
	}
patmandin@991
   158
patmandin@991
   159
	/* Load functions pointers (osmesa.ldg) */
patmandin@991
   160
	this->gl_data->OSMesaCreateContextExt = SDL_LoadFunction(handle, "OSMesaCreateContextExt");
patmandin@991
   161
	this->gl_data->OSMesaDestroyContext = SDL_LoadFunction(handle, "OSMesaDestroyContext");
patmandin@991
   162
	this->gl_data->OSMesaMakeCurrent = SDL_LoadFunction(handle, "OSMesaMakeCurrent");
patmandin@991
   163
	this->gl_data->OSMesaPixelStore = SDL_LoadFunction(handle, "OSMesaPixelStore");
patmandin@991
   164
	this->gl_data->OSMesaGetProcAddress = SDL_LoadFunction(handle, "OSMesaGetProcAddress");
patmandin@991
   165
	this->gl_data->glGetIntegerv = SDL_LoadFunction(handle, "glGetIntegerv");
patmandin@991
   166
patmandin@991
   167
	/* Load old functions pointers (mesa_gl.ldg, tiny_gl.ldg) */
patmandin@991
   168
	this->gl_data->OSMesaCreateLDG = SDL_LoadFunction(handle, "OSMesaCreateLDG");
patmandin@991
   169
	this->gl_data->OSMesaDestroyLDG = SDL_LoadFunction(handle, "OSMesaDestroyLDG");
patmandin@991
   170
patmandin@991
   171
	gl_oldmesa = 0;
patmandin@991
   172
patmandin@991
   173
	if ( (this->gl_data->OSMesaCreateContextExt == NULL) || 
patmandin@991
   174
	     (this->gl_data->OSMesaDestroyContext == NULL) ||
patmandin@991
   175
	     (this->gl_data->OSMesaMakeCurrent == NULL) ||
patmandin@991
   176
	     (this->gl_data->OSMesaPixelStore == NULL) ||
patmandin@991
   177
	     (this->gl_data->glGetIntegerv == NULL) ||
patmandin@991
   178
	     (this->gl_data->OSMesaGetProcAddress == NULL)) {
patmandin@991
   179
		/* Hum, maybe old library ? */
patmandin@991
   180
		if ( (this->gl_data->OSMesaCreateLDG == NULL) || 
patmandin@991
   181
		     (this->gl_data->OSMesaDestroyLDG == NULL)) {
patmandin@991
   182
			SDL_SetError("Could not retrieve OpenGL functions");
patmandin@991
   183
			return -1;
patmandin@991
   184
		} else {
patmandin@991
   185
			gl_oldmesa = 1;
patmandin@991
   186
		}
patmandin@991
   187
	}
patmandin@991
   188
patmandin@991
   189
	this->gl_config.dll_handle = handle;
patmandin@991
   190
	if ( path ) {
patmandin@991
   191
		strncpy(this->gl_config.driver_path, path,
patmandin@991
   192
			sizeof(this->gl_config.driver_path)-1);
patmandin@991
   193
	} else {
patmandin@991
   194
		strcpy(this->gl_config.driver_path, "");
patmandin@991
   195
	}
patmandin@991
   196
patmandin@991
   197
#endif
patmandin@989
   198
	this->gl_config.driver_loaded = 1;
patmandin@991
   199
patmandin@991
   200
	return 0;
patmandin@991
   201
#else
patmandin@991
   202
	return -1;
patmandin@989
   203
#endif
patmandin@989
   204
}
patmandin@989
   205
patmandin@989
   206
void *SDL_AtariGL_GetProcAddress(_THIS, const char *proc)
patmandin@989
   207
{
patmandin@989
   208
	void *func = NULL;
patmandin@989
   209
#ifdef HAVE_OPENGL
patmandin@991
   210
patmandin@991
   211
	if (this->gl_config.dll_handle) {
patmandin@991
   212
		func = SDL_LoadFunction(this->gl_config.dll_handle, (void *)proc);
patmandin@991
   213
	} else if (this->gl_data->OSMesaGetProcAddress) {
patmandin@991
   214
		func = this->gl_data->OSMesaGetProcAddress(proc);
patmandin@989
   215
	}
patmandin@991
   216
patmandin@989
   217
#endif
patmandin@989
   218
	return func;
patmandin@989
   219
}
patmandin@989
   220
patmandin@989
   221
int SDL_AtariGL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
patmandin@989
   222
{
patmandin@989
   223
#ifdef HAVE_OPENGL
patmandin@989
   224
	GLenum mesa_attrib;
patmandin@989
   225
	SDL_Surface *surface;
patmandin@989
   226
patmandin@991
   227
	if (this->gl_config.dll_handle) {
patmandin@991
   228
		if (this->gl_data->glGetIntegerv == NULL) {
patmandin@991
   229
			return -1;
patmandin@991
   230
		}
patmandin@991
   231
	}
patmandin@991
   232
patmandin@991
   233
	if (!gl_active) {
patmandin@989
   234
		return -1;
patmandin@989
   235
	}
patmandin@989
   236
patmandin@989
   237
	switch(attrib) {
patmandin@989
   238
		case SDL_GL_RED_SIZE:
patmandin@989
   239
			mesa_attrib = GL_RED_BITS;
patmandin@989
   240
			break;
patmandin@989
   241
		case SDL_GL_GREEN_SIZE:
patmandin@989
   242
			mesa_attrib = GL_GREEN_BITS;
patmandin@989
   243
			break;
patmandin@989
   244
		case SDL_GL_BLUE_SIZE:
patmandin@989
   245
			mesa_attrib = GL_BLUE_BITS;
patmandin@989
   246
			break;
patmandin@989
   247
		case SDL_GL_ALPHA_SIZE:
patmandin@989
   248
			mesa_attrib = GL_ALPHA_BITS;
patmandin@989
   249
			break;
patmandin@989
   250
		case SDL_GL_DOUBLEBUFFER:
patmandin@989
   251
			surface = this->screen;
patmandin@989
   252
			*value = ((surface->flags & SDL_DOUBLEBUF)==SDL_DOUBLEBUF);
patmandin@989
   253
			return 0;
patmandin@989
   254
		case SDL_GL_DEPTH_SIZE:
patmandin@989
   255
			mesa_attrib = GL_DEPTH_BITS;
patmandin@989
   256
			break;
patmandin@989
   257
		case SDL_GL_STENCIL_SIZE:
patmandin@989
   258
			mesa_attrib = GL_STENCIL_BITS;
patmandin@989
   259
			break;
patmandin@989
   260
		case SDL_GL_ACCUM_RED_SIZE:
patmandin@989
   261
			mesa_attrib = GL_ACCUM_RED_BITS;
patmandin@989
   262
			break;
patmandin@989
   263
		case SDL_GL_ACCUM_GREEN_SIZE:
patmandin@989
   264
			mesa_attrib = GL_ACCUM_GREEN_BITS;
patmandin@989
   265
			break;
patmandin@989
   266
		case SDL_GL_ACCUM_BLUE_SIZE:
patmandin@989
   267
			mesa_attrib = GL_ACCUM_BLUE_BITS;
patmandin@989
   268
			break;
patmandin@989
   269
		case SDL_GL_ACCUM_ALPHA_SIZE:
patmandin@989
   270
			mesa_attrib = GL_ACCUM_ALPHA_BITS;
patmandin@989
   271
			break;
patmandin@989
   272
		default :
patmandin@989
   273
			return -1;
patmandin@989
   274
	}
patmandin@989
   275
patmandin@991
   276
	this->gl_data->glGetIntegerv(mesa_attrib, value);
patmandin@989
   277
	return 0;
patmandin@989
   278
#else
patmandin@989
   279
	return -1;
patmandin@989
   280
#endif
patmandin@989
   281
}
patmandin@989
   282
patmandin@989
   283
int SDL_AtariGL_MakeCurrent(_THIS)
patmandin@989
   284
{
patmandin@989
   285
#ifdef HAVE_OPENGL
patmandin@989
   286
	SDL_Surface *surface;
patmandin@989
   287
	GLenum type;
patmandin@989
   288
patmandin@991
   289
	if (gl_oldmesa && gl_active) {
patmandin@991
   290
		return 0;
patmandin@991
   291
	}
patmandin@991
   292
patmandin@991
   293
	if (this->gl_config.dll_handle) {
patmandin@991
   294
		if ((this->gl_data->OSMesaMakeCurrent == NULL) ||
patmandin@991
   295
			(this->gl_data->OSMesaPixelStore == NULL)) {
patmandin@991
   296
			return -1;
patmandin@991
   297
		}
patmandin@991
   298
	}
patmandin@991
   299
patmandin@991
   300
	if (!gl_active) {
patmandin@989
   301
		SDL_SetError("Invalid OpenGL context");
patmandin@989
   302
		return -1;
patmandin@989
   303
	}
patmandin@989
   304
patmandin@989
   305
	surface = this->screen;
patmandin@989
   306
	
patmandin@989
   307
	if ((surface->format->BitsPerPixel == 15) || (surface->format->BitsPerPixel == 16)) {
patmandin@989
   308
		type = GL_UNSIGNED_SHORT_5_6_5;
patmandin@989
   309
	} else {
patmandin@989
   310
		type = GL_UNSIGNED_BYTE;
patmandin@989
   311
	}
patmandin@989
   312
patmandin@991
   313
	if (!(this->gl_data->OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w, surface->h))) {
patmandin@989
   314
		SDL_SetError("Can not make OpenGL context current");
patmandin@989
   315
		return -1;
patmandin@989
   316
	}
patmandin@989
   317
patmandin@989
   318
	/* OSMesa draws upside down */
patmandin@991
   319
	this->gl_data->OSMesaPixelStore(OSMESA_Y_UP, 0);
patmandin@989
   320
patmandin@989
   321
	return 0;
patmandin@989
   322
#else
patmandin@989
   323
	return -1;
patmandin@989
   324
#endif
patmandin@989
   325
}
patmandin@989
   326
patmandin@989
   327
void SDL_AtariGL_SwapBuffers(_THIS)
patmandin@989
   328
{
patmandin@989
   329
#ifdef HAVE_OPENGL
patmandin@991
   330
	if (gl_active) {
patmandin@991
   331
		gl_copyshadow(this, this->screen);
patmandin@991
   332
		gl_convert(this, this->screen);
patmandin@989
   333
	}
patmandin@991
   334
#endif
patmandin@991
   335
}
patmandin@989
   336
patmandin@991
   337
void SDL_AtariGL_InitPointers(_THIS)
patmandin@991
   338
{
patmandin@991
   339
#if defined(HAVE_OPENGL)
patmandin@991
   340
	this->gl_data->OSMesaCreateContextExt = OSMesaCreateContextExt;
patmandin@991
   341
	this->gl_data->OSMesaDestroyContext = OSMesaDestroyContext;
patmandin@991
   342
	this->gl_data->OSMesaMakeCurrent = OSMesaMakeCurrent;
patmandin@991
   343
	this->gl_data->OSMesaPixelStore = OSMesaPixelStore;
patmandin@991
   344
	this->gl_data->OSMesaGetProcAddress = OSMesaGetProcAddress;
patmandin@991
   345
	this->gl_data->glGetIntegerv = glGetIntegerv;
patmandin@989
   346
#endif
patmandin@989
   347
}
patmandin@989
   348
patmandin@989
   349
/*--- Private functions ---*/
patmandin@989
   350
patmandin@991
   351
static void SDL_AtariGL_UnloadLibrary(_THIS)
patmandin@991
   352
{
patmandin@991
   353
#if defined(HAVE_OPENGL)
patmandin@991
   354
	if (this->gl_config.dll_handle) {
patmandin@991
   355
		SDL_UnloadObject(this->gl_config.dll_handle);
patmandin@991
   356
		this->gl_config.dll_handle = NULL;
patmandin@991
   357
patmandin@991
   358
		/* Restore pointers to static library */
patmandin@991
   359
		this->gl_data->OSMesaCreateContextExt = OSMesaCreateContextExt;
patmandin@991
   360
		this->gl_data->OSMesaDestroyContext = OSMesaDestroyContext;
patmandin@991
   361
		this->gl_data->OSMesaMakeCurrent = OSMesaMakeCurrent;
patmandin@991
   362
		this->gl_data->OSMesaPixelStore = OSMesaPixelStore;
patmandin@991
   363
		this->gl_data->OSMesaGetProcAddress = OSMesaGetProcAddress;
patmandin@991
   364
		this->gl_data->glGetIntegerv = glGetIntegerv;
patmandin@991
   365
patmandin@991
   366
		this->gl_data->OSMesaCreateLDG = NULL;
patmandin@991
   367
		this->gl_data->OSMesaDestroyLDG = NULL;
patmandin@991
   368
	}
patmandin@991
   369
#endif
patmandin@991
   370
}
patmandin@991
   371
patmandin@991
   372
/*--- Creation of an OpenGL context using new/old functions ---*/
patmandin@991
   373
patmandin@991
   374
static int InitNew(_THIS, SDL_Surface *current)
patmandin@991
   375
{
patmandin@991
   376
	GLenum osmesa_format;
patmandin@991
   377
	SDL_PixelFormat *pixel_format;
patmandin@991
   378
	Uint32	redmask;
patmandin@992
   379
	int recreatecontext;
patmandin@992
   380
	GLint newaccumsize;
patmandin@991
   381
patmandin@991
   382
	if (this->gl_config.dll_handle) {
patmandin@991
   383
		if (this->gl_data->OSMesaCreateContextExt == NULL) {
patmandin@991
   384
			return 0;
patmandin@991
   385
		}
patmandin@991
   386
	}
patmandin@991
   387
patmandin@991
   388
	/* Init OpenGL context using OSMesa */
patmandin@991
   389
	gl_convert = ConvertNull;
patmandin@991
   390
	gl_copyshadow = CopyShadowNull;
patmandin@991
   391
patmandin@991
   392
	pixel_format = current->format;
patmandin@991
   393
	redmask = pixel_format->Rmask;
patmandin@991
   394
	switch (pixel_format->BitsPerPixel) {
patmandin@991
   395
		case 15:
patmandin@991
   396
			/* 1555, big and little endian, unsupported */
patmandin@991
   397
			gl_pixelsize = 2;
patmandin@991
   398
			osmesa_format = OSMESA_RGB_565;
patmandin@991
   399
			if (redmask == 31<<10) {
patmandin@991
   400
				gl_convert = Convert565To555be;
patmandin@991
   401
			} else {
patmandin@991
   402
				gl_convert = Convert565To555le;
patmandin@991
   403
			}
patmandin@991
   404
			break;
patmandin@991
   405
		case 16:
patmandin@991
   406
			gl_pixelsize = 2;
patmandin@991
   407
			if (redmask == 31<<11) {
patmandin@991
   408
				osmesa_format = OSMESA_RGB_565;
patmandin@991
   409
			} else {
patmandin@991
   410
				/* 565, little endian, unsupported */
patmandin@991
   411
				osmesa_format = OSMESA_RGB_565;
patmandin@991
   412
				gl_convert = Convert565le;
patmandin@991
   413
			}
patmandin@991
   414
			break;
patmandin@991
   415
		case 24:
patmandin@991
   416
			gl_pixelsize = 3;
patmandin@991
   417
			if (redmask == 255<<16) {
patmandin@991
   418
				osmesa_format = OSMESA_RGB;
patmandin@991
   419
			} else {
patmandin@991
   420
				osmesa_format = OSMESA_BGR;
patmandin@991
   421
			}
patmandin@991
   422
			break;
patmandin@991
   423
		case 32:
patmandin@991
   424
			gl_pixelsize = 4;
patmandin@991
   425
			if (redmask == 255<<16) {
patmandin@991
   426
				osmesa_format = OSMESA_ARGB;
patmandin@991
   427
			} else if (redmask == 255<<8) {
patmandin@991
   428
				osmesa_format = OSMESA_BGRA;
patmandin@991
   429
			} else if (redmask == 255<<24) {
patmandin@991
   430
				osmesa_format = OSMESA_RGBA;
patmandin@991
   431
			} else {
patmandin@991
   432
				/* ABGR format unsupported */
patmandin@991
   433
				osmesa_format = OSMESA_BGRA;
patmandin@991
   434
				gl_convert = ConvertBGRAToABGR;
patmandin@991
   435
			}
patmandin@991
   436
			break;
patmandin@991
   437
		default:
patmandin@991
   438
			gl_pixelsize = 1;
patmandin@991
   439
			osmesa_format = OSMESA_COLOR_INDEX;
patmandin@991
   440
			break;
patmandin@991
   441
	}
patmandin@991
   442
patmandin@992
   443
	/* Try to keep current context if possible */
patmandin@992
   444
	newaccumsize =
patmandin@992
   445
		this->gl_config.accum_red_size +
patmandin@992
   446
		this->gl_config.accum_green_size +
patmandin@992
   447
		this->gl_config.accum_blue_size +
patmandin@992
   448
		this->gl_config.accum_alpha_size;
patmandin@992
   449
	recreatecontext=1;
patmandin@992
   450
	if (gl_ctx &&
patmandin@992
   451
		(gl_curformat == osmesa_format) &&
patmandin@992
   452
		(gl_curdepth == this->gl_config.depth_size) &&
patmandin@992
   453
		(gl_curstencil == this->gl_config.stencil_size) &&
patmandin@992
   454
		(gl_curaccum == newaccumsize)) {
patmandin@992
   455
		recreatecontext = 0;
patmandin@992
   456
	}
patmandin@992
   457
	if (recreatecontext) {
patmandin@992
   458
		SDL_AtariGL_Quit(this, SDL_FALSE);
patmandin@992
   459
patmandin@992
   460
		gl_ctx = this->gl_data->OSMesaCreateContextExt(
patmandin@992
   461
			osmesa_format, this->gl_config.depth_size,
patmandin@992
   462
			this->gl_config.stencil_size, newaccumsize, NULL );
patmandin@992
   463
patmandin@992
   464
		if (gl_ctx) {
patmandin@992
   465
			gl_curformat = osmesa_format;
patmandin@992
   466
			gl_curdepth = this->gl_config.depth_size;
patmandin@992
   467
			gl_curstencil = this->gl_config.stencil_size;
patmandin@992
   468
			gl_curaccum = newaccumsize;
patmandin@992
   469
		} else {
patmandin@992
   470
			gl_curformat = 0;
patmandin@992
   471
			gl_curdepth = 0;
patmandin@992
   472
			gl_curstencil = 0;
patmandin@992
   473
			gl_curaccum = 0;
patmandin@992
   474
		}
patmandin@992
   475
	}
patmandin@991
   476
patmandin@991
   477
	return (gl_ctx != NULL);
patmandin@991
   478
}
patmandin@991
   479
patmandin@991
   480
static int InitOld(_THIS, SDL_Surface *current)
patmandin@991
   481
{
patmandin@991
   482
	GLenum osmesa_format;
patmandin@991
   483
	SDL_PixelFormat *pixel_format;
patmandin@991
   484
	Uint32	redmask;
patmandin@992
   485
	int recreatecontext;
patmandin@991
   486
patmandin@991
   487
	if (this->gl_config.dll_handle) {
patmandin@991
   488
		if (this->gl_data->OSMesaCreateLDG == NULL) {
patmandin@991
   489
			return 0;
patmandin@991
   490
		}
patmandin@991
   491
	}
patmandin@991
   492
patmandin@991
   493
	/* Init OpenGL context using OSMesa */
patmandin@991
   494
	gl_convert = ConvertNull;
patmandin@991
   495
	gl_copyshadow = CopyShadowNull;
patmandin@991
   496
patmandin@991
   497
	pixel_format = current->format;
patmandin@991
   498
	redmask = pixel_format->Rmask;
patmandin@991
   499
	switch (pixel_format->BitsPerPixel) {
patmandin@991
   500
		case 15:
patmandin@991
   501
			/* 15 bits unsupported */
patmandin@991
   502
			gl_pixelsize = 2;
patmandin@991
   503
			osmesa_format = OSMESA_ARGB;
patmandin@991
   504
			if (redmask == 31<<10) {
patmandin@991
   505
				gl_copyshadow = CopyShadow8888To555;
patmandin@991
   506
			} else {
patmandin@991
   507
				gl_copyshadow = CopyShadow8888To565;
patmandin@991
   508
				gl_convert = Convert565To555le;
patmandin@991
   509
			}
patmandin@991
   510
			break;
patmandin@991
   511
		case 16:
patmandin@991
   512
			/* 16 bits unsupported */
patmandin@991
   513
			gl_pixelsize = 2;
patmandin@991
   514
			osmesa_format = OSMESA_ARGB;
patmandin@991
   515
			gl_copyshadow = CopyShadow8888To565;
patmandin@991
   516
			if (redmask != 31<<11) {
patmandin@991
   517
				/* 565, little endian, unsupported */
patmandin@991
   518
				gl_convert = Convert565le;
patmandin@991
   519
			}
patmandin@991
   520
			break;
patmandin@991
   521
		case 24:
patmandin@991
   522
			gl_pixelsize = 3;
patmandin@991
   523
			gl_copyshadow = CopyShadowDirect;
patmandin@991
   524
			if (redmask == 255<<16) {
patmandin@991
   525
				osmesa_format = OSMESA_RGB;
patmandin@991
   526
			} else {
patmandin@991
   527
				osmesa_format = OSMESA_BGR;
patmandin@991
   528
			}
patmandin@991
   529
			break;
patmandin@991
   530
		case 32:
patmandin@991
   531
			gl_pixelsize = 4;
patmandin@991
   532
			gl_copyshadow = CopyShadowDirect;
patmandin@991
   533
			if (redmask == 255<<16) {
patmandin@991
   534
				osmesa_format = OSMESA_ARGB;
patmandin@991
   535
			} else if (redmask == 255<<8) {
patmandin@991
   536
				osmesa_format = OSMESA_BGRA;
patmandin@991
   537
			} else if (redmask == 255<<24) {
patmandin@991
   538
				osmesa_format = OSMESA_RGBA;
patmandin@991
   539
			} else {
patmandin@991
   540
				/* ABGR format unsupported */
patmandin@991
   541
				osmesa_format = OSMESA_BGRA;
patmandin@991
   542
				gl_convert = ConvertBGRAToABGR;
patmandin@991
   543
			}
patmandin@991
   544
			break;
patmandin@991
   545
		default:
patmandin@991
   546
			gl_pixelsize = 1;
patmandin@991
   547
			gl_copyshadow = CopyShadowDirect;
patmandin@991
   548
			osmesa_format = OSMESA_COLOR_INDEX;
patmandin@991
   549
			break;
patmandin@991
   550
	}
patmandin@991
   551
patmandin@992
   552
	/* Try to keep current context if possible */
patmandin@992
   553
	recreatecontext=1;
patmandin@992
   554
	if (gl_shadow &&
patmandin@992
   555
		(gl_curformat == osmesa_format) &&
patmandin@992
   556
		(gl_curwidth == current->w) &&
patmandin@992
   557
		(gl_curheight == current->h)) {
patmandin@992
   558
		recreatecontext = 0;
patmandin@992
   559
	}
patmandin@992
   560
	if (recreatecontext) {
patmandin@992
   561
		SDL_AtariGL_Quit(this, SDL_FALSE);
patmandin@992
   562
patmandin@992
   563
		gl_shadow = this->gl_data->OSMesaCreateLDG(
patmandin@992
   564
			osmesa_format, GL_UNSIGNED_BYTE, current->w, current->h
patmandin@992
   565
		);
patmandin@992
   566
patmandin@992
   567
		if (gl_shadow) {
patmandin@992
   568
			gl_curformat = osmesa_format;
patmandin@992
   569
			gl_curwidth = current->w;
patmandin@992
   570
			gl_curheight = current->h;
patmandin@992
   571
		} else {
patmandin@992
   572
			gl_curformat = 0;
patmandin@992
   573
			gl_curwidth = 0;
patmandin@992
   574
			gl_curheight = 0;
patmandin@992
   575
		}
patmandin@992
   576
	}
patmandin@991
   577
patmandin@991
   578
	return (gl_shadow != NULL);
patmandin@991
   579
}
patmandin@991
   580
patmandin@991
   581
/*--- Conversions routines from shadow buffer to the screen ---*/
patmandin@991
   582
patmandin@991
   583
static void CopyShadowNull(_THIS, SDL_Surface *surface)
patmandin@989
   584
{
patmandin@989
   585
}
patmandin@989
   586
patmandin@991
   587
static void CopyShadowDirect(_THIS, SDL_Surface *surface)
patmandin@991
   588
{
patmandin@991
   589
	int y, srcpitch, dstpitch;
patmandin@991
   590
	Uint8 *srcline, *dstline;
patmandin@991
   591
patmandin@991
   592
	srcline = gl_shadow;
patmandin@991
   593
	srcpitch = surface->w * gl_pixelsize;
patmandin@991
   594
	dstline = surface->pixels;
patmandin@991
   595
	dstpitch = surface->pitch;
patmandin@991
   596
patmandin@991
   597
	for (y=0; y<surface->h; y++) {
patmandin@991
   598
		memcpy(dstline, srcline, srcpitch);
patmandin@991
   599
patmandin@991
   600
		srcline += srcpitch;
patmandin@991
   601
		dstline += dstpitch;
patmandin@991
   602
	}
patmandin@991
   603
}
patmandin@991
   604
patmandin@991
   605
static void CopyShadow8888To555(_THIS, SDL_Surface *surface)
patmandin@991
   606
{
patmandin@991
   607
	int x,y, srcpitch, dstpitch;
patmandin@991
   608
	Uint16 *dstline, *dstcol;
patmandin@991
   609
	Uint32 *srcline, *srccol;
patmandin@991
   610
patmandin@991
   611
	srcline = (Uint32 *)gl_shadow;
patmandin@991
   612
	srcpitch = surface->w;
patmandin@991
   613
	dstline = surface->pixels;
patmandin@991
   614
	dstpitch = surface->pitch >>1;
patmandin@991
   615
patmandin@991
   616
	for (y=0; y<surface->h; y++) {
patmandin@991
   617
		srccol = srcline;
patmandin@991
   618
		dstcol = dstline;
patmandin@991
   619
		for (x=0; x<surface->w; x++) {
patmandin@991
   620
			Uint32 srccolor;
patmandin@991
   621
			Uint16 dstcolor;
patmandin@991
   622
			
patmandin@991
   623
			srccolor = *srccol++;
patmandin@991
   624
			dstcolor = (srccolor>>9) & (31<<10);
patmandin@991
   625
			dstcolor |= (srccolor>>6) & (31<<5);
patmandin@991
   626
			dstcolor |= (srccolor>>3) & 31;
patmandin@991
   627
			*dstcol++ = dstcolor;
patmandin@991
   628
		}
patmandin@991
   629
patmandin@991
   630
		srcline += srcpitch;
patmandin@991
   631
		dstline += dstpitch;
patmandin@991
   632
	}
patmandin@991
   633
}
patmandin@991
   634
patmandin@991
   635
static void CopyShadow8888To565(_THIS, SDL_Surface *surface)
patmandin@991
   636
{
patmandin@991
   637
	int x,y, srcpitch, dstpitch;
patmandin@991
   638
	Uint16 *dstline, *dstcol;
patmandin@991
   639
	Uint32 *srcline, *srccol;
patmandin@991
   640
patmandin@991
   641
	srcline = (Uint32 *)gl_shadow;
patmandin@991
   642
	srcpitch = surface->w;
patmandin@991
   643
	dstline = surface->pixels;
patmandin@991
   644
	dstpitch = surface->pitch >>1;
patmandin@991
   645
patmandin@991
   646
	for (y=0; y<surface->h; y++) {
patmandin@991
   647
		srccol = srcline;
patmandin@991
   648
		dstcol = dstline;
patmandin@991
   649
patmandin@991
   650
		for (x=0; x<surface->w; x++) {
patmandin@991
   651
			Uint32 srccolor;
patmandin@991
   652
			Uint16 dstcolor;
patmandin@991
   653
			
patmandin@991
   654
			srccolor = *srccol++;
patmandin@991
   655
			dstcolor = (srccolor>>8) & (31<<11);
patmandin@991
   656
			dstcolor |= (srccolor>>5) & (63<<5);
patmandin@991
   657
			dstcolor |= (srccolor>>3) & 31;
patmandin@991
   658
			*dstcol++ = dstcolor;
patmandin@991
   659
		}
patmandin@991
   660
patmandin@991
   661
		srcline += srcpitch;
patmandin@991
   662
		dstline += dstpitch;
patmandin@991
   663
	}
patmandin@991
   664
}
patmandin@991
   665
patmandin@991
   666
/*--- Conversions routines in the screen ---*/
patmandin@991
   667
patmandin@991
   668
static void ConvertNull(_THIS, SDL_Surface *surface)
patmandin@991
   669
{
patmandin@991
   670
}
patmandin@991
   671
patmandin@991
   672
static void Convert565To555be(_THIS, SDL_Surface *surface)
patmandin@989
   673
{
patmandin@989
   674
	int x,y, pitch;
patmandin@989
   675
	unsigned short *line, *pixel;
patmandin@989
   676
patmandin@989
   677
	line = surface->pixels;
patmandin@989
   678
	pitch = surface->pitch >> 1;
patmandin@989
   679
	for (y=0; y<surface->h; y++) {
patmandin@989
   680
		pixel = line;
patmandin@989
   681
		for (x=0; x<surface->w; x++) {
patmandin@989
   682
			unsigned short color = *pixel;
patmandin@989
   683
patmandin@989
   684
			*pixel++ = (color & 0x1f)|((color>>1) & 0xffe0);
patmandin@989
   685
		}
patmandin@989
   686
patmandin@989
   687
		line += pitch;
patmandin@989
   688
	}
patmandin@989
   689
}
patmandin@989
   690
patmandin@991
   691
static void Convert565To555le(_THIS, SDL_Surface *surface)
patmandin@989
   692
{
patmandin@989
   693
	int x,y, pitch;
patmandin@989
   694
	unsigned short *line, *pixel;
patmandin@989
   695
patmandin@989
   696
	line = surface->pixels;
patmandin@989
   697
	pitch = surface->pitch >>1;
patmandin@989
   698
	for (y=0; y<surface->h; y++) {
patmandin@989
   699
		pixel = line;
patmandin@989
   700
		for (x=0; x<surface->w; x++) {
patmandin@989
   701
			unsigned short color = *pixel;
patmandin@989
   702
patmandin@989
   703
			color = (color & 0x1f)|((color>>1) & 0xffe0);
patmandin@989
   704
			*pixel++ = SDL_Swap16(color);
patmandin@989
   705
		}
patmandin@989
   706
patmandin@989
   707
		line += pitch;
patmandin@989
   708
	}
patmandin@989
   709
}
patmandin@989
   710
patmandin@991
   711
static void Convert565le(_THIS, SDL_Surface *surface)
patmandin@989
   712
{
patmandin@989
   713
	int x,y, pitch;
patmandin@989
   714
	unsigned short *line, *pixel;
patmandin@989
   715
patmandin@989
   716
	line = surface->pixels;
patmandin@989
   717
	pitch = surface->pitch >>1;
patmandin@989
   718
	for (y=0; y<surface->h; y++) {
patmandin@989
   719
		pixel = line;
patmandin@989
   720
		for (x=0; x<surface->w; x++) {
patmandin@989
   721
			unsigned short color = *pixel;
patmandin@989
   722
patmandin@989
   723
			*pixel++ = SDL_Swap16(color);
patmandin@989
   724
		}
patmandin@989
   725
patmandin@989
   726
		line += pitch;
patmandin@989
   727
	}
patmandin@989
   728
}
patmandin@989
   729
patmandin@991
   730
static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface)
patmandin@989
   731
{
patmandin@989
   732
	int x,y, pitch;
patmandin@989
   733
	unsigned long *line, *pixel;
patmandin@989
   734
patmandin@989
   735
	line = surface->pixels;
patmandin@989
   736
	pitch = surface->pitch >>2;
patmandin@989
   737
	for (y=0; y<surface->h; y++) {
patmandin@989
   738
		pixel = line;
patmandin@989
   739
		for (x=0; x<surface->w; x++) {
patmandin@989
   740
			unsigned long color = *pixel;
patmandin@989
   741
patmandin@989
   742
			*pixel++ = (color<<24)|(color>>8);
patmandin@989
   743
		}
patmandin@989
   744
patmandin@989
   745
		line += pitch;
patmandin@989
   746
	}
patmandin@989
   747
}