comparison src/video/gem/SDL_gemvideo.c @ 989:475166d13b44

Factorize OSMesa OpenGL code for Atari drivers
author Patrice Mandin <patmandin@gmail.com>
date Thu, 25 Nov 2004 15:47:49 +0000
parents 24b5c3ad4852
children 12b13601a544
comparison
equal deleted inserted replaced
988:24b5c3ad4852 989:475166d13b44
34 */ 34 */
35 35
36 #include <stdio.h> 36 #include <stdio.h>
37 #include <stdlib.h> 37 #include <stdlib.h>
38 #include <string.h> 38 #include <string.h>
39
40 #ifdef HAVE_OPENGL
41 #include <GL/osmesa.h>
42 #endif
43 39
44 /* Mint includes */ 40 /* Mint includes */
45 #include <gem.h> 41 #include <gem.h>
46 #include <gemx.h> 42 #include <gemx.h>
47 #include <mint/osbind.h> 43 #include <mint/osbind.h>
58 #include "SDL_cursor_c.h" 54 #include "SDL_cursor_c.h"
59 55
60 #include "SDL_ataric2p_s.h" 56 #include "SDL_ataric2p_s.h"
61 #include "SDL_atarieddi_s.h" 57 #include "SDL_atarieddi_s.h"
62 #include "SDL_atarimxalloc_c.h" 58 #include "SDL_atarimxalloc_c.h"
59 #include "SDL_atarigl_c.h"
60
63 #include "SDL_gemvideo.h" 61 #include "SDL_gemvideo.h"
64 #include "SDL_gemevents_c.h" 62 #include "SDL_gemevents_c.h"
65 #include "SDL_gemmouse_c.h" 63 #include "SDL_gemmouse_c.h"
66 #include "SDL_gemwm_c.h" 64 #include "SDL_gemwm_c.h"
67 #include "SDL_xbiosevents_c.h" 65 #include "SDL_xbiosevents_c.h"
112 static void GEM_UnlockScreen(_THIS); 110 static void GEM_UnlockScreen(_THIS);
113 static void refresh_window(_THIS, int winhandle, short *rect); 111 static void refresh_window(_THIS, int winhandle, short *rect);
114 112
115 #ifdef HAVE_OPENGL 113 #ifdef HAVE_OPENGL
116 /* OpenGL functions */ 114 /* OpenGL functions */
117 static int GEM_GL_LoadLibrary(_THIS, const char *path);
118 static void *GEM_GL_GetProcAddress(_THIS, const char *proc);
119 static int GEM_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
120 static int GEM_GL_MakeCurrent(_THIS);
121 static void GEM_GL_SwapBuffers(_THIS); 115 static void GEM_GL_SwapBuffers(_THIS);
122
123 static void GEM_GL_ConvertNull(SDL_Surface *surface);
124 static void GEM_GL_Convert565To555be(SDL_Surface *surface);
125 static void GEM_GL_Convert565To555le(SDL_Surface *surface);
126 static void GEM_GL_Convert565le(SDL_Surface *surface);
127 static void GEM_GL_ConvertBGRAToABGR(SDL_Surface *surface);
128
129 static void (*GEM_GL_Convert)(SDL_Surface *surface);
130 #endif 116 #endif
131 117
132 /* GEM driver bootstrap functions */ 118 /* GEM driver bootstrap functions */
133 119
134 static int GEM_Available(void) 120 static int GEM_Available(void)
155 device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); 141 device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
156 if ( device ) { 142 if ( device ) {
157 memset(device, 0, (sizeof *device)); 143 memset(device, 0, (sizeof *device));
158 device->hidden = (struct SDL_PrivateVideoData *) 144 device->hidden = (struct SDL_PrivateVideoData *)
159 malloc((sizeof *device->hidden)); 145 malloc((sizeof *device->hidden));
146 device->gl_data = (struct SDL_PrivateGLData *)
147 malloc((sizeof *device->gl_data));
160 } 148 }
161 if ( (device == NULL) || (device->hidden == NULL) ) { 149 if ( (device == NULL) || (device->hidden == NULL) ) {
162 SDL_OutOfMemory(); 150 SDL_OutOfMemory();
163 if ( device ) { 151 if ( device ) {
164 free(device); 152 free(device);
165 } 153 }
166 return(0); 154 return(0);
167 } 155 }
168 memset(device->hidden, 0, (sizeof *device->hidden)); 156 memset(device->hidden, 0, (sizeof *device->hidden));
157 memset(device->gl_data, 0, sizeof(*device->gl_data));
169 158
170 /* Set the function pointers */ 159 /* Set the function pointers */
171 device->VideoInit = GEM_VideoInit; 160 device->VideoInit = GEM_VideoInit;
172 device->ListModes = GEM_ListModes; 161 device->ListModes = GEM_ListModes;
173 device->SetVideoMode = GEM_SetVideoMode; 162 device->SetVideoMode = GEM_SetVideoMode;
198 device->WarpWMCursor = NULL /*GEM_WarpWMCursor*/; 187 device->WarpWMCursor = NULL /*GEM_WarpWMCursor*/;
199 device->CheckMouseMode = GEM_CheckMouseMode; 188 device->CheckMouseMode = GEM_CheckMouseMode;
200 189
201 #ifdef HAVE_OPENGL 190 #ifdef HAVE_OPENGL
202 /* OpenGL functions */ 191 /* OpenGL functions */
203 device->GL_LoadLibrary = GEM_GL_LoadLibrary; 192 device->GL_LoadLibrary = SDL_AtariGL_LoadLibrary;
204 device->GL_GetProcAddress = GEM_GL_GetProcAddress; 193 device->GL_GetProcAddress = SDL_AtariGL_GetProcAddress;
205 device->GL_GetAttribute = GEM_GL_GetAttribute; 194 device->GL_GetAttribute = SDL_AtariGL_GetAttribute;
206 device->GL_MakeCurrent = GEM_GL_MakeCurrent; 195 device->GL_MakeCurrent = SDL_AtariGL_MakeCurrent;
207 device->GL_SwapBuffers = GEM_GL_SwapBuffers; 196 device->GL_SwapBuffers = GEM_GL_SwapBuffers;
208 #endif 197 #endif
209 198
210 /* Joystick + Mouse relative motion */ 199 /* Joystick + Mouse relative motion */
211 SDL_AtariXbios_InstallVectors(ATARI_XBIOS_MOUSEEVENTS|ATARI_XBIOS_JOYSTICKEVENTS); 200 SDL_AtariXbios_InstallVectors(ATARI_XBIOS_MOUSEEVENTS|ATARI_XBIOS_JOYSTICKEVENTS);
481 470
482 #ifdef DEBUG_VIDEO_GEM 471 #ifdef DEBUG_VIDEO_GEM
483 printf("sdl:video:gem: VideoInit(): done\n"); 472 printf("sdl:video:gem: VideoInit(): done\n");
484 #endif 473 #endif
485 474
486 #ifdef HAVE_OPENGL
487 this->gl_config.driver_loaded = 1;
488 #endif
489
490 /* We're done! */ 475 /* We're done! */
491 return(0); 476 return(0);
492 } 477 }
493 478
494 SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) 479 SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
505 } 490 }
506 491
507 static void GEM_FreeBuffers(_THIS) 492 static void GEM_FreeBuffers(_THIS)
508 { 493 {
509 #ifdef HAVE_OPENGL 494 #ifdef HAVE_OPENGL
510 /* Shutdown OpenGL context */ 495 SDL_AtariGL_Quit(this);
511 if (GEM_ctx) {
512 OSMesaDestroyContext(GEM_ctx);
513 GEM_ctx = NULL;
514 }
515 #endif 496 #endif
516 497
517 /* Release buffer */ 498 /* Release buffer */
518 if ( GEM_buffer2 ) { 499 if ( GEM_buffer2 ) {
519 free( GEM_buffer2 ); 500 free( GEM_buffer2 );
758 current->pitch = VDI_pitch; 739 current->pitch = VDI_pitch;
759 } 740 }
760 741
761 #ifdef HAVE_OPENGL 742 #ifdef HAVE_OPENGL
762 if (flags & SDL_OPENGL) { 743 if (flags & SDL_OPENGL) {
763 GLenum format = OSMESA_COLOR_INDEX; /* 8 bits */ 744 if (!SDL_AtariGL_Init(this, current)) {
764
765 /* Init OpenGL context using OSMesa */
766 GEM_GL_Convert = GEM_GL_ConvertNull;
767 switch (VDI_bpp) {
768 case 15:
769 /* 1555, big and little endian, unsupported */
770 format = OSMESA_RGB_565;
771 if (VDI_redmask == 31<<10) {
772 GEM_GL_Convert = GEM_GL_Convert565To555be;
773 } else {
774 GEM_GL_Convert = GEM_GL_Convert565To555le;
775 }
776 break;
777 case 16:
778 if (VDI_redmask == 31<<11) {
779 format = OSMESA_RGB_565;
780 } else {
781 /* 565, little endian, unsupported */
782 format = OSMESA_RGB_565;
783 GEM_GL_Convert = GEM_GL_Convert565le;
784 }
785 break;
786 case 24:
787 if (VDI_redmask == 255<<16) {
788 format = OSMESA_RGB;
789 } else {
790 format = OSMESA_BGR;
791 }
792 break;
793 case 32:
794 if (VDI_redmask == 255<<16) {
795 format = OSMESA_ARGB;
796 } else if (VDI_redmask == 255<<8) {
797 format = OSMESA_BGRA;
798 } else if (VDI_redmask == 255<<24) {
799 format = OSMESA_RGBA;
800 } else {
801 /* ABGR format unsupported */
802 format = OSMESA_BGRA;
803 GEM_GL_Convert = GEM_GL_ConvertBGRAToABGR;
804 }
805 break;
806 }
807
808 GEM_ctx = OSMesaCreateContextExt( format, this->gl_config.depth_size,
809 this->gl_config.stencil_size, this->gl_config.accum_red_size +
810 this->gl_config.accum_green_size + this->gl_config.accum_blue_size +
811 this->gl_config.accum_alpha_size, NULL );
812 if (!GEM_ctx) {
813 GEM_FreeBuffers(this); 745 GEM_FreeBuffers(this);
814 SDL_SetError("OSMesaCreateContext failed"); 746 SDL_SetError("Can not create OpenGL context");
815 return(NULL); 747 return NULL;
816 } 748 }
817 749
818 modeflags |= SDL_OPENGL; 750 modeflags |= SDL_OPENGL;
819 } 751 }
820 #endif 752 #endif
1354 vro_cpyfm( VDI_handle, S_ONLY, pxy, &mfdb_src, &VDI_dst_mfdb); 1286 vro_cpyfm( VDI_handle, S_ONLY, pxy, &mfdb_src, &VDI_dst_mfdb);
1355 } 1287 }
1356 1288
1357 #ifdef HAVE_OPENGL 1289 #ifdef HAVE_OPENGL
1358 1290
1359 static int GEM_GL_LoadLibrary(_THIS, const char *path)
1360 {
1361 /* Library is always opened */
1362 this->gl_config.driver_loaded = 1;
1363
1364 return 0;
1365 }
1366
1367 static void *GEM_GL_GetProcAddress(_THIS, const char *proc)
1368 {
1369 void *func = NULL;
1370
1371 if (GEM_ctx != NULL) {
1372 func = OSMesaGetProcAddress(proc);
1373 }
1374
1375 return func;
1376 }
1377
1378 static int GEM_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
1379 {
1380 GLenum mesa_attrib;
1381
1382 if (GEM_ctx == NULL) {
1383 return -1;
1384 }
1385
1386 switch(attrib) {
1387 case SDL_GL_RED_SIZE:
1388 mesa_attrib = GL_RED_BITS;
1389 break;
1390 case SDL_GL_GREEN_SIZE:
1391 mesa_attrib = GL_GREEN_BITS;
1392 break;
1393 case SDL_GL_BLUE_SIZE:
1394 mesa_attrib = GL_BLUE_BITS;
1395 break;
1396 case SDL_GL_ALPHA_SIZE:
1397 mesa_attrib = GL_ALPHA_BITS;
1398 break;
1399 case SDL_GL_DOUBLEBUFFER:
1400 mesa_attrib = GL_DOUBLEBUFFER;
1401 break;
1402 case SDL_GL_DEPTH_SIZE:
1403 mesa_attrib = GL_DEPTH_BITS;
1404 break;
1405 case SDL_GL_STENCIL_SIZE:
1406 mesa_attrib = GL_STENCIL_BITS;
1407 break;
1408 case SDL_GL_ACCUM_RED_SIZE:
1409 mesa_attrib = GL_ACCUM_RED_BITS;
1410 break;
1411 case SDL_GL_ACCUM_GREEN_SIZE:
1412 mesa_attrib = GL_ACCUM_GREEN_BITS;
1413 break;
1414 case SDL_GL_ACCUM_BLUE_SIZE:
1415 mesa_attrib = GL_ACCUM_BLUE_BITS;
1416 break;
1417 case SDL_GL_ACCUM_ALPHA_SIZE:
1418 mesa_attrib = GL_ACCUM_ALPHA_BITS;
1419 break;
1420 default :
1421 return -1;
1422 }
1423
1424 glGetIntegerv(mesa_attrib, value);
1425 return 0;
1426 }
1427
1428 static int GEM_GL_MakeCurrent(_THIS)
1429 {
1430 SDL_Surface *surface;
1431 GLenum type;
1432
1433 if (GEM_ctx == NULL) {
1434 return -1;
1435 }
1436
1437 surface = this->screen;
1438
1439 if ((surface->format->BitsPerPixel == 15) || (surface->format->BitsPerPixel == 16)) {
1440 type = GL_UNSIGNED_SHORT_5_6_5;
1441 } else {
1442 type = GL_UNSIGNED_BYTE;
1443 }
1444
1445 if (!OSMesaMakeCurrent(GEM_ctx, surface->pixels, type, surface->w, surface->h)) {
1446 SDL_SetError("Can not make OpenGL context current");
1447 return -1;
1448 }
1449
1450 /* OSMesa draws upside down */
1451 OSMesaPixelStore(OSMESA_Y_UP, 0);
1452
1453 return 0;
1454 }
1455
1456 static void GEM_GL_SwapBuffers(_THIS) 1291 static void GEM_GL_SwapBuffers(_THIS)
1457 { 1292 {
1458 GEM_GL_Convert(this->screen); 1293 if (gl_ctx == NULL) {
1294 return;
1295 }
1296
1297 gl_convert(this->screen);
1459 GEM_FlipHWSurface(this, this->screen); 1298 GEM_FlipHWSurface(this, this->screen);
1460 } 1299 }
1461 1300
1462 static void GEM_GL_ConvertNull(SDL_Surface *surface) 1301 #endif
1463 {
1464 }
1465
1466 static void GEM_GL_Convert565To555be(SDL_Surface *surface)
1467 {
1468 int x,y, pitch;
1469 unsigned short *line, *pixel;
1470
1471 line = surface->pixels;
1472 pitch = surface->pitch >> 1;
1473 for (y=0; y<surface->h; y++) {
1474 pixel = line;
1475 for (x=0; x<surface->w; x++) {
1476 unsigned short color = *pixel;
1477
1478 *pixel++ = (color & 0x1f)|((color>>1) & 0xffe0);
1479 }
1480
1481 line += pitch;
1482 }
1483 }
1484
1485 static void GEM_GL_Convert565To555le(SDL_Surface *surface)
1486 {
1487 int x,y, pitch;
1488 unsigned short *line, *pixel;
1489
1490 line = surface->pixels;
1491 pitch = surface->pitch >>1;
1492 for (y=0; y<surface->h; y++) {
1493 pixel = line;
1494 for (x=0; x<surface->w; x++) {
1495 unsigned short color = *pixel;
1496
1497 color = (color & 0x1f)|((color>>1) & 0xffe0);
1498 *pixel++ = SDL_Swap16(color);
1499 }
1500
1501 line += pitch;
1502 }
1503 }
1504
1505 static void GEM_GL_Convert565le(SDL_Surface *surface)
1506 {
1507 int x,y, pitch;
1508 unsigned short *line, *pixel;
1509
1510 line = surface->pixels;
1511 pitch = surface->pitch >>1;
1512 for (y=0; y<surface->h; y++) {
1513 pixel = line;
1514 for (x=0; x<surface->w; x++) {
1515 unsigned short color = *pixel;
1516
1517 *pixel++ = SDL_Swap16(color);
1518 }
1519
1520 line += pitch;
1521 }
1522 }
1523
1524 static void GEM_GL_ConvertBGRAToABGR(SDL_Surface *surface)
1525 {
1526 int x,y, pitch;
1527 unsigned long *line, *pixel;
1528
1529 line = surface->pixels;
1530 pitch = surface->pitch >>2;
1531 for (y=0; y<surface->h; y++) {
1532 pixel = line;
1533 for (x=0; x<surface->w; x++) {
1534 unsigned long color = *pixel;
1535
1536 *pixel++ = (color<<24)|(color>>8);
1537 }
1538
1539 line += pitch;
1540 }
1541 }
1542
1543 #endif