src/video/ataricommon/SDL_atarigl.c
author Patrice Mandin
Sat, 27 Nov 2004 21:28:49 +0000
changeset 993 2662da16d668
parent 992 0324ce32b2d9
child 995 22fc5f45bbb7
permissions -rw-r--r--
Forgot to flush OpenGL buffer using glFinish
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@993
   159
	this->gl_data->glGetIntegerv = SDL_LoadFunction(handle, "glGetIntegerv");
patmandin@993
   160
	this->gl_data->glFinish = SDL_LoadFunction(handle, "glFinish");
patmandin@993
   161
patmandin@993
   162
	if ( (this->gl_data->glGetIntegerv == NULL) || 
patmandin@993
   163
	     (this->gl_data->glFinish == NULL)) {
patmandin@993
   164
		SDL_SetError("Could not retrieve OpenGL functions");
patmandin@993
   165
		SDL_UnloadObject(handle);
patmandin@993
   166
		/* Restore pointers to static library */
patmandin@993
   167
		SDL_AtariGL_InitPointers(this);
patmandin@993
   168
		return -1;
patmandin@993
   169
	}
patmandin@993
   170
patmandin@991
   171
	/* Load functions pointers (osmesa.ldg) */
patmandin@991
   172
	this->gl_data->OSMesaCreateContextExt = SDL_LoadFunction(handle, "OSMesaCreateContextExt");
patmandin@991
   173
	this->gl_data->OSMesaDestroyContext = SDL_LoadFunction(handle, "OSMesaDestroyContext");
patmandin@991
   174
	this->gl_data->OSMesaMakeCurrent = SDL_LoadFunction(handle, "OSMesaMakeCurrent");
patmandin@991
   175
	this->gl_data->OSMesaPixelStore = SDL_LoadFunction(handle, "OSMesaPixelStore");
patmandin@991
   176
	this->gl_data->OSMesaGetProcAddress = SDL_LoadFunction(handle, "OSMesaGetProcAddress");
patmandin@991
   177
patmandin@991
   178
	/* Load old functions pointers (mesa_gl.ldg, tiny_gl.ldg) */
patmandin@991
   179
	this->gl_data->OSMesaCreateLDG = SDL_LoadFunction(handle, "OSMesaCreateLDG");
patmandin@991
   180
	this->gl_data->OSMesaDestroyLDG = SDL_LoadFunction(handle, "OSMesaDestroyLDG");
patmandin@991
   181
patmandin@991
   182
	gl_oldmesa = 0;
patmandin@991
   183
patmandin@991
   184
	if ( (this->gl_data->OSMesaCreateContextExt == NULL) || 
patmandin@991
   185
	     (this->gl_data->OSMesaDestroyContext == NULL) ||
patmandin@991
   186
	     (this->gl_data->OSMesaMakeCurrent == NULL) ||
patmandin@991
   187
	     (this->gl_data->OSMesaPixelStore == NULL) ||
patmandin@991
   188
	     (this->gl_data->OSMesaGetProcAddress == NULL)) {
patmandin@991
   189
		/* Hum, maybe old library ? */
patmandin@991
   190
		if ( (this->gl_data->OSMesaCreateLDG == NULL) || 
patmandin@991
   191
		     (this->gl_data->OSMesaDestroyLDG == NULL)) {
patmandin@993
   192
			SDL_SetError("Could not retrieve OSMesa functions");
patmandin@993
   193
			SDL_UnloadObject(handle);
patmandin@993
   194
			/* Restore pointers to static library */
patmandin@993
   195
			SDL_AtariGL_InitPointers(this);
patmandin@991
   196
			return -1;
patmandin@991
   197
		} else {
patmandin@991
   198
			gl_oldmesa = 1;
patmandin@991
   199
		}
patmandin@991
   200
	}
patmandin@991
   201
patmandin@991
   202
	this->gl_config.dll_handle = handle;
patmandin@991
   203
	if ( path ) {
patmandin@991
   204
		strncpy(this->gl_config.driver_path, path,
patmandin@991
   205
			sizeof(this->gl_config.driver_path)-1);
patmandin@991
   206
	} else {
patmandin@991
   207
		strcpy(this->gl_config.driver_path, "");
patmandin@991
   208
	}
patmandin@991
   209
patmandin@991
   210
#endif
patmandin@989
   211
	this->gl_config.driver_loaded = 1;
patmandin@991
   212
patmandin@991
   213
	return 0;
patmandin@991
   214
#else
patmandin@991
   215
	return -1;
patmandin@989
   216
#endif
patmandin@989
   217
}
patmandin@989
   218
patmandin@989
   219
void *SDL_AtariGL_GetProcAddress(_THIS, const char *proc)
patmandin@989
   220
{
patmandin@989
   221
	void *func = NULL;
patmandin@989
   222
#ifdef HAVE_OPENGL
patmandin@991
   223
patmandin@991
   224
	if (this->gl_config.dll_handle) {
patmandin@991
   225
		func = SDL_LoadFunction(this->gl_config.dll_handle, (void *)proc);
patmandin@991
   226
	} else if (this->gl_data->OSMesaGetProcAddress) {
patmandin@991
   227
		func = this->gl_data->OSMesaGetProcAddress(proc);
patmandin@989
   228
	}
patmandin@991
   229
patmandin@989
   230
#endif
patmandin@989
   231
	return func;
patmandin@989
   232
}
patmandin@989
   233
patmandin@989
   234
int SDL_AtariGL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
patmandin@989
   235
{
patmandin@989
   236
#ifdef HAVE_OPENGL
patmandin@989
   237
	GLenum mesa_attrib;
patmandin@989
   238
	SDL_Surface *surface;
patmandin@989
   239
patmandin@991
   240
	if (this->gl_config.dll_handle) {
patmandin@991
   241
		if (this->gl_data->glGetIntegerv == NULL) {
patmandin@991
   242
			return -1;
patmandin@991
   243
		}
patmandin@991
   244
	}
patmandin@991
   245
patmandin@991
   246
	if (!gl_active) {
patmandin@989
   247
		return -1;
patmandin@989
   248
	}
patmandin@989
   249
patmandin@989
   250
	switch(attrib) {
patmandin@989
   251
		case SDL_GL_RED_SIZE:
patmandin@989
   252
			mesa_attrib = GL_RED_BITS;
patmandin@989
   253
			break;
patmandin@989
   254
		case SDL_GL_GREEN_SIZE:
patmandin@989
   255
			mesa_attrib = GL_GREEN_BITS;
patmandin@989
   256
			break;
patmandin@989
   257
		case SDL_GL_BLUE_SIZE:
patmandin@989
   258
			mesa_attrib = GL_BLUE_BITS;
patmandin@989
   259
			break;
patmandin@989
   260
		case SDL_GL_ALPHA_SIZE:
patmandin@989
   261
			mesa_attrib = GL_ALPHA_BITS;
patmandin@989
   262
			break;
patmandin@989
   263
		case SDL_GL_DOUBLEBUFFER:
patmandin@989
   264
			surface = this->screen;
patmandin@989
   265
			*value = ((surface->flags & SDL_DOUBLEBUF)==SDL_DOUBLEBUF);
patmandin@989
   266
			return 0;
patmandin@989
   267
		case SDL_GL_DEPTH_SIZE:
patmandin@989
   268
			mesa_attrib = GL_DEPTH_BITS;
patmandin@989
   269
			break;
patmandin@989
   270
		case SDL_GL_STENCIL_SIZE:
patmandin@989
   271
			mesa_attrib = GL_STENCIL_BITS;
patmandin@989
   272
			break;
patmandin@989
   273
		case SDL_GL_ACCUM_RED_SIZE:
patmandin@989
   274
			mesa_attrib = GL_ACCUM_RED_BITS;
patmandin@989
   275
			break;
patmandin@989
   276
		case SDL_GL_ACCUM_GREEN_SIZE:
patmandin@989
   277
			mesa_attrib = GL_ACCUM_GREEN_BITS;
patmandin@989
   278
			break;
patmandin@989
   279
		case SDL_GL_ACCUM_BLUE_SIZE:
patmandin@989
   280
			mesa_attrib = GL_ACCUM_BLUE_BITS;
patmandin@989
   281
			break;
patmandin@989
   282
		case SDL_GL_ACCUM_ALPHA_SIZE:
patmandin@989
   283
			mesa_attrib = GL_ACCUM_ALPHA_BITS;
patmandin@989
   284
			break;
patmandin@989
   285
		default :
patmandin@989
   286
			return -1;
patmandin@989
   287
	}
patmandin@989
   288
patmandin@991
   289
	this->gl_data->glGetIntegerv(mesa_attrib, value);
patmandin@989
   290
	return 0;
patmandin@989
   291
#else
patmandin@989
   292
	return -1;
patmandin@989
   293
#endif
patmandin@989
   294
}
patmandin@989
   295
patmandin@989
   296
int SDL_AtariGL_MakeCurrent(_THIS)
patmandin@989
   297
{
patmandin@989
   298
#ifdef HAVE_OPENGL
patmandin@989
   299
	SDL_Surface *surface;
patmandin@989
   300
	GLenum type;
patmandin@989
   301
patmandin@991
   302
	if (gl_oldmesa && gl_active) {
patmandin@991
   303
		return 0;
patmandin@991
   304
	}
patmandin@991
   305
patmandin@991
   306
	if (this->gl_config.dll_handle) {
patmandin@991
   307
		if ((this->gl_data->OSMesaMakeCurrent == NULL) ||
patmandin@991
   308
			(this->gl_data->OSMesaPixelStore == NULL)) {
patmandin@991
   309
			return -1;
patmandin@991
   310
		}
patmandin@991
   311
	}
patmandin@991
   312
patmandin@991
   313
	if (!gl_active) {
patmandin@989
   314
		SDL_SetError("Invalid OpenGL context");
patmandin@989
   315
		return -1;
patmandin@989
   316
	}
patmandin@989
   317
patmandin@989
   318
	surface = this->screen;
patmandin@989
   319
	
patmandin@989
   320
	if ((surface->format->BitsPerPixel == 15) || (surface->format->BitsPerPixel == 16)) {
patmandin@989
   321
		type = GL_UNSIGNED_SHORT_5_6_5;
patmandin@989
   322
	} else {
patmandin@989
   323
		type = GL_UNSIGNED_BYTE;
patmandin@989
   324
	}
patmandin@989
   325
patmandin@991
   326
	if (!(this->gl_data->OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w, surface->h))) {
patmandin@989
   327
		SDL_SetError("Can not make OpenGL context current");
patmandin@989
   328
		return -1;
patmandin@989
   329
	}
patmandin@989
   330
patmandin@989
   331
	/* OSMesa draws upside down */
patmandin@991
   332
	this->gl_data->OSMesaPixelStore(OSMESA_Y_UP, 0);
patmandin@989
   333
patmandin@989
   334
	return 0;
patmandin@989
   335
#else
patmandin@989
   336
	return -1;
patmandin@989
   337
#endif
patmandin@989
   338
}
patmandin@989
   339
patmandin@989
   340
void SDL_AtariGL_SwapBuffers(_THIS)
patmandin@989
   341
{
patmandin@989
   342
#ifdef HAVE_OPENGL
patmandin@991
   343
	if (gl_active) {
patmandin@993
   344
		if (this->gl_config.dll_handle) {
patmandin@993
   345
			if (this->gl_data->glFinish) {
patmandin@993
   346
				this->gl_data->glFinish();
patmandin@993
   347
			}
patmandin@993
   348
		} else {
patmandin@993
   349
			this->gl_data->glFinish();
patmandin@993
   350
		}
patmandin@991
   351
		gl_copyshadow(this, this->screen);
patmandin@991
   352
		gl_convert(this, this->screen);
patmandin@989
   353
	}
patmandin@991
   354
#endif
patmandin@991
   355
}
patmandin@989
   356
patmandin@991
   357
void SDL_AtariGL_InitPointers(_THIS)
patmandin@991
   358
{
patmandin@991
   359
#if defined(HAVE_OPENGL)
patmandin@991
   360
	this->gl_data->OSMesaCreateContextExt = OSMesaCreateContextExt;
patmandin@991
   361
	this->gl_data->OSMesaDestroyContext = OSMesaDestroyContext;
patmandin@991
   362
	this->gl_data->OSMesaMakeCurrent = OSMesaMakeCurrent;
patmandin@991
   363
	this->gl_data->OSMesaPixelStore = OSMesaPixelStore;
patmandin@991
   364
	this->gl_data->OSMesaGetProcAddress = OSMesaGetProcAddress;
patmandin@993
   365
patmandin@991
   366
	this->gl_data->glGetIntegerv = glGetIntegerv;
patmandin@993
   367
	this->gl_data->glFinish = glFinish;
patmandin@993
   368
patmandin@993
   369
	this->gl_data->OSMesaCreateLDG = NULL;
patmandin@993
   370
	this->gl_data->OSMesaDestroyLDG = NULL;
patmandin@989
   371
#endif
patmandin@989
   372
}
patmandin@989
   373
patmandin@989
   374
/*--- Private functions ---*/
patmandin@989
   375
patmandin@991
   376
static void SDL_AtariGL_UnloadLibrary(_THIS)
patmandin@991
   377
{
patmandin@991
   378
#if defined(HAVE_OPENGL)
patmandin@991
   379
	if (this->gl_config.dll_handle) {
patmandin@991
   380
		SDL_UnloadObject(this->gl_config.dll_handle);
patmandin@991
   381
		this->gl_config.dll_handle = NULL;
patmandin@991
   382
patmandin@991
   383
		/* Restore pointers to static library */
patmandin@993
   384
		SDL_AtariGL_InitPointers(this);
patmandin@991
   385
	}
patmandin@991
   386
#endif
patmandin@991
   387
}
patmandin@991
   388
patmandin@991
   389
/*--- Creation of an OpenGL context using new/old functions ---*/
patmandin@991
   390
patmandin@991
   391
static int InitNew(_THIS, SDL_Surface *current)
patmandin@991
   392
{
patmandin@991
   393
	GLenum osmesa_format;
patmandin@991
   394
	SDL_PixelFormat *pixel_format;
patmandin@991
   395
	Uint32	redmask;
patmandin@992
   396
	int recreatecontext;
patmandin@992
   397
	GLint newaccumsize;
patmandin@991
   398
patmandin@991
   399
	if (this->gl_config.dll_handle) {
patmandin@991
   400
		if (this->gl_data->OSMesaCreateContextExt == NULL) {
patmandin@991
   401
			return 0;
patmandin@991
   402
		}
patmandin@991
   403
	}
patmandin@991
   404
patmandin@991
   405
	/* Init OpenGL context using OSMesa */
patmandin@991
   406
	gl_convert = ConvertNull;
patmandin@991
   407
	gl_copyshadow = CopyShadowNull;
patmandin@991
   408
patmandin@991
   409
	pixel_format = current->format;
patmandin@991
   410
	redmask = pixel_format->Rmask;
patmandin@991
   411
	switch (pixel_format->BitsPerPixel) {
patmandin@991
   412
		case 15:
patmandin@991
   413
			/* 1555, big and little endian, unsupported */
patmandin@991
   414
			gl_pixelsize = 2;
patmandin@991
   415
			osmesa_format = OSMESA_RGB_565;
patmandin@991
   416
			if (redmask == 31<<10) {
patmandin@991
   417
				gl_convert = Convert565To555be;
patmandin@991
   418
			} else {
patmandin@991
   419
				gl_convert = Convert565To555le;
patmandin@991
   420
			}
patmandin@991
   421
			break;
patmandin@991
   422
		case 16:
patmandin@991
   423
			gl_pixelsize = 2;
patmandin@991
   424
			if (redmask == 31<<11) {
patmandin@991
   425
				osmesa_format = OSMESA_RGB_565;
patmandin@991
   426
			} else {
patmandin@991
   427
				/* 565, little endian, unsupported */
patmandin@991
   428
				osmesa_format = OSMESA_RGB_565;
patmandin@991
   429
				gl_convert = Convert565le;
patmandin@991
   430
			}
patmandin@991
   431
			break;
patmandin@991
   432
		case 24:
patmandin@991
   433
			gl_pixelsize = 3;
patmandin@991
   434
			if (redmask == 255<<16) {
patmandin@991
   435
				osmesa_format = OSMESA_RGB;
patmandin@991
   436
			} else {
patmandin@991
   437
				osmesa_format = OSMESA_BGR;
patmandin@991
   438
			}
patmandin@991
   439
			break;
patmandin@991
   440
		case 32:
patmandin@991
   441
			gl_pixelsize = 4;
patmandin@991
   442
			if (redmask == 255<<16) {
patmandin@991
   443
				osmesa_format = OSMESA_ARGB;
patmandin@991
   444
			} else if (redmask == 255<<8) {
patmandin@991
   445
				osmesa_format = OSMESA_BGRA;
patmandin@991
   446
			} else if (redmask == 255<<24) {
patmandin@991
   447
				osmesa_format = OSMESA_RGBA;
patmandin@991
   448
			} else {
patmandin@991
   449
				/* ABGR format unsupported */
patmandin@991
   450
				osmesa_format = OSMESA_BGRA;
patmandin@991
   451
				gl_convert = ConvertBGRAToABGR;
patmandin@991
   452
			}
patmandin@991
   453
			break;
patmandin@991
   454
		default:
patmandin@991
   455
			gl_pixelsize = 1;
patmandin@991
   456
			osmesa_format = OSMESA_COLOR_INDEX;
patmandin@991
   457
			break;
patmandin@991
   458
	}
patmandin@991
   459
patmandin@992
   460
	/* Try to keep current context if possible */
patmandin@992
   461
	newaccumsize =
patmandin@992
   462
		this->gl_config.accum_red_size +
patmandin@992
   463
		this->gl_config.accum_green_size +
patmandin@992
   464
		this->gl_config.accum_blue_size +
patmandin@992
   465
		this->gl_config.accum_alpha_size;
patmandin@992
   466
	recreatecontext=1;
patmandin@992
   467
	if (gl_ctx &&
patmandin@992
   468
		(gl_curformat == osmesa_format) &&
patmandin@992
   469
		(gl_curdepth == this->gl_config.depth_size) &&
patmandin@992
   470
		(gl_curstencil == this->gl_config.stencil_size) &&
patmandin@992
   471
		(gl_curaccum == newaccumsize)) {
patmandin@992
   472
		recreatecontext = 0;
patmandin@992
   473
	}
patmandin@992
   474
	if (recreatecontext) {
patmandin@992
   475
		SDL_AtariGL_Quit(this, SDL_FALSE);
patmandin@992
   476
patmandin@992
   477
		gl_ctx = this->gl_data->OSMesaCreateContextExt(
patmandin@992
   478
			osmesa_format, this->gl_config.depth_size,
patmandin@992
   479
			this->gl_config.stencil_size, newaccumsize, NULL );
patmandin@992
   480
patmandin@992
   481
		if (gl_ctx) {
patmandin@992
   482
			gl_curformat = osmesa_format;
patmandin@992
   483
			gl_curdepth = this->gl_config.depth_size;
patmandin@992
   484
			gl_curstencil = this->gl_config.stencil_size;
patmandin@992
   485
			gl_curaccum = newaccumsize;
patmandin@992
   486
		} else {
patmandin@992
   487
			gl_curformat = 0;
patmandin@992
   488
			gl_curdepth = 0;
patmandin@992
   489
			gl_curstencil = 0;
patmandin@992
   490
			gl_curaccum = 0;
patmandin@992
   491
		}
patmandin@992
   492
	}
patmandin@991
   493
patmandin@991
   494
	return (gl_ctx != NULL);
patmandin@991
   495
}
patmandin@991
   496
patmandin@991
   497
static int InitOld(_THIS, SDL_Surface *current)
patmandin@991
   498
{
patmandin@991
   499
	GLenum osmesa_format;
patmandin@991
   500
	SDL_PixelFormat *pixel_format;
patmandin@991
   501
	Uint32	redmask;
patmandin@992
   502
	int recreatecontext;
patmandin@991
   503
patmandin@991
   504
	if (this->gl_config.dll_handle) {
patmandin@991
   505
		if (this->gl_data->OSMesaCreateLDG == NULL) {
patmandin@991
   506
			return 0;
patmandin@991
   507
		}
patmandin@991
   508
	}
patmandin@991
   509
patmandin@991
   510
	/* Init OpenGL context using OSMesa */
patmandin@991
   511
	gl_convert = ConvertNull;
patmandin@991
   512
	gl_copyshadow = CopyShadowNull;
patmandin@991
   513
patmandin@991
   514
	pixel_format = current->format;
patmandin@991
   515
	redmask = pixel_format->Rmask;
patmandin@991
   516
	switch (pixel_format->BitsPerPixel) {
patmandin@991
   517
		case 15:
patmandin@991
   518
			/* 15 bits unsupported */
patmandin@991
   519
			gl_pixelsize = 2;
patmandin@991
   520
			osmesa_format = OSMESA_ARGB;
patmandin@991
   521
			if (redmask == 31<<10) {
patmandin@991
   522
				gl_copyshadow = CopyShadow8888To555;
patmandin@991
   523
			} else {
patmandin@991
   524
				gl_copyshadow = CopyShadow8888To565;
patmandin@991
   525
				gl_convert = Convert565To555le;
patmandin@991
   526
			}
patmandin@991
   527
			break;
patmandin@991
   528
		case 16:
patmandin@991
   529
			/* 16 bits unsupported */
patmandin@991
   530
			gl_pixelsize = 2;
patmandin@991
   531
			osmesa_format = OSMESA_ARGB;
patmandin@991
   532
			gl_copyshadow = CopyShadow8888To565;
patmandin@991
   533
			if (redmask != 31<<11) {
patmandin@991
   534
				/* 565, little endian, unsupported */
patmandin@991
   535
				gl_convert = Convert565le;
patmandin@991
   536
			}
patmandin@991
   537
			break;
patmandin@991
   538
		case 24:
patmandin@991
   539
			gl_pixelsize = 3;
patmandin@991
   540
			gl_copyshadow = CopyShadowDirect;
patmandin@991
   541
			if (redmask == 255<<16) {
patmandin@991
   542
				osmesa_format = OSMESA_RGB;
patmandin@991
   543
			} else {
patmandin@991
   544
				osmesa_format = OSMESA_BGR;
patmandin@991
   545
			}
patmandin@991
   546
			break;
patmandin@991
   547
		case 32:
patmandin@991
   548
			gl_pixelsize = 4;
patmandin@991
   549
			gl_copyshadow = CopyShadowDirect;
patmandin@991
   550
			if (redmask == 255<<16) {
patmandin@991
   551
				osmesa_format = OSMESA_ARGB;
patmandin@991
   552
			} else if (redmask == 255<<8) {
patmandin@991
   553
				osmesa_format = OSMESA_BGRA;
patmandin@991
   554
			} else if (redmask == 255<<24) {
patmandin@991
   555
				osmesa_format = OSMESA_RGBA;
patmandin@991
   556
			} else {
patmandin@991
   557
				/* ABGR format unsupported */
patmandin@991
   558
				osmesa_format = OSMESA_BGRA;
patmandin@991
   559
				gl_convert = ConvertBGRAToABGR;
patmandin@991
   560
			}
patmandin@991
   561
			break;
patmandin@991
   562
		default:
patmandin@991
   563
			gl_pixelsize = 1;
patmandin@991
   564
			gl_copyshadow = CopyShadowDirect;
patmandin@991
   565
			osmesa_format = OSMESA_COLOR_INDEX;
patmandin@991
   566
			break;
patmandin@991
   567
	}
patmandin@991
   568
patmandin@992
   569
	/* Try to keep current context if possible */
patmandin@992
   570
	recreatecontext=1;
patmandin@992
   571
	if (gl_shadow &&
patmandin@992
   572
		(gl_curformat == osmesa_format) &&
patmandin@992
   573
		(gl_curwidth == current->w) &&
patmandin@992
   574
		(gl_curheight == current->h)) {
patmandin@992
   575
		recreatecontext = 0;
patmandin@992
   576
	}
patmandin@992
   577
	if (recreatecontext) {
patmandin@992
   578
		SDL_AtariGL_Quit(this, SDL_FALSE);
patmandin@992
   579
patmandin@992
   580
		gl_shadow = this->gl_data->OSMesaCreateLDG(
patmandin@992
   581
			osmesa_format, GL_UNSIGNED_BYTE, current->w, current->h
patmandin@992
   582
		);
patmandin@992
   583
patmandin@992
   584
		if (gl_shadow) {
patmandin@992
   585
			gl_curformat = osmesa_format;
patmandin@992
   586
			gl_curwidth = current->w;
patmandin@992
   587
			gl_curheight = current->h;
patmandin@992
   588
		} else {
patmandin@992
   589
			gl_curformat = 0;
patmandin@992
   590
			gl_curwidth = 0;
patmandin@992
   591
			gl_curheight = 0;
patmandin@992
   592
		}
patmandin@992
   593
	}
patmandin@991
   594
patmandin@991
   595
	return (gl_shadow != NULL);
patmandin@991
   596
}
patmandin@991
   597
patmandin@991
   598
/*--- Conversions routines from shadow buffer to the screen ---*/
patmandin@991
   599
patmandin@991
   600
static void CopyShadowNull(_THIS, SDL_Surface *surface)
patmandin@989
   601
{
patmandin@989
   602
}
patmandin@989
   603
patmandin@991
   604
static void CopyShadowDirect(_THIS, SDL_Surface *surface)
patmandin@991
   605
{
patmandin@991
   606
	int y, srcpitch, dstpitch;
patmandin@991
   607
	Uint8 *srcline, *dstline;
patmandin@991
   608
patmandin@991
   609
	srcline = gl_shadow;
patmandin@991
   610
	srcpitch = surface->w * gl_pixelsize;
patmandin@991
   611
	dstline = surface->pixels;
patmandin@991
   612
	dstpitch = surface->pitch;
patmandin@991
   613
patmandin@991
   614
	for (y=0; y<surface->h; y++) {
patmandin@991
   615
		memcpy(dstline, srcline, srcpitch);
patmandin@991
   616
patmandin@991
   617
		srcline += srcpitch;
patmandin@991
   618
		dstline += dstpitch;
patmandin@991
   619
	}
patmandin@991
   620
}
patmandin@991
   621
patmandin@991
   622
static void CopyShadow8888To555(_THIS, SDL_Surface *surface)
patmandin@991
   623
{
patmandin@991
   624
	int x,y, srcpitch, dstpitch;
patmandin@991
   625
	Uint16 *dstline, *dstcol;
patmandin@991
   626
	Uint32 *srcline, *srccol;
patmandin@991
   627
patmandin@991
   628
	srcline = (Uint32 *)gl_shadow;
patmandin@991
   629
	srcpitch = surface->w;
patmandin@991
   630
	dstline = surface->pixels;
patmandin@991
   631
	dstpitch = surface->pitch >>1;
patmandin@991
   632
patmandin@991
   633
	for (y=0; y<surface->h; y++) {
patmandin@991
   634
		srccol = srcline;
patmandin@991
   635
		dstcol = dstline;
patmandin@991
   636
		for (x=0; x<surface->w; x++) {
patmandin@991
   637
			Uint32 srccolor;
patmandin@991
   638
			Uint16 dstcolor;
patmandin@991
   639
			
patmandin@991
   640
			srccolor = *srccol++;
patmandin@991
   641
			dstcolor = (srccolor>>9) & (31<<10);
patmandin@991
   642
			dstcolor |= (srccolor>>6) & (31<<5);
patmandin@991
   643
			dstcolor |= (srccolor>>3) & 31;
patmandin@991
   644
			*dstcol++ = dstcolor;
patmandin@991
   645
		}
patmandin@991
   646
patmandin@991
   647
		srcline += srcpitch;
patmandin@991
   648
		dstline += dstpitch;
patmandin@991
   649
	}
patmandin@991
   650
}
patmandin@991
   651
patmandin@991
   652
static void CopyShadow8888To565(_THIS, SDL_Surface *surface)
patmandin@991
   653
{
patmandin@991
   654
	int x,y, srcpitch, dstpitch;
patmandin@991
   655
	Uint16 *dstline, *dstcol;
patmandin@991
   656
	Uint32 *srcline, *srccol;
patmandin@991
   657
patmandin@991
   658
	srcline = (Uint32 *)gl_shadow;
patmandin@991
   659
	srcpitch = surface->w;
patmandin@991
   660
	dstline = surface->pixels;
patmandin@991
   661
	dstpitch = surface->pitch >>1;
patmandin@991
   662
patmandin@991
   663
	for (y=0; y<surface->h; y++) {
patmandin@991
   664
		srccol = srcline;
patmandin@991
   665
		dstcol = dstline;
patmandin@991
   666
patmandin@991
   667
		for (x=0; x<surface->w; x++) {
patmandin@991
   668
			Uint32 srccolor;
patmandin@991
   669
			Uint16 dstcolor;
patmandin@991
   670
			
patmandin@991
   671
			srccolor = *srccol++;
patmandin@991
   672
			dstcolor = (srccolor>>8) & (31<<11);
patmandin@991
   673
			dstcolor |= (srccolor>>5) & (63<<5);
patmandin@991
   674
			dstcolor |= (srccolor>>3) & 31;
patmandin@991
   675
			*dstcol++ = dstcolor;
patmandin@991
   676
		}
patmandin@991
   677
patmandin@991
   678
		srcline += srcpitch;
patmandin@991
   679
		dstline += dstpitch;
patmandin@991
   680
	}
patmandin@991
   681
}
patmandin@991
   682
patmandin@991
   683
/*--- Conversions routines in the screen ---*/
patmandin@991
   684
patmandin@991
   685
static void ConvertNull(_THIS, SDL_Surface *surface)
patmandin@991
   686
{
patmandin@991
   687
}
patmandin@991
   688
patmandin@991
   689
static void Convert565To555be(_THIS, SDL_Surface *surface)
patmandin@989
   690
{
patmandin@989
   691
	int x,y, pitch;
patmandin@989
   692
	unsigned short *line, *pixel;
patmandin@989
   693
patmandin@989
   694
	line = surface->pixels;
patmandin@989
   695
	pitch = surface->pitch >> 1;
patmandin@989
   696
	for (y=0; y<surface->h; y++) {
patmandin@989
   697
		pixel = line;
patmandin@989
   698
		for (x=0; x<surface->w; x++) {
patmandin@989
   699
			unsigned short color = *pixel;
patmandin@989
   700
patmandin@989
   701
			*pixel++ = (color & 0x1f)|((color>>1) & 0xffe0);
patmandin@989
   702
		}
patmandin@989
   703
patmandin@989
   704
		line += pitch;
patmandin@989
   705
	}
patmandin@989
   706
}
patmandin@989
   707
patmandin@991
   708
static void Convert565To555le(_THIS, SDL_Surface *surface)
patmandin@989
   709
{
patmandin@989
   710
	int x,y, pitch;
patmandin@989
   711
	unsigned short *line, *pixel;
patmandin@989
   712
patmandin@989
   713
	line = surface->pixels;
patmandin@989
   714
	pitch = surface->pitch >>1;
patmandin@989
   715
	for (y=0; y<surface->h; y++) {
patmandin@989
   716
		pixel = line;
patmandin@989
   717
		for (x=0; x<surface->w; x++) {
patmandin@989
   718
			unsigned short color = *pixel;
patmandin@989
   719
patmandin@989
   720
			color = (color & 0x1f)|((color>>1) & 0xffe0);
patmandin@989
   721
			*pixel++ = SDL_Swap16(color);
patmandin@989
   722
		}
patmandin@989
   723
patmandin@989
   724
		line += pitch;
patmandin@989
   725
	}
patmandin@989
   726
}
patmandin@989
   727
patmandin@991
   728
static void Convert565le(_THIS, SDL_Surface *surface)
patmandin@989
   729
{
patmandin@989
   730
	int x,y, pitch;
patmandin@989
   731
	unsigned short *line, *pixel;
patmandin@989
   732
patmandin@989
   733
	line = surface->pixels;
patmandin@989
   734
	pitch = surface->pitch >>1;
patmandin@989
   735
	for (y=0; y<surface->h; y++) {
patmandin@989
   736
		pixel = line;
patmandin@989
   737
		for (x=0; x<surface->w; x++) {
patmandin@989
   738
			unsigned short color = *pixel;
patmandin@989
   739
patmandin@989
   740
			*pixel++ = SDL_Swap16(color);
patmandin@989
   741
		}
patmandin@989
   742
patmandin@989
   743
		line += pitch;
patmandin@989
   744
	}
patmandin@989
   745
}
patmandin@989
   746
patmandin@991
   747
static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface)
patmandin@989
   748
{
patmandin@989
   749
	int x,y, pitch;
patmandin@989
   750
	unsigned long *line, *pixel;
patmandin@989
   751
patmandin@989
   752
	line = surface->pixels;
patmandin@989
   753
	pitch = surface->pitch >>2;
patmandin@989
   754
	for (y=0; y<surface->h; y++) {
patmandin@989
   755
		pixel = line;
patmandin@989
   756
		for (x=0; x<surface->w; x++) {
patmandin@989
   757
			unsigned long color = *pixel;
patmandin@989
   758
patmandin@989
   759
			*pixel++ = (color<<24)|(color>>8);
patmandin@989
   760
		}
patmandin@989
   761
patmandin@989
   762
		line += pitch;
patmandin@989
   763
	}
patmandin@989
   764
}