From 527dfc98cc4f09dfd8e0c6d66018ea2e15ad277e Mon Sep 17 00:00:00 2001
From: Miro Kropacek <[EMAIL REDACTED]>
Date: Thu, 24 Sep 2026 11:33:02 +1000
Subject: [PATCH] atari:video: make OpenGL usable with a static OSMesa
Programs not using OpenGL no longer link the whole of OSMesa (~2.5 MB).
OSMesa itself has to link its context functions whenever any gl*()
function is used (it requires patched OSMesa build).
OpenGL surfaces are centered in GEM fullscreen, like 2D ones.
---
src/video/SDL_video.c | 2 --
src/video/ataricommon/SDL_atarigl.c | 52 ++++++++++++++++++-----------
src/video/gem/SDL_gemvideo.c | 17 ++++++++++
src/video/xbios/SDL_xbios.c | 5 +++
4 files changed, 55 insertions(+), 21 deletions(-)
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 4618f5dec..75b889784 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -786,8 +786,6 @@ SDL_Surface * SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags)
#if defined(__QNXNTO__) && (_NTO_VERSION < 630)
#define __SDL_NOGETPROCADDR__
-#elif defined(__MINT__)
-#define __SDL_NOGETPROCADDR__
#endif
#ifdef __SDL_NOGETPROCADDR__
#define SDL_PROC(ret,func,params) video->func=func;
diff --git a/src/video/ataricommon/SDL_atarigl.c b/src/video/ataricommon/SDL_atarigl.c
index 1cf2689c9..46c4fae10 100644
--- a/src/video/ataricommon/SDL_atarigl.c
+++ b/src/video/ataricommon/SDL_atarigl.c
@@ -27,6 +27,16 @@
#if SDL_VIDEO_OPENGL
#include <GL/osmesa.h>
+
+/* Keep OSMesa out of programs that don't use OpenGL; any gl*() call pulls it in */
+#pragma weak OSMesaCreateContextExt
+#pragma weak OSMesaDestroyContext
+#pragma weak OSMesaMakeCurrent
+#pragma weak OSMesaPixelStore
+#pragma weak OSMesaGetProcAddress
+#pragma weak glGetIntegerv
+#pragma weak glFinish
+#pragma weak glFlush
#endif
#include <mint/osbind.h>
@@ -336,7 +346,7 @@ int SDL_AtariGL_MakeCurrent(_THIS)
type = GL_UNSIGNED_BYTE;
}
- if (!(this->gl_data->OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w, surface->h))) {
+ if (!(this->gl_data->OSMesaMakeCurrent(gl_ctx, (Uint8 *)surface->pixels + surface->offset, type, surface->w, surface->h))) {
SDL_SetError("Can not make OpenGL context current");
return -1;
}
@@ -344,6 +354,9 @@ int SDL_AtariGL_MakeCurrent(_THIS)
/* OSMesa draws upside down */
this->gl_data->OSMesaPixelStore(OSMESA_Y_UP, 0);
+ /* The surface can be a part of a larger buffer */
+ this->gl_data->OSMesaPixelStore(OSMESA_ROW_LENGTH, surface->pitch / gl_pixelsize);
+
return 0;
#else
return -1;
@@ -411,12 +424,13 @@ static int InitNew(_THIS, SDL_Surface *current)
int recreatecontext;
GLint newaccumsize;
- if (this->gl_config.dll_handle) {
- if (this->gl_data->OSMesaCreateContextExt == NULL) {
- return 0;
- }
+ if (this->gl_data->OSMesaCreateContextExt == NULL) {
+ return 0;
}
+ /* SDL_SetVideoMode() looks up GL functions via SDL_GL_GetProcAddress() */
+ this->gl_config.driver_loaded = 1;
+
/* Init OpenGL context using OSMesa */
gl_convert = ConvertNull;
gl_copyshadow = CopyShadowNull;
@@ -684,7 +698,7 @@ static void CopyShadowDirect(_THIS, SDL_Surface *surface)
srcline = gl_shadow;
srcpitch = surface->w * gl_pixelsize;
- dstline = surface->pixels;
+ dstline = (void *)((Uint8 *)surface->pixels + surface->offset);
dstpitch = surface->pitch;
if (gl_upsidedown) {
srcline += (surface->h-1)*srcpitch;
@@ -707,7 +721,7 @@ static void CopyShadowRGBTo555(_THIS, SDL_Surface *surface)
srcline = (Uint8 *)gl_shadow;
srcpitch = surface->w * gl_pixelsize;
- dstline = surface->pixels;
+ dstline = (void *)((Uint8 *)surface->pixels + surface->offset);
dstpitch = surface->pitch >>1;
if (gl_upsidedown) {
srcline += (surface->h-1)*srcpitch;
@@ -739,7 +753,7 @@ static void CopyShadowRGBTo565(_THIS, SDL_Surface *surface)
srcline = (Uint8 *)gl_shadow;
srcpitch = surface->w * gl_pixelsize;
- dstline = surface->pixels;
+ dstline = (void *)((Uint8 *)surface->pixels + surface->offset);
dstpitch = surface->pitch >>1;
if (gl_upsidedown) {
srcline += (surface->h-1)*srcpitch;
@@ -772,7 +786,7 @@ static void CopyShadowRGBSwap(_THIS, SDL_Surface *surface)
srcline = (Uint8 *)gl_shadow;
srcpitch = surface->w * gl_pixelsize;
- dstline = surface->pixels;
+ dstline = (void *)((Uint8 *)surface->pixels + surface->offset);
dstpitch = surface->pitch;
if (gl_upsidedown) {
srcline += (surface->h-1)*srcpitch;
@@ -803,7 +817,7 @@ static void CopyShadowRGBToARGB(_THIS, SDL_Surface *surface)
srcline = (Uint8 *)gl_shadow;
srcpitch = surface->w * gl_pixelsize;
- dstline = surface->pixels;
+ dstline = (void *)((Uint8 *)surface->pixels + surface->offset);
dstpitch = surface->pitch >>2;
if (gl_upsidedown) {
srcline += (surface->h-1)*srcpitch;
@@ -837,7 +851,7 @@ static void CopyShadowRGBToABGR(_THIS, SDL_Surface *surface)
srcline = (Uint8 *)gl_shadow;
srcpitch = surface->w * gl_pixelsize;
- dstline = surface->pixels;
+ dstline = (void *)((Uint8 *)surface->pixels + surface->offset);
dstpitch = surface->pitch >>2;
if (gl_upsidedown) {
srcline += (surface->h-1)*srcpitch;
@@ -871,7 +885,7 @@ static void CopyShadowRGBToBGRA(_THIS, SDL_Surface *surface)
srcline = (Uint8 *)gl_shadow;
srcpitch = surface->w * gl_pixelsize;
- dstline = surface->pixels;
+ dstline = (void *)((Uint8 *)surface->pixels + surface->offset);
dstpitch = surface->pitch >>2;
if (gl_upsidedown) {
srcline += (surface->h-1)*srcpitch;
@@ -905,7 +919,7 @@ static void CopyShadowRGBToRGBA(_THIS, SDL_Surface *surface)
srcline = (Uint8 *)gl_shadow;
srcpitch = surface->w * gl_pixelsize;
- dstline = surface->pixels;
+ dstline = (void *)((Uint8 *)surface->pixels + surface->offset);
dstpitch = surface->pitch >>2;
if (gl_upsidedown) {
srcline += (surface->h-1)*srcpitch;
@@ -939,7 +953,7 @@ static void CopyShadow8888To555(_THIS, SDL_Surface *surface)
srcline = (Uint32 *)gl_shadow;
srcpitch = (surface->w * gl_pixelsize) >>2;
- dstline = surface->pixels;
+ dstline = (void *)((Uint8 *)surface->pixels + surface->offset);
dstpitch = surface->pitch >>1;
if (gl_upsidedown) {
srcline += (surface->h-1)*srcpitch;
@@ -973,7 +987,7 @@ static void CopyShadow8888To565(_THIS, SDL_Surface *surface)
srcline = (Uint32 *)gl_shadow;
srcpitch = (surface->w * gl_pixelsize) >> 2;
- dstline = surface->pixels;
+ dstline = (void *)((Uint8 *)surface->pixels + surface->offset);
dstpitch = surface->pitch >>1;
if (gl_upsidedown) {
srcline += (surface->h-1)*srcpitch;
@@ -1011,7 +1025,7 @@ static void Convert565To555be(_THIS, SDL_Surface *surface)
int x,y, pitch;
unsigned short *line, *pixel;
- line = surface->pixels;
+ line = (void *)((Uint8 *)surface->pixels + surface->offset);
pitch = surface->pitch >> 1;
for (y=0; y<surface->h; y++) {
pixel = line;
@@ -1030,7 +1044,7 @@ static void Convert565To555le(_THIS, SDL_Surface *surface)
int x,y, pitch;
unsigned short *line, *pixel;
- line = surface->pixels;
+ line = (void *)((Uint8 *)surface->pixels + surface->offset);
pitch = surface->pitch >>1;
for (y=0; y<surface->h; y++) {
pixel = line;
@@ -1050,7 +1064,7 @@ static void Convert565le(_THIS, SDL_Surface *surface)
int x,y, pitch;
unsigned short *line, *pixel;
- line = surface->pixels;
+ line = (void *)((Uint8 *)surface->pixels + surface->offset);
pitch = surface->pitch >>1;
for (y=0; y<surface->h; y++) {
pixel = line;
@@ -1069,7 +1083,7 @@ static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface)
int x,y, pitch;
unsigned long *line, *pixel;
- line = surface->pixels;
+ line = (void *)((Uint8 *)surface->pixels + surface->offset);
pitch = surface->pitch >>2;
for (y=0; y<surface->h; y++) {
pixel = line;
diff --git a/src/video/gem/SDL_gemvideo.c b/src/video/gem/SDL_gemvideo.c
index 9459ef980..f248bf6de 100644
--- a/src/video/gem/SDL_gemvideo.c
+++ b/src/video/gem/SDL_gemvideo.c
@@ -655,11 +655,18 @@ static SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current,
{
Uint32 modeflags, screensize;
SDL_bool use_shadow1, use_shadow2;
+#if SDL_VIDEO_OPENGL
+ int surf_width, surf_height;
+#endif
/* width must be multiple of 16, for vro_cpyfm() and c2p_convert() */
if ((width & 15) != 0) {
width = (width | 15) +1;
}
+#if SDL_VIDEO_OPENGL
+ surf_width = width;
+ surf_height = height;
+#endif
/*--- Verify if asked mode can be used ---*/
if (VDI_bpp != bpp) {
@@ -867,6 +874,16 @@ static SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current,
#if SDL_VIDEO_OPENGL
if (flags & SDL_OPENGL) {
+ /* SDL_SetVideoMode() centers a 2D surface only */
+ if (flags & SDL_FULLSCREEN) {
+ this->offset_x = (width - surf_width) / 2;
+ this->offset_y = (height - surf_height) / 2;
+ current->offset = this->offset_y * current->pitch +
+ this->offset_x * VDI_pixelsize;
+ current->w = surf_width;
+ current->h = surf_height;
+ }
+
if (!SDL_AtariGL_Init(this, current)) {
GEM_FreeBuffers(this);
SDL_SetError("Can not create OpenGL context");
diff --git a/src/video/xbios/SDL_xbios.c b/src/video/xbios/SDL_xbios.c
index c28987c13..9fd8ec343 100644
--- a/src/video/xbios/SDL_xbios.c
+++ b/src/video/xbios/SDL_xbios.c
@@ -571,6 +571,11 @@ static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current,
#if SDL_VIDEO_OPENGL
if (flags & SDL_OPENGL) {
+ /* SDL_SetVideoMode() sets the offsets of a 2D surface only */
+ current->offset = 0;
+ this->offset_x = 0;
+ this->offset_y = 0;
+
if (!SDL_AtariGL_Init(this, current)) {
XBIOS_FreeBuffers(this);
SDL_SetError("Can not create OpenGL context");