src/video/ataricommon/SDL_atarigl.c
author Edgar Simo <bobbens@gmail.com>
Sun, 06 Jul 2008 17:06:37 +0000
branchgsoc2008_force_feedback
changeset 2498 ab567bd667bf
parent 2043 adf732f1f016
child 2698 e1da92da346c
permissions -rw-r--r--
Fixed various mistakes in the doxygen.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2004 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 /* Atari OSMesa.ldg implementation of SDL OpenGL support */
    25 
    26 /*--- Includes ---*/
    27 
    28 #if SDL_VIDEO_OPENGL
    29 #include <GL/osmesa.h>
    30 #endif
    31 
    32 #include <mint/osbind.h>
    33 
    34 #include "SDL_endian.h"
    35 #include "SDL_video.h"
    36 #include "SDL_atarigl_c.h"
    37 #if SDL_VIDEO_OPENGL_OSMESA_DYNAMIC
    38 #include "SDL_loadso.h"
    39 #endif
    40 
    41 /*--- Defines ---*/
    42 
    43 #define PATH_OSMESA_LDG	"osmesa.ldg"
    44 #define PATH_MESAGL_LDG	"mesa_gl.ldg"
    45 #define PATH_TINYGL_LDG	"tiny_gl.ldg"
    46 
    47 #define VDI_RGB	0xf
    48 
    49 /*--- Functions prototypes ---*/
    50 
    51 static void SDL_AtariGL_UnloadLibrary(_THIS);
    52 
    53 #if SDL_VIDEO_OPENGL
    54 static void CopyShadowNull(_THIS, SDL_Surface * surface);
    55 static void CopyShadowDirect(_THIS, SDL_Surface * surface);
    56 static void CopyShadowRGBTo555(_THIS, SDL_Surface * surface);
    57 static void CopyShadowRGBTo565(_THIS, SDL_Surface * surface);
    58 static void CopyShadowRGBSwap(_THIS, SDL_Surface * surface);
    59 static void CopyShadowRGBToARGB(_THIS, SDL_Surface * surface);
    60 static void CopyShadowRGBToABGR(_THIS, SDL_Surface * surface);
    61 static void CopyShadowRGBToBGRA(_THIS, SDL_Surface * surface);
    62 static void CopyShadowRGBToRGBA(_THIS, SDL_Surface * surface);
    63 static void CopyShadow8888To555(_THIS, SDL_Surface * surface);
    64 static void CopyShadow8888To565(_THIS, SDL_Surface * surface);
    65 
    66 static void ConvertNull(_THIS, SDL_Surface * surface);
    67 static void Convert565To555be(_THIS, SDL_Surface * surface);
    68 static void Convert565To555le(_THIS, SDL_Surface * surface);
    69 static void Convert565le(_THIS, SDL_Surface * surface);
    70 static void ConvertBGRAToABGR(_THIS, SDL_Surface * surface);
    71 
    72 static int InitNew(_THIS, SDL_Surface * current);
    73 static int InitOld(_THIS, SDL_Surface * current);
    74 #endif
    75 
    76 /*--- Public functions ---*/
    77 
    78 int
    79 SDL_AtariGL_Init(_THIS, SDL_Surface * current)
    80 {
    81 #if SDL_VIDEO_OPENGL
    82     if (gl_oldmesa) {
    83         gl_active = InitOld(_this, current);
    84     } else {
    85         gl_active = InitNew(_this, current);
    86     }
    87 #endif
    88 
    89     return (gl_active);
    90 }
    91 
    92 void
    93 SDL_AtariGL_Quit(_THIS, SDL_bool unload)
    94 {
    95 #if SDL_VIDEO_OPENGL
    96     if (gl_oldmesa) {
    97         /* Old mesa implementations */
    98         if (_this->gl_data->OSMesaDestroyLDG) {
    99             _this->gl_data->OSMesaDestroyLDG();
   100         }
   101         if (gl_shadow) {
   102             Mfree(gl_shadow);
   103             gl_shadow = NULL;
   104         }
   105     } else {
   106         /* New mesa implementation */
   107         if (gl_ctx) {
   108             if (_this->gl_data->OSMesaDestroyContext) {
   109                 _this->gl_data->OSMesaDestroyContext(gl_ctx);
   110             }
   111             gl_ctx = NULL;
   112         }
   113     }
   114 
   115     if (unload) {
   116         SDL_AtariGL_UnloadLibrary(_this);
   117     }
   118 #endif /* SDL_VIDEO_OPENGL */
   119     gl_active = 0;
   120 }
   121 
   122 int
   123 SDL_AtariGL_LoadLibrary(_THIS, const char *path)
   124 {
   125 #if SDL_VIDEO_OPENGL
   126 
   127 #if SDL_VIDEO_OPENGL_OSMESA_DYNAMIC
   128     void *handle;
   129     SDL_bool cancel_load;
   130 
   131     if (gl_active) {
   132         SDL_SetError("OpenGL context already created");
   133         return -1;
   134     }
   135 
   136     /* Unload previous driver */
   137     SDL_AtariGL_UnloadLibrary(_this);
   138 
   139     /* Load library given by path */
   140     handle = SDL_LoadObject(path);
   141     if (handle == NULL) {
   142         /* Try to load another one */
   143         path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
   144         if (path != NULL) {
   145             handle = SDL_LoadObject(path);
   146         }
   147 
   148         /* If it does not work, try some other */
   149         if (handle == NULL) {
   150             path = PATH_OSMESA_LDG;
   151             handle = SDL_LoadObject(path);
   152         }
   153 
   154         if (handle == NULL) {
   155             path = PATH_MESAGL_LDG;
   156             handle = SDL_LoadObject(path);
   157         }
   158 
   159         if (handle == NULL) {
   160             path = PATH_TINYGL_LDG;
   161             handle = SDL_LoadObject(path);
   162         }
   163     }
   164 
   165     if (handle == NULL) {
   166         SDL_SetError("Could not load OpenGL library");
   167         return -1;
   168     }
   169 
   170     _this->gl_data->glGetIntegerv = SDL_LoadFunction(handle, "glGetIntegerv");
   171     _this->gl_data->glFinish = SDL_LoadFunction(handle, "glFinish");
   172     _this->gl_data->glFlush = SDL_LoadFunction(handle, "glFlush");
   173 
   174     cancel_load = SDL_FALSE;
   175     if (_this->gl_data->glGetIntegerv == NULL) {
   176         cancel_load = SDL_TRUE;
   177     } else {
   178         /* We need either glFinish (OSMesa) or glFlush (TinyGL) */
   179         if ((_this->gl_data->glFinish == NULL) &&
   180             (_this->gl_data->glFlush == NULL)) {
   181             cancel_load = SDL_TRUE;
   182         }
   183     }
   184     if (cancel_load) {
   185         SDL_SetError("Could not retrieve OpenGL functions");
   186         SDL_UnloadObject(handle);
   187         /* Restore pointers to static library */
   188         SDL_AtariGL_InitPointers(this);
   189         return -1;
   190     }
   191 
   192     /* Load functions pointers (osmesa.ldg) */
   193     _this->gl_data->OSMesaCreateContextExt =
   194         SDL_LoadFunction(handle, "OSMesaCreateContextExt");
   195     _this->gl_data->OSMesaDestroyContext =
   196         SDL_LoadFunction(handle, "OSMesaDestroyContext");
   197     _this->gl_data->OSMesaMakeCurrent =
   198         SDL_LoadFunction(handle, "OSMesaMakeCurrent");
   199     _this->gl_data->OSMesaPixelStore =
   200         SDL_LoadFunction(handle, "OSMesaPixelStore");
   201     _this->gl_data->OSMesaGetProcAddress =
   202         SDL_LoadFunction(handle, "OSMesaGetProcAddress");
   203 
   204     /* Load old functions pointers (mesa_gl.ldg, tiny_gl.ldg) */
   205     _this->gl_data->OSMesaCreateLDG =
   206         SDL_LoadFunction(handle, "OSMesaCreateLDG");
   207     _this->gl_data->OSMesaDestroyLDG =
   208         SDL_LoadFunction(handle, "OSMesaDestroyLDG");
   209 
   210     gl_oldmesa = 0;
   211 
   212     if ((_this->gl_data->OSMesaCreateContextExt == NULL) ||
   213         (_this->gl_data->OSMesaDestroyContext == NULL) ||
   214         (_this->gl_data->OSMesaMakeCurrent == NULL) ||
   215         (_this->gl_data->OSMesaPixelStore == NULL) ||
   216         (_this->gl_data->OSMesaGetProcAddress == NULL)) {
   217         /* Hum, maybe old library ? */
   218         if ((_this->gl_data->OSMesaCreateLDG == NULL) ||
   219             (_this->gl_data->OSMesaDestroyLDG == NULL)) {
   220             SDL_SetError("Could not retrieve OSMesa functions");
   221             SDL_UnloadObject(handle);
   222             /* Restore pointers to static library */
   223             SDL_AtariGL_InitPointers(_this);
   224             return -1;
   225         } else {
   226             gl_oldmesa = 1;
   227         }
   228     }
   229 
   230     _this->gl_config.dll_handle = handle;
   231     if (path) {
   232         SDL_strlcpy(_this->gl_config.driver_path, path,
   233                     SDL_arraysize(_this->gl_config.driver_path));
   234     } else {
   235         *this->gl_config.driver_path = '\0';
   236     }
   237 
   238 #endif
   239     _this->gl_config.driver_loaded = 1;
   240 
   241     return 0;
   242 #else
   243     return -1;
   244 #endif
   245 }
   246 
   247 void *
   248 SDL_AtariGL_GetProcAddress(_THIS, const char *proc)
   249 {
   250     void *func = NULL;
   251 #if SDL_VIDEO_OPENGL
   252 
   253     if (_this->gl_config.dll_handle) {
   254         func = SDL_LoadFunction(this->gl_config.dll_handle, (void *) proc);
   255     } else if (_this->gl_data->OSMesaGetProcAddress) {
   256         func = _this->gl_data->OSMesaGetProcAddress(proc);
   257     }
   258 #endif
   259     return func;
   260 }
   261 
   262 int
   263 SDL_AtariGL_GetAttribute(_THIS, SDL_GLattr attrib, int *value)
   264 {
   265 #if SDL_VIDEO_OPENGL
   266     GLenum mesa_attrib;
   267     SDL_Surface *surface;
   268 
   269     if (!gl_active) {
   270         return -1;
   271     }
   272 
   273     switch (attrib) {
   274     case SDL_GL_RED_SIZE:
   275         mesa_attrib = GL_RED_BITS;
   276         break;
   277     case SDL_GL_GREEN_SIZE:
   278         mesa_attrib = GL_GREEN_BITS;
   279         break;
   280     case SDL_GL_BLUE_SIZE:
   281         mesa_attrib = GL_BLUE_BITS;
   282         break;
   283     case SDL_GL_ALPHA_SIZE:
   284         mesa_attrib = GL_ALPHA_BITS;
   285         break;
   286     case SDL_GL_DOUBLEBUFFER:
   287         surface = _this->screen;
   288         *value = ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF);
   289         return 0;
   290     case SDL_GL_DEPTH_SIZE:
   291         mesa_attrib = GL_DEPTH_BITS;
   292         break;
   293     case SDL_GL_STENCIL_SIZE:
   294         mesa_attrib = GL_STENCIL_BITS;
   295         break;
   296     case SDL_GL_ACCUM_RED_SIZE:
   297         mesa_attrib = GL_ACCUM_RED_BITS;
   298         break;
   299     case SDL_GL_ACCUM_GREEN_SIZE:
   300         mesa_attrib = GL_ACCUM_GREEN_BITS;
   301         break;
   302     case SDL_GL_ACCUM_BLUE_SIZE:
   303         mesa_attrib = GL_ACCUM_BLUE_BITS;
   304         break;
   305     case SDL_GL_ACCUM_ALPHA_SIZE:
   306         mesa_attrib = GL_ACCUM_ALPHA_BITS;
   307         break;
   308     default:
   309         return -1;
   310     }
   311 
   312     _this->gl_data->glGetIntegerv(mesa_attrib, value);
   313     return 0;
   314 #else
   315     return -1;
   316 #endif
   317 }
   318 
   319 int
   320 SDL_AtariGL_MakeCurrent(_THIS)
   321 {
   322 #if SDL_VIDEO_OPENGL
   323     SDL_Surface *surface;
   324     GLenum type;
   325 
   326     if (gl_oldmesa && gl_active) {
   327         return 0;
   328     }
   329 
   330     if (_this->gl_config.dll_handle) {
   331         if ((_this->gl_data->OSMesaMakeCurrent == NULL) ||
   332             (_this->gl_data->OSMesaPixelStore == NULL)) {
   333             return -1;
   334         }
   335     }
   336 
   337     if (!gl_active) {
   338         SDL_SetError("Invalid OpenGL context");
   339         return -1;
   340     }
   341 
   342     surface = _this->screen;
   343 
   344     if ((surface->format->BitsPerPixel == 15)
   345         || (surface->format->BitsPerPixel == 16)) {
   346         type = GL_UNSIGNED_SHORT_5_6_5;
   347     } else {
   348         type = GL_UNSIGNED_BYTE;
   349     }
   350 
   351     if (!
   352         (_this->gl_data->
   353          OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w,
   354                            surface->h))) {
   355         SDL_SetError("Can not make OpenGL context current");
   356         return -1;
   357     }
   358 
   359     /* OSMesa draws upside down */
   360     _this->gl_data->OSMesaPixelStore(OSMESA_Y_UP, 0);
   361 
   362     return 0;
   363 #else
   364     return -1;
   365 #endif
   366 }
   367 
   368 void
   369 SDL_AtariGL_SwapBuffers(_THIS)
   370 {
   371 #if SDL_VIDEO_OPENGL
   372     if (gl_active) {
   373         if (_this->gl_config.dll_handle) {
   374             if (_this->gl_data->glFinish) {
   375                 _this->gl_data->glFinish();
   376             } else if (_this->gl_data->glFlush) {
   377                 _this->gl_data->glFlush();
   378             }
   379         } else {
   380             _this->gl_data->glFinish();
   381         }
   382         gl_copyshadow(_this, _this->screen);
   383         gl_convert(_this, _this->screen);
   384     }
   385 #endif
   386 }
   387 
   388 void
   389 SDL_AtariGL_InitPointers(_THIS)
   390 {
   391 #if SDL_VIDEO_OPENGL
   392     _this->gl_data->OSMesaCreateContextExt = OSMesaCreateContextExt;
   393     _this->gl_data->OSMesaDestroyContext = OSMesaDestroyContext;
   394     _this->gl_data->OSMesaMakeCurrent = OSMesaMakeCurrent;
   395     _this->gl_data->OSMesaPixelStore = OSMesaPixelStore;
   396     _this->gl_data->OSMesaGetProcAddress = OSMesaGetProcAddress;
   397 
   398     _this->gl_data->glGetIntegerv = glGetIntegerv;
   399     _this->gl_data->glFinish = glFinish;
   400     _this->gl_data->glFlush = glFlush;
   401 
   402     _this->gl_data->OSMesaCreateLDG = NULL;
   403     _this->gl_data->OSMesaDestroyLDG = NULL;
   404 #endif
   405 }
   406 
   407 /*--- Private functions ---*/
   408 
   409 static void
   410 SDL_AtariGL_UnloadLibrary(_THIS)
   411 {
   412 #if SDL_VIDEO_OPENGL
   413     if (_this->gl_config.dll_handle) {
   414         SDL_UnloadObject(_this->gl_config.dll_handle);
   415         _this->gl_config.dll_handle = NULL;
   416 
   417         /* Restore pointers to static library */
   418         SDL_AtariGL_InitPointers(_this);
   419     }
   420 #endif
   421 }
   422 
   423 /*--- Creation of an OpenGL context using new/old functions ---*/
   424 
   425 #if SDL_VIDEO_OPENGL
   426 static int
   427 InitNew(_THIS, SDL_Surface * current)
   428 {
   429     GLenum osmesa_format;
   430     SDL_PixelFormat *pixel_format;
   431     Uint32 redmask;
   432     int recreatecontext;
   433     GLint newaccumsize;
   434 
   435     if (_this->gl_config.dll_handle) {
   436         if (_this->gl_data->OSMesaCreateContextExt == NULL) {
   437             return 0;
   438         }
   439     }
   440 
   441     /* Init OpenGL context using OSMesa */
   442     gl_convert = ConvertNull;
   443     gl_copyshadow = CopyShadowNull;
   444     gl_upsidedown = SDL_FALSE;
   445 
   446     pixel_format = current->format;
   447     redmask = pixel_format->Rmask;
   448     switch (pixel_format->BitsPerPixel) {
   449     case 15:
   450         /* 1555, big and little endian, unsupported */
   451         gl_pixelsize = 2;
   452         osmesa_format = OSMESA_RGB_565;
   453         if (redmask == 31 << 10) {
   454             gl_convert = Convert565To555be;
   455         } else {
   456             gl_convert = Convert565To555le;
   457         }
   458         break;
   459     case 16:
   460         gl_pixelsize = 2;
   461         if (redmask == 31 << 11) {
   462             osmesa_format = OSMESA_RGB_565;
   463         } else {
   464             /* 565, little endian, unsupported */
   465             osmesa_format = OSMESA_RGB_565;
   466             gl_convert = Convert565le;
   467         }
   468         break;
   469     case 24:
   470         gl_pixelsize = 3;
   471         if (redmask == 255 << 16) {
   472             osmesa_format = OSMESA_RGB;
   473         } else {
   474             osmesa_format = OSMESA_BGR;
   475         }
   476         break;
   477     case 32:
   478         gl_pixelsize = 4;
   479         if (redmask == 255 << 16) {
   480             osmesa_format = OSMESA_ARGB;
   481         } else if (redmask == 255 << 8) {
   482             osmesa_format = OSMESA_BGRA;
   483         } else if (redmask == 255 << 24) {
   484             osmesa_format = OSMESA_RGBA;
   485         } else {
   486             /* ABGR format unsupported */
   487             osmesa_format = OSMESA_BGRA;
   488             gl_convert = ConvertBGRAToABGR;
   489         }
   490         break;
   491     default:
   492         gl_pixelsize = 1;
   493         osmesa_format = OSMESA_COLOR_INDEX;
   494         break;
   495     }
   496 
   497     /* Try to keep current context if possible */
   498     newaccumsize =
   499         _this->gl_config.accum_red_size +
   500         _this->gl_config.accum_green_size +
   501         _this->gl_config.accum_blue_size + _this->gl_config.accum_alpha_size;
   502     recreatecontext = 1;
   503     if (gl_ctx &&
   504         (gl_curformat == osmesa_format) &&
   505         (gl_curdepth == _this->gl_config.depth_size) &&
   506         (gl_curstencil == _this->gl_config.stencil_size) &&
   507         (gl_curaccum == newaccumsize)) {
   508         recreatecontext = 0;
   509     }
   510     if (recreatecontext) {
   511         SDL_AtariGL_Quit(this, SDL_FALSE);
   512 
   513         gl_ctx =
   514             _this->gl_data->OSMesaCreateContextExt(osmesa_format,
   515                                                    _this->gl_config.
   516                                                    depth_size,
   517                                                    _this->gl_config.
   518                                                    stencil_size,
   519                                                    newaccumsize, NULL);
   520 
   521         if (gl_ctx) {
   522             gl_curformat = osmesa_format;
   523             gl_curdepth = _this->gl_config.depth_size;
   524             gl_curstencil = _this->gl_config.stencil_size;
   525             gl_curaccum = newaccumsize;
   526         } else {
   527             gl_curformat = 0;
   528             gl_curdepth = 0;
   529             gl_curstencil = 0;
   530             gl_curaccum = 0;
   531         }
   532     }
   533 
   534     return (gl_ctx != NULL);
   535 }
   536 
   537 
   538 static int
   539 InitOld(_THIS, SDL_Surface * current)
   540 {
   541     GLenum osmesa_format;
   542     SDL_PixelFormat *pixel_format;
   543     Uint32 redmask;
   544     int recreatecontext, tinygl_present;
   545 
   546     if (_this->gl_config.dll_handle) {
   547         if (_this->gl_data->OSMesaCreateLDG == NULL) {
   548             return 0;
   549         }
   550     }
   551 
   552     /* TinyGL only supports VDI_RGB (OSMESA_RGB) */
   553     tinygl_present = 0;
   554     if (_this->gl_config.dll_handle) {
   555         if (_this->gl_data->glFinish == NULL) {
   556             tinygl_present = 1;
   557         }
   558     }
   559 
   560     /* Init OpenGL context using OSMesa */
   561     gl_convert = ConvertNull;
   562     gl_copyshadow = CopyShadowNull;
   563     gl_upsidedown = SDL_FALSE;
   564 
   565     pixel_format = current->format;
   566     redmask = pixel_format->Rmask;
   567     switch (pixel_format->BitsPerPixel) {
   568     case 15:
   569         /* 15 bits unsupported */
   570         if (tinygl_present) {
   571             gl_pixelsize = 3;
   572             osmesa_format = VDI_RGB;
   573             if (redmask == 31 << 10) {
   574                 gl_copyshadow = CopyShadowRGBTo555;
   575             } else {
   576                 gl_copyshadow = CopyShadowRGBTo565;
   577                 gl_convert = Convert565To555le;
   578             }
   579         } else {
   580             gl_pixelsize = 4;
   581             gl_upsidedown = SDL_TRUE;
   582             osmesa_format = OSMESA_ARGB;
   583             if (redmask == 31 << 10) {
   584                 gl_copyshadow = CopyShadow8888To555;
   585             } else {
   586                 gl_copyshadow = CopyShadow8888To565;
   587                 gl_convert = Convert565To555le;
   588             }
   589         }
   590         break;
   591     case 16:
   592         /* 16 bits unsupported */
   593         if (tinygl_present) {
   594             gl_pixelsize = 3;
   595             osmesa_format = VDI_RGB;
   596             gl_copyshadow = CopyShadowRGBTo565;
   597             if (redmask != 31 << 11) {
   598                 /* 565, little endian, unsupported */
   599                 gl_convert = Convert565le;
   600             }
   601         } else {
   602             gl_pixelsize = 4;
   603             gl_upsidedown = SDL_TRUE;
   604             osmesa_format = OSMESA_ARGB;
   605             gl_copyshadow = CopyShadow8888To565;
   606             if (redmask != 31 << 11) {
   607                 /* 565, little endian, unsupported */
   608                 gl_convert = Convert565le;
   609             }
   610         }
   611         break;
   612     case 24:
   613         gl_pixelsize = 3;
   614         if (tinygl_present) {
   615             osmesa_format = VDI_RGB;
   616             gl_copyshadow = CopyShadowDirect;
   617             if (redmask != 255 << 16) {
   618                 gl_copyshadow = CopyShadowRGBSwap;
   619             }
   620         } else {
   621             gl_copyshadow = CopyShadowDirect;
   622             gl_upsidedown = SDL_TRUE;
   623             if (redmask == 255 << 16) {
   624                 osmesa_format = OSMESA_RGB;
   625             } else {
   626                 osmesa_format = OSMESA_BGR;
   627             }
   628         }
   629         break;
   630     case 32:
   631         if (tinygl_present) {
   632             gl_pixelsize = 3;
   633             osmesa_format = VDI_RGB;
   634             gl_copyshadow = CopyShadowRGBToARGB;
   635             if (redmask == 255) {
   636                 gl_convert = CopyShadowRGBToABGR;
   637             } else if (redmask == 255 << 8) {
   638                 gl_convert = CopyShadowRGBToBGRA;
   639             } else if (redmask == 255 << 24) {
   640                 gl_convert = CopyShadowRGBToRGBA;
   641             }
   642         } else {
   643             gl_pixelsize = 4;
   644             gl_upsidedown = SDL_TRUE;
   645             gl_copyshadow = CopyShadowDirect;
   646             if (redmask == 255 << 16) {
   647                 osmesa_format = OSMESA_ARGB;
   648             } else if (redmask == 255 << 8) {
   649                 osmesa_format = OSMESA_BGRA;
   650             } else if (redmask == 255 << 24) {
   651                 osmesa_format = OSMESA_RGBA;
   652             } else {
   653                 /* ABGR format unsupported */
   654                 osmesa_format = OSMESA_BGRA;
   655                 gl_convert = ConvertBGRAToABGR;
   656             }
   657         }
   658         break;
   659     default:
   660         if (tinygl_present) {
   661             SDL_AtariGL_Quit(_this, SDL_FALSE);
   662             return 0;
   663         }
   664         gl_pixelsize = 1;
   665         gl_copyshadow = CopyShadowDirect;
   666         osmesa_format = OSMESA_COLOR_INDEX;
   667         break;
   668     }
   669 
   670     /* Try to keep current context if possible */
   671     recreatecontext = 1;
   672     if (gl_shadow &&
   673         (gl_curformat == osmesa_format) &&
   674         (gl_curwidth == current->w) && (gl_curheight == current->h)) {
   675         recreatecontext = 0;
   676     }
   677     if (recreatecontext) {
   678         SDL_AtariGL_Quit(_this, SDL_FALSE);
   679 
   680         gl_shadow =
   681             _this->gl_data->OSMesaCreateLDG(osmesa_format, GL_UNSIGNED_BYTE,
   682                                             current->w, current->h);
   683 
   684         if (gl_shadow) {
   685             gl_curformat = osmesa_format;
   686             gl_curwidth = current->w;
   687             gl_curheight = current->h;
   688         } else {
   689             gl_curformat = 0;
   690             gl_curwidth = 0;
   691             gl_curheight = 0;
   692         }
   693     }
   694 
   695     return (gl_shadow != NULL);
   696 }
   697 
   698 /*--- Conversions routines from shadow buffer to the screen ---*/
   699 
   700 static void
   701 CopyShadowNull(_THIS, SDL_Surface * surface)
   702 {
   703 }
   704 
   705 static void
   706 CopyShadowDirect(_THIS, SDL_Surface * surface)
   707 {
   708     int y, srcpitch, dstpitch;
   709     Uint8 *srcline, *dstline;
   710 
   711     srcline = gl_shadow;
   712     srcpitch = surface->w * gl_pixelsize;
   713     dstline = surface->pixels;
   714     dstpitch = surface->pitch;
   715     if (gl_upsidedown) {
   716         srcline += (surface->h - 1) * srcpitch;
   717         srcpitch = -srcpitch;
   718     }
   719 
   720     for (y = 0; y < surface->h; y++) {
   721         SDL_memcpy(dstline, srcline, srcpitch);
   722 
   723         srcline += srcpitch;
   724         dstline += dstpitch;
   725     }
   726 }
   727 
   728 static void
   729 CopyShadowRGBTo555(_THIS, SDL_Surface * surface)
   730 {
   731     int x, y, srcpitch, dstpitch;
   732     Uint16 *dstline, *dstcol;
   733     Uint8 *srcline, *srccol;
   734 
   735     srcline = (Uint8 *) gl_shadow;
   736     srcpitch = surface->w * gl_pixelsize;
   737     dstline = surface->pixels;
   738     dstpitch = surface->pitch >> 1;
   739     if (gl_upsidedown) {
   740         srcline += (surface->h - 1) * srcpitch;
   741         srcpitch = -srcpitch;
   742     }
   743 
   744     for (y = 0; y < surface->h; y++) {
   745         srccol = srcline;
   746         dstcol = dstline;
   747         for (x = 0; x < surface->w; x++) {
   748             Uint16 dstcolor;
   749 
   750             dstcolor = ((*srccol++) << 7) & (31 << 10);
   751             dstcolor |= ((*srccol++) << 2) & (31 << 5);
   752             dstcolor |= ((*srccol++) >> 3) & 31;
   753             *dstcol++ = dstcolor;
   754         }
   755 
   756         srcline += srcpitch;
   757         dstline += dstpitch;
   758     }
   759 }
   760 
   761 static void
   762 CopyShadowRGBTo565(_THIS, SDL_Surface * surface)
   763 {
   764     int x, y, srcpitch, dstpitch;
   765     Uint16 *dstline, *dstcol;
   766     Uint8 *srcline, *srccol;
   767 
   768     srcline = (Uint8 *) gl_shadow;
   769     srcpitch = surface->w * gl_pixelsize;
   770     dstline = surface->pixels;
   771     dstpitch = surface->pitch >> 1;
   772     if (gl_upsidedown) {
   773         srcline += (surface->h - 1) * srcpitch;
   774         srcpitch = -srcpitch;
   775     }
   776 
   777     for (y = 0; y < surface->h; y++) {
   778         srccol = srcline;
   779         dstcol = dstline;
   780 
   781         for (x = 0; x < surface->w; x++) {
   782             Uint16 dstcolor;
   783 
   784             dstcolor = ((*srccol++) << 8) & (31 << 11);
   785             dstcolor |= ((*srccol++) << 3) & (63 << 5);
   786             dstcolor |= ((*srccol++) >> 3) & 31;
   787             *dstcol++ = dstcolor;
   788         }
   789 
   790         srcline += srcpitch;
   791         dstline += dstpitch;
   792     }
   793 }
   794 
   795 static void
   796 CopyShadowRGBSwap(_THIS, SDL_Surface * surface)
   797 {
   798     int x, y, srcpitch, dstpitch;
   799     Uint8 *dstline, *dstcol;
   800     Uint8 *srcline, *srccol;
   801 
   802     srcline = (Uint8 *) gl_shadow;
   803     srcpitch = surface->w * gl_pixelsize;
   804     dstline = surface->pixels;
   805     dstpitch = surface->pitch;
   806     if (gl_upsidedown) {
   807         srcline += (surface->h - 1) * srcpitch;
   808         srcpitch = -srcpitch;
   809     }
   810 
   811     for (y = 0; y < surface->h; y++) {
   812         srccol = srcline;
   813         dstcol = dstline;
   814 
   815         for (x = 0; x < surface->w; x++) {
   816             *dstcol++ = srccol[2];
   817             *dstcol++ = srccol[1];
   818             *dstcol++ = srccol[0];
   819             srccol += 3;
   820         }
   821 
   822         srcline += srcpitch;
   823         dstline += dstpitch;
   824     }
   825 }
   826 
   827 static void
   828 CopyShadowRGBToARGB(_THIS, SDL_Surface * surface)
   829 {
   830     int x, y, srcpitch, dstpitch;
   831     Uint32 *dstline, *dstcol;
   832     Uint8 *srcline, *srccol;
   833 
   834     srcline = (Uint8 *) gl_shadow;
   835     srcpitch = surface->w * gl_pixelsize;
   836     dstline = surface->pixels;
   837     dstpitch = surface->pitch >> 2;
   838     if (gl_upsidedown) {
   839         srcline += (surface->h - 1) * srcpitch;
   840         srcpitch = -srcpitch;
   841     }
   842 
   843     for (y = 0; y < surface->h; y++) {
   844         srccol = srcline;
   845         dstcol = dstline;
   846 
   847         for (x = 0; x < surface->w; x++) {
   848             Uint32 dstcolor;
   849 
   850             dstcolor = (*srccol++) << 16;
   851             dstcolor |= (*srccol++) << 8;
   852             dstcolor |= *srccol++;
   853 
   854             *dstcol++ = dstcolor;
   855         }
   856 
   857         srcline += srcpitch;
   858         dstline += dstpitch;
   859     }
   860 }
   861 
   862 static void
   863 CopyShadowRGBToABGR(_THIS, SDL_Surface * surface)
   864 {
   865     int x, y, srcpitch, dstpitch;
   866     Uint32 *dstline, *dstcol;
   867     Uint8 *srcline, *srccol;
   868 
   869     srcline = (Uint8 *) gl_shadow;
   870     srcpitch = surface->w * gl_pixelsize;
   871     dstline = surface->pixels;
   872     dstpitch = surface->pitch >> 2;
   873     if (gl_upsidedown) {
   874         srcline += (surface->h - 1) * srcpitch;
   875         srcpitch = -srcpitch;
   876     }
   877 
   878     for (y = 0; y < surface->h; y++) {
   879         srccol = srcline;
   880         dstcol = dstline;
   881 
   882         for (x = 0; x < surface->w; x++) {
   883             Uint32 dstcolor;
   884 
   885             dstcolor = *srccol++;
   886             dstcolor |= (*srccol++) << 8;
   887             dstcolor |= (*srccol++) << 16;
   888 
   889             *dstcol++ = dstcolor;
   890         }
   891 
   892         srcline += srcpitch;
   893         dstline += dstpitch;
   894     }
   895 }
   896 
   897 static void
   898 CopyShadowRGBToBGRA(_THIS, SDL_Surface * surface)
   899 {
   900     int x, y, srcpitch, dstpitch;
   901     Uint32 *dstline, *dstcol;
   902     Uint8 *srcline, *srccol;
   903 
   904     srcline = (Uint8 *) gl_shadow;
   905     srcpitch = surface->w * gl_pixelsize;
   906     dstline = surface->pixels;
   907     dstpitch = surface->pitch >> 2;
   908     if (gl_upsidedown) {
   909         srcline += (surface->h - 1) * srcpitch;
   910         srcpitch = -srcpitch;
   911     }
   912 
   913     for (y = 0; y < surface->h; y++) {
   914         srccol = srcline;
   915         dstcol = dstline;
   916 
   917         for (x = 0; x < surface->w; x++) {
   918             Uint32 dstcolor;
   919 
   920             dstcolor = (*srccol++) << 8;
   921             dstcolor |= (*srccol++) << 16;
   922             dstcolor |= (*srccol++) << 24;
   923 
   924             *dstcol++ = dstcolor;
   925         }
   926 
   927         srcline += srcpitch;
   928         dstline += dstpitch;
   929     }
   930 }
   931 
   932 static void
   933 CopyShadowRGBToRGBA(_THIS, SDL_Surface * surface)
   934 {
   935     int x, y, srcpitch, dstpitch;
   936     Uint32 *dstline, *dstcol;
   937     Uint8 *srcline, *srccol;
   938 
   939     srcline = (Uint8 *) gl_shadow;
   940     srcpitch = surface->w * gl_pixelsize;
   941     dstline = surface->pixels;
   942     dstpitch = surface->pitch >> 2;
   943     if (gl_upsidedown) {
   944         srcline += (surface->h - 1) * srcpitch;
   945         srcpitch = -srcpitch;
   946     }
   947 
   948     for (y = 0; y < surface->h; y++) {
   949         srccol = srcline;
   950         dstcol = dstline;
   951 
   952         for (x = 0; x < surface->w; x++) {
   953             Uint32 dstcolor;
   954 
   955             dstcolor = (*srccol++) << 24;
   956             dstcolor |= (*srccol++) << 16;
   957             dstcolor |= (*srccol++) << 8;
   958 
   959             *dstcol++ = dstcolor;
   960         }
   961 
   962         srcline += srcpitch;
   963         dstline += dstpitch;
   964     }
   965 }
   966 
   967 static void
   968 CopyShadow8888To555(_THIS, SDL_Surface * surface)
   969 {
   970     int x, y, srcpitch, dstpitch;
   971     Uint16 *dstline, *dstcol;
   972     Uint32 *srcline, *srccol;
   973 
   974     srcline = (Uint32 *) gl_shadow;
   975     srcpitch = (surface->w * gl_pixelsize) >> 2;
   976     dstline = surface->pixels;
   977     dstpitch = surface->pitch >> 1;
   978     if (gl_upsidedown) {
   979         srcline += (surface->h - 1) * srcpitch;
   980         srcpitch = -srcpitch;
   981     }
   982 
   983     for (y = 0; y < surface->h; y++) {
   984         srccol = srcline;
   985         dstcol = dstline;
   986         for (x = 0; x < surface->w; x++) {
   987             Uint32 srccolor;
   988             Uint16 dstcolor;
   989 
   990             srccolor = *srccol++;
   991             dstcolor = (srccolor >> 9) & (31 << 10);
   992             dstcolor |= (srccolor >> 6) & (31 << 5);
   993             dstcolor |= (srccolor >> 3) & 31;
   994             *dstcol++ = dstcolor;
   995         }
   996 
   997         srcline += srcpitch;
   998         dstline += dstpitch;
   999     }
  1000 }
  1001 
  1002 static void
  1003 CopyShadow8888To565(_THIS, SDL_Surface * surface)
  1004 {
  1005     int x, y, srcpitch, dstpitch;
  1006     Uint16 *dstline, *dstcol;
  1007     Uint32 *srcline, *srccol;
  1008 
  1009     srcline = (Uint32 *) gl_shadow;
  1010     srcpitch = (surface->w * gl_pixelsize) >> 2;
  1011     dstline = surface->pixels;
  1012     dstpitch = surface->pitch >> 1;
  1013     if (gl_upsidedown) {
  1014         srcline += (surface->h - 1) * srcpitch;
  1015         srcpitch = -srcpitch;
  1016     }
  1017 
  1018     for (y = 0; y < surface->h; y++) {
  1019         srccol = srcline;
  1020         dstcol = dstline;
  1021 
  1022         for (x = 0; x < surface->w; x++) {
  1023             Uint32 srccolor;
  1024             Uint16 dstcolor;
  1025 
  1026             srccolor = *srccol++;
  1027             dstcolor = (srccolor >> 8) & (31 << 11);
  1028             dstcolor |= (srccolor >> 5) & (63 << 5);
  1029             dstcolor |= (srccolor >> 3) & 31;
  1030             *dstcol++ = dstcolor;
  1031         }
  1032 
  1033         srcline += srcpitch;
  1034         dstline += dstpitch;
  1035     }
  1036 }
  1037 
  1038 /*--- Conversions routines in the screen ---*/
  1039 
  1040 static void
  1041 ConvertNull(_THIS, SDL_Surface * surface)
  1042 {
  1043 }
  1044 
  1045 static void
  1046 Convert565To555be(_THIS, SDL_Surface * surface)
  1047 {
  1048     int x, y, pitch;
  1049     unsigned short *line, *pixel;
  1050 
  1051     line = surface->pixels;
  1052     pitch = surface->pitch >> 1;
  1053     for (y = 0; y < surface->h; y++) {
  1054         pixel = line;
  1055         for (x = 0; x < surface->w; x++) {
  1056             unsigned short color = *pixel;
  1057 
  1058             *pixel++ = (color & 0x1f) | ((color >> 1) & 0xffe0);
  1059         }
  1060 
  1061         line += pitch;
  1062     }
  1063 }
  1064 
  1065 static void
  1066 Convert565To555le(_THIS, SDL_Surface * surface)
  1067 {
  1068     int x, y, pitch;
  1069     unsigned short *line, *pixel;
  1070 
  1071     line = surface->pixels;
  1072     pitch = surface->pitch >> 1;
  1073     for (y = 0; y < surface->h; y++) {
  1074         pixel = line;
  1075         for (x = 0; x < surface->w; x++) {
  1076             unsigned short color = *pixel;
  1077 
  1078             color = (color & 0x1f) | ((color >> 1) & 0xffe0);
  1079             *pixel++ = SDL_Swap16(color);
  1080         }
  1081 
  1082         line += pitch;
  1083     }
  1084 }
  1085 
  1086 static void
  1087 Convert565le(_THIS, SDL_Surface * surface)
  1088 {
  1089     int x, y, pitch;
  1090     unsigned short *line, *pixel;
  1091 
  1092     line = surface->pixels;
  1093     pitch = surface->pitch >> 1;
  1094     for (y = 0; y < surface->h; y++) {
  1095         pixel = line;
  1096         for (x = 0; x < surface->w; x++) {
  1097             unsigned short color = *pixel;
  1098 
  1099             *pixel++ = SDL_Swap16(color);
  1100         }
  1101 
  1102         line += pitch;
  1103     }
  1104 }
  1105 
  1106 static void
  1107 ConvertBGRAToABGR(_THIS, SDL_Surface * surface)
  1108 {
  1109     int x, y, pitch;
  1110     unsigned long *line, *pixel;
  1111 
  1112     line = surface->pixels;
  1113     pitch = surface->pitch >> 2;
  1114     for (y = 0; y < surface->h; y++) {
  1115         pixel = line;
  1116         for (x = 0; x < surface->w; x++) {
  1117             unsigned long color = *pixel;
  1118 
  1119             *pixel++ = (color << 24) | (color >> 8);
  1120         }
  1121 
  1122         line += pitch;
  1123     }
  1124 }
  1125 
  1126 #endif /* SDL_VIDEO_OPENGL */
  1127 /* vi: set ts=4 sw=4 expandtab: */