From d319d2c6fb31e159a1542c17c4598ed06cc3ec12 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Thu, 19 Nov 2020 01:58:20 +0100 Subject: [PATCH] GTK: Use SDL2 instead of GLX for OpenGL context creation GLX is tied to X11, while SDL2 works on many other platforms (including native Wayland). --- desmume/src/frontend/posix/gtk/glx_3Demu.cpp | 165 ------------------ desmume/src/frontend/posix/gtk/main.cpp | 36 ++-- desmume/src/frontend/posix/gtk/meson.build | 2 +- desmume/src/frontend/posix/gtk/sdl_3Demu.cpp | 83 +++++++++ .../posix/gtk/{glx_3Demu.h => sdl_3Demu.h} | 15 +- desmume/src/frontend/posix/meson.build | 1 - 6 files changed, 108 insertions(+), 194 deletions(-) delete mode 100644 desmume/src/frontend/posix/gtk/glx_3Demu.cpp create mode 100644 desmume/src/frontend/posix/gtk/sdl_3Demu.cpp rename desmume/src/frontend/posix/gtk/{glx_3Demu.h => sdl_3Demu.h} (74%) diff --git a/desmume/src/frontend/posix/gtk/glx_3Demu.cpp b/desmume/src/frontend/posix/gtk/glx_3Demu.cpp deleted file mode 100644 index 98618b422..000000000 --- a/desmume/src/frontend/posix/gtk/glx_3Demu.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - Copyright (C) 2013 The Lemon Man - Copyright (C) 2013-2017 DeSmuME team - - This file is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - This file is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with the this software. If not, see . - */ - -#ifdef HAVE_GL_GLX -#include -#include -#include -#include "../OGLRender.h" - -#include "glx_3Demu.h" - -static bool glx_beginOpenGL(void) { return 1; } -static void glx_endOpenGL(void) { } -static bool glx_init(void) { return is_glx_initialized(); } -static int xerror_handler(Display *dpy, XErrorEvent *ev) { return 0; } - -static GLXContext ctx = NULL; -static GLXPbuffer pbuf; - -typedef GLXContext (*wtf)(Display*, GLXFBConfig, GLXContext, Bool, const int*); - -bool deinit_glx_3Demu(void) -{ - Display *dpy = glXGetCurrentDisplay(); - - if (dpy) - { - glXDestroyPbuffer(dpy, pbuf); - glXDestroyContext(dpy, ctx); - - XCloseDisplay(dpy); - - ctx = NULL; - - return true; - } - - return false; -} - -bool init_glx_3Demu(void) -{ - Display *dpy = XOpenDisplay(NULL); - XVisualInfo *vis; - GLXFBConfig *cfg; - int maj, min; - - if (!dpy) - return false; - - // Check if GLX is present - if (!glXQueryVersion(dpy, &maj, &min)) - return false; - - // We need GLX 1.3 at least - if (maj < 1 || (maj == 1 && min < 3)) - return false; - - const int vis_attr[] = { - GLX_RGBA, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - GLX_ALPHA_SIZE, 8, - GLX_DEPTH_SIZE, 24, - GLX_STENCIL_SIZE, 8, - GLX_DOUBLEBUFFER, - None - }; - vis = glXChooseVisual(dpy, DefaultScreen(dpy), (int *)&vis_attr); - - if (!vis) - return false; - - const int fb_attr[] = { - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, - GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, - GLX_DOUBLEBUFFER, true, - GLX_X_RENDERABLE, true, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - GLX_ALPHA_SIZE, 8, - GLX_DEPTH_SIZE, 24, - GLX_STENCIL_SIZE, 8, - None - }; - int configs; - cfg = glXChooseFBConfig(dpy, DefaultScreen(dpy), (int *)&fb_attr, &configs); - - if (!cfg) - return false; - - const int pbuf_attr[] = { - GLX_PBUFFER_WIDTH, 256, - //GLX_PBUFFER_HEIGHT, 192, // Use a square size to prevent possible incompatibilities - GLX_PBUFFER_HEIGHT, 256, - None - }; - // The first should match exactly, otherwise is the least wrong one - pbuf = glXCreatePbuffer(dpy, cfg[0], (int *)&pbuf_attr); - - // Dynamic linking is a pain, sigh - OGLEXT(PFNGLXCREATECONTEXTATTRIBSARBPROC, glXCreateContextAttribsARB); - INITOGLEXT(PFNGLXCREATECONTEXTATTRIBSARBPROC, glXCreateContextAttribsARB); - - // Try to get a 3.2 core profile context - if (glXCreateContextAttribsARB) { - const int ctx_attr[] = { - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 2, - None - }; - // This silly dance is needed because if Xorg can't acquire the context - // we asked for it will throw an error, which is caught by GTK X error - // handler and made fatal. The show must go on. - int (*old_handler)(Display*, XErrorEvent*) = XSetErrorHandler(&xerror_handler); - ctx = glXCreateContextAttribsARB(dpy, cfg[0], 0, true, ctx_attr); - XSetErrorHandler(old_handler); - } - - // Something went wrong, try with a standard context - if (!ctx) - ctx = glXCreateContext(dpy, vis, NULL, true); - - XFree(cfg); - - if (!ctx) - return false; - - if (!glXMakeContextCurrent(dpy, pbuf, pbuf, ctx)) - return false; - - printf("OGL/GLX Renderer has finished the initialization.\n"); - - oglrender_init = glx_init; - oglrender_beginOpenGL = glx_beginOpenGL; - oglrender_endOpenGL = glx_endOpenGL; - - return true; -} - -bool is_glx_initialized(void) -{ - return (ctx != NULL); -} - -#endif // HAVE_GLX diff --git a/desmume/src/frontend/posix/gtk/main.cpp b/desmume/src/frontend/posix/gtk/main.cpp index cf026ec4e..2ad7c43f7 100644 --- a/desmume/src/frontend/posix/gtk/main.cpp +++ b/desmume/src/frontend/posix/gtk/main.cpp @@ -69,9 +69,7 @@ #include "gdbstub.h" #endif -#if defined(HAVE_LIBOSMESA) || defined(HAVE_GL_GLX) - #define HAVE_OPENGL -#endif +#define HAVE_OPENGL #ifdef HAVE_OPENGL #include @@ -79,10 +77,10 @@ #include "OGLRender_3_2.h" #endif -#if defined(HAVE_GL_GLX) - #include "glx_3Demu.h" -#elif defined(HAVE_LIBOSMESA) +#if defined(HAVE_LIBOSMESA) #include "osmesa_3Demu.h" +#else + #include "sdl_3Demu.h" #endif #include "config.h" @@ -3060,16 +3058,16 @@ static void GraphicsSettingsDialog(GSimpleAction *action, GVariant *parameter, g { #if !defined(HAVE_OPENGL) sel3DCore = RENDERID_SOFTRASTERIZER; -#elif defined(HAVE_GL_GLX) - if (!is_glx_initialized()) - { - init_glx_3Demu(); - } #elif defined(HAVE_LIBOSMESA) if (!is_osmesa_initialized()) { init_osmesa_3Demu(); } +#else + if (!is_sdl_initialized()) + { + init_sdl_3Demu(); + } #endif } @@ -4466,16 +4464,16 @@ common_gtk_main(GApplication *app, gpointer user_data) { #if !defined(HAVE_OPENGL) core = RENDERID_SOFTRASTERIZER; -#elif defined(HAVE_GL_GLX) - if (!is_glx_initialized()) - { - init_glx_3Demu(); - } #elif defined(HAVE_LIBOSMESA) if (!is_osmesa_initialized()) { init_osmesa_3Demu(); } +#else + if (!is_sdl_initialized()) + { + init_sdl_3Demu(); + } #endif } @@ -4546,10 +4544,10 @@ static void Teardown() { desmume_free(); -#if defined(HAVE_GL_GLX) - deinit_glx_3Demu(); -#elif defined(HAVE_LIBOSMESA) +#if defined(HAVE_LIBOSMESA) deinit_osmesa_3Demu(); +#else + deinit_sdl_3Demu(); #endif /* Unload joystick */ diff --git a/desmume/src/frontend/posix/gtk/meson.build b/desmume/src/frontend/posix/gtk/meson.build index 46706b473..20a31da12 100644 --- a/desmume/src/frontend/posix/gtk/meson.build +++ b/desmume/src/frontend/posix/gtk/meson.build @@ -14,7 +14,7 @@ desmume_src = [ '../shared/sndsdl.cpp', '../shared/ctrlssdl.cpp', 'osmesa_3Demu.cpp', - 'glx_3Demu.cpp', + 'sdl_3Demu.cpp', 'cheatsGTK.cpp', 'main.cpp', ] diff --git a/desmume/src/frontend/posix/gtk/sdl_3Demu.cpp b/desmume/src/frontend/posix/gtk/sdl_3Demu.cpp new file mode 100644 index 000000000..c05051122 --- /dev/null +++ b/desmume/src/frontend/posix/gtk/sdl_3Demu.cpp @@ -0,0 +1,83 @@ +/* + Copyright (C) 2020 Emmanuel Gil Peyrot + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . + */ + +#include +#include +#include "../OGLRender.h" + +#include "sdl_3Demu.h" + +static bool sdl_beginOpenGL(void) { return 1; } +static void sdl_endOpenGL(void) { } +static bool sdl_init(void) { return is_sdl_initialized(); } + +static SDL_Window *win = NULL; +static SDL_GLContext ctx = NULL; + +bool deinit_sdl_3Demu(void) +{ + bool ret = false; + + if (ctx) { + SDL_GL_DeleteContext(ctx); + ctx = NULL; + ret = true; + } + + if (win) { + SDL_DestroyWindow(win); + win = NULL; + ret = true; + } + + return ret; +} + +bool init_sdl_3Demu(void) +{ + win = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 256, 192, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN); + if (!win) + return false; + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + + ctx = SDL_GL_CreateContext(win); + if (!ctx) + return false; + + printf("OGL/SDL Renderer has finished the initialization.\n"); + + oglrender_init = sdl_init; + oglrender_beginOpenGL = sdl_beginOpenGL; + oglrender_endOpenGL = sdl_endOpenGL; + + return true; +} + +bool is_sdl_initialized(void) +{ + return (ctx != NULL); +} diff --git a/desmume/src/frontend/posix/gtk/glx_3Demu.h b/desmume/src/frontend/posix/gtk/sdl_3Demu.h similarity index 74% rename from desmume/src/frontend/posix/gtk/glx_3Demu.h rename to desmume/src/frontend/posix/gtk/sdl_3Demu.h index c35dbc0dc..2088263da 100644 --- a/desmume/src/frontend/posix/gtk/glx_3Demu.h +++ b/desmume/src/frontend/posix/gtk/sdl_3Demu.h @@ -1,6 +1,5 @@ /* - Copyright (C) 2013 The Lemon Man - Copyright (C) 2013-2017 DeSmuME team + Copyright (C) 2020 Emmanuel Gil Peyrot This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,12 +15,12 @@ along with the this software. If not, see . */ -#ifndef GLX_3DEMU_H -#define GLX_3DEMU_H +#ifndef SDL_3DEMU_H +#define SDL_3DEMU_H -bool init_glx_3Demu(void); -bool deinit_glx_3Demu(void); -bool is_glx_initialized(void); +bool init_sdl_3Demu(void); +bool deinit_sdl_3Demu(void); +bool is_sdl_initialized(void); -#endif // GLX_3DEMU_H +#endif // SDL_3DEMU_H diff --git a/desmume/src/frontend/posix/meson.build b/desmume/src/frontend/posix/meson.build index f218fed42..901c4defc 100644 --- a/desmume/src/frontend/posix/meson.build +++ b/desmume/src/frontend/posix/meson.build @@ -169,7 +169,6 @@ libdesmume_src += [ if dep_gl.found() dependencies += dep_gl - add_global_arguments('-DHAVE_GL_GLX', language: ['c', 'cpp']) libdesmume_src += [ '../../OGLRender.cpp', '../../OGLRender_3_2.cpp',