From fc47091592bba840e9a97b2e5717d922992d21e3 Mon Sep 17 00:00:00 2001 From: Link Mauve Date: Mon, 20 Apr 2026 16:06:14 +0200 Subject: [PATCH] Remove GLX support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EGL is the de-facto GL context initialization API, including on X11 where it provides many additional features over GLX. I’m planning on adding support for selecting the GPU (adapter in Dolphin-speak) also to OpenGL, similarly to the Vulkan backend, and that will require EGL, so let’s remove the legacy API first. --- Source/Core/Common/CMakeLists.txt | 6 - Source/Core/Common/GL/GLContext.cpp | 20 +- Source/Core/Common/GL/GLContext.h | 3 +- Source/Core/Common/GL/GLInterface/GLX.cpp | 320 ---------------------- Source/Core/Common/GL/GLInterface/GLX.h | 49 ---- Source/Core/VideoBackends/OGL/OGLMain.cpp | 4 +- 6 files changed, 6 insertions(+), 396 deletions(-) delete mode 100644 Source/Core/Common/GL/GLInterface/GLX.cpp delete mode 100644 Source/Core/Common/GL/GLInterface/GLX.h diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index fe7aa9f72b..894fd38128 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -331,13 +331,7 @@ elseif(ENABLE_X11 AND X11_FOUND) target_sources(common PRIVATE GL/GLX11Window.cpp GL/GLX11Window.h - GL/GLInterface/GLX.cpp - GL/GLInterface/GLX.h ) - - # GLX has a hard dependency on libGL. - # Make sure to link to it if using GLX. - target_link_libraries(common PUBLIC ${OPENGL_LIBRARIES}) endif() if(CMAKE_SYSTEM_NAME STREQUAL "Linux") diff --git a/Source/Core/Common/GL/GLContext.cpp b/Source/Core/Common/GL/GLContext.cpp index f7b6ca8af8..eef689616e 100644 --- a/Source/Core/Common/GL/GLContext.cpp +++ b/Source/Core/Common/GL/GLContext.cpp @@ -14,9 +14,6 @@ #if defined(__HAIKU__) #include "Common/GL/GLInterface/BGL.h" #endif -#if HAVE_X11 -#include "Common/GL/GLInterface/GLX.h" -#endif #if HAVE_EGL #include "Common/GL/GLInterface/EGL.h" #if HAVE_X11 @@ -79,7 +76,7 @@ void* GLContext::GetFuncAddress(const std::string& name) } std::unique_ptr GLContext::Create(const WindowSystemInfo& wsi, bool stereo, bool core, - bool prefer_egl, bool prefer_gles) + bool prefer_gles) { std::unique_ptr context; #if defined(__APPLE__) @@ -98,22 +95,11 @@ std::unique_ptr GLContext::Create(const WindowSystemInfo& wsi, bool s if (wsi.type == WindowSystemType::Haiku) context = std::make_unique(); #endif +#if HAVE_EGL #if HAVE_X11 if (wsi.type == WindowSystemType::X11) - { -#if defined(HAVE_EGL) - // GLES 3 is not supported via GLX. - const bool use_egl = prefer_egl || prefer_gles; - if (use_egl) - context = std::make_unique(); - else - context = std::make_unique(); -#else - context = std::make_unique(); + context = std::make_unique(); #endif - } -#endif -#if HAVE_EGL if (wsi.type == WindowSystemType::Headless || wsi.type == WindowSystemType::FBDev) context = std::make_unique(); #endif diff --git a/Source/Core/Common/GL/GLContext.h b/Source/Core/Common/GL/GLContext.h index a1d0a931bf..b1619a647f 100644 --- a/Source/Core/Common/GL/GLContext.h +++ b/Source/Core/Common/GL/GLContext.h @@ -47,8 +47,7 @@ public: // Creates an instance of GLContext specific to the platform we are running on. // If successful, the context is made current on the calling thread. static std::unique_ptr Create(const WindowSystemInfo& wsi, bool stereo = false, - bool core = true, bool prefer_egl = false, - bool prefer_gles = false); + bool core = true, bool prefer_gles = false); protected: virtual bool Initialize(const WindowSystemInfo& wsi, bool stereo, bool core); diff --git a/Source/Core/Common/GL/GLInterface/GLX.cpp b/Source/Core/Common/GL/GLInterface/GLX.cpp deleted file mode 100644 index ce16bb2155..0000000000 --- a/Source/Core/Common/GL/GLInterface/GLX.cpp +++ /dev/null @@ -1,320 +0,0 @@ -// Copyright 2012 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "Common/GL/GLInterface/GLX.h" - -#include -#include - -#include "Common/Logging/Log.h" - -#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 - -typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSPROC)(Display*, GLXFBConfig, GLXContext, Bool, - const int*); - -#ifndef GLX_EXT_swap_control -typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*, GLXDrawable, int); -#endif - -typedef int (*PFNGLXSWAPINTERVALMESAPROC)(unsigned int); - -static PFNGLXCREATECONTEXTATTRIBSPROC glXCreateContextAttribs = nullptr; -static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXTPtr = nullptr; -static PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESAPtr = nullptr; - -static PFNGLXCREATEGLXPBUFFERSGIXPROC glXCreateGLXPbufferSGIX = nullptr; -static PFNGLXDESTROYGLXPBUFFERSGIXPROC glXDestroyGLXPbufferSGIX = nullptr; - -static bool s_glxError; -static int ctxErrorHandler(Display* dpy, XErrorEvent* ev) -{ - s_glxError = true; - return 0; -} - -GLContextGLX::~GLContextGLX() -{ - DestroyWindowSurface(); - if (m_context) - { - if (glXGetCurrentContext() == m_context) - glXMakeCurrent(m_display, None, nullptr); - - glXDestroyContext(m_display, m_context); - } -} - -bool GLContextGLX::IsHeadless() const -{ - return !m_render_window; -} - -void GLContextGLX::SwapInterval(int Interval) -{ - if (!m_drawable) - return; - - // Try EXT_swap_control, then MESA_swap_control. - if (glXSwapIntervalEXTPtr) - { - glXSwapIntervalEXTPtr(m_display, m_drawable, Interval); - } - else if (glXSwapIntervalMESAPtr) - { - glXSwapIntervalMESAPtr(static_cast(Interval)); - } - else - { - ERROR_LOG_FMT(VIDEO, - "No support for SwapInterval (framerate clamped to monitor refresh rate)."); - } -} - -void* GLContextGLX::GetFuncAddress(const std::string& name) -{ - return reinterpret_cast(glXGetProcAddress(reinterpret_cast(name.c_str()))); -} - -void GLContextGLX::Swap() -{ - glXSwapBuffers(m_display, m_drawable); -} - -// Create rendering window. -// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() -bool GLContextGLX::Initialize(const WindowSystemInfo& wsi, bool stereo, bool core) -{ - m_display = static_cast(wsi.display_connection); - int screen = DefaultScreen(m_display); - - // checking glx version - int glxMajorVersion, glxMinorVersion; - glXQueryVersion(m_display, &glxMajorVersion, &glxMinorVersion); - if (glxMajorVersion < 1 || (glxMajorVersion == 1 && glxMinorVersion < 4)) - { - ERROR_LOG_FMT(VIDEO, "glX-Version {}.{} detected, but need at least 1.4", glxMajorVersion, - glxMinorVersion); - return false; - } - - // loading core context creation function - glXCreateContextAttribs = - (PFNGLXCREATECONTEXTATTRIBSPROC)GetFuncAddress("glXCreateContextAttribsARB"); - if (!glXCreateContextAttribs) - { - ERROR_LOG_FMT(VIDEO, - "glXCreateContextAttribsARB not found, do you support GLX_ARB_create_context?"); - return false; - } - - // choosing framebuffer - int visual_attribs[] = {GLX_X_RENDERABLE, - True, - GLX_DRAWABLE_TYPE, - GLX_WINDOW_BIT, - GLX_X_VISUAL_TYPE, - GLX_TRUE_COLOR, - GLX_RED_SIZE, - 8, - GLX_GREEN_SIZE, - 8, - GLX_BLUE_SIZE, - 8, - GLX_DEPTH_SIZE, - 0, - GLX_STENCIL_SIZE, - 0, - GLX_DOUBLEBUFFER, - True, - GLX_STEREO, - stereo ? True : False, - None}; - int fbcount = 0; - GLXFBConfig* fbc = glXChooseFBConfig(m_display, screen, visual_attribs, &fbcount); - if (!fbc || !fbcount) - { - ERROR_LOG_FMT(VIDEO, "Failed to retrieve a framebuffer config"); - return false; - } - m_fbconfig = *fbc; - XFree(fbc); - - s_glxError = false; - XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler); - - // Create a GLX context. - if (core) - { - for (const auto& version : s_desktop_opengl_versions) - { - std::array context_attribs = { - {GLX_CONTEXT_MAJOR_VERSION_ARB, version.first, GLX_CONTEXT_MINOR_VERSION_ARB, - version.second, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, None}}; - - s_glxError = false; - m_context = - glXCreateContextAttribs(m_display, m_fbconfig, nullptr, True, &context_attribs[0]); - XSync(m_display, False); - if (!m_context || s_glxError) - continue; - - // Got a context. - INFO_LOG_FMT(VIDEO, "Created a GLX context with version {}.{}", version.first, - version.second); - m_attribs.insert(m_attribs.end(), context_attribs.begin(), context_attribs.end()); - break; - } - } - - // Failed to create any core contexts, try for anything. - if (!m_context || s_glxError) - { - std::array context_attribs_legacy = { - {GLX_CONTEXT_MAJOR_VERSION_ARB, 1, GLX_CONTEXT_MINOR_VERSION_ARB, 0, None}}; - s_glxError = false; - m_context = - glXCreateContextAttribs(m_display, m_fbconfig, nullptr, True, &context_attribs_legacy[0]); - XSync(m_display, False); - m_attribs.clear(); - m_attribs.insert(m_attribs.end(), context_attribs_legacy.begin(), context_attribs_legacy.end()); - } - if (!m_context || s_glxError) - { - ERROR_LOG_FMT(VIDEO, "Unable to create GL context."); - XSetErrorHandler(oldHandler); - return false; - } - - glXSwapIntervalEXTPtr = nullptr; - glXSwapIntervalMESAPtr = nullptr; - glXCreateGLXPbufferSGIX = nullptr; - glXDestroyGLXPbufferSGIX = nullptr; - m_supports_pbuffer = false; - - std::string tmp; - std::istringstream buffer(glXQueryExtensionsString(m_display, screen)); - while (buffer >> tmp) - { - if (tmp == "GLX_SGIX_pbuffer") - { - glXCreateGLXPbufferSGIX = reinterpret_cast( - GetFuncAddress("glXCreateGLXPbufferSGIX")); - glXDestroyGLXPbufferSGIX = reinterpret_cast( - GetFuncAddress("glXDestroyGLXPbufferSGIX")); - m_supports_pbuffer = glXCreateGLXPbufferSGIX && glXDestroyGLXPbufferSGIX; - } - else if (tmp == "GLX_EXT_swap_control") - { - glXSwapIntervalEXTPtr = - reinterpret_cast(GetFuncAddress("glXSwapIntervalEXT")); - } - else if (tmp == "GLX_MESA_swap_control") - { - glXSwapIntervalMESAPtr = - reinterpret_cast(GetFuncAddress("glXSwapIntervalMESA")); - } - } - - if (!CreateWindowSurface(reinterpret_cast(wsi.render_surface))) - { - ERROR_LOG_FMT(VIDEO, "Error: CreateWindowSurface failed\n"); - XSetErrorHandler(oldHandler); - return false; - } - - XSetErrorHandler(oldHandler); - m_opengl_mode = Mode::OpenGL; - return MakeCurrent(); -} - -std::unique_ptr GLContextGLX::CreateSharedContext() -{ - s_glxError = false; - XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler); - - GLXContext new_glx_context = - glXCreateContextAttribs(m_display, m_fbconfig, m_context, True, &m_attribs[0]); - XSync(m_display, False); - - if (!new_glx_context || s_glxError) - { - ERROR_LOG_FMT(VIDEO, "Unable to create GL context."); - XSetErrorHandler(oldHandler); - return nullptr; - } - - std::unique_ptr new_context = std::make_unique(); - new_context->m_context = new_glx_context; - new_context->m_opengl_mode = m_opengl_mode; - new_context->m_supports_pbuffer = m_supports_pbuffer; - new_context->m_display = m_display; - new_context->m_fbconfig = m_fbconfig; - new_context->m_is_shared = true; - - if (m_supports_pbuffer && !new_context->CreateWindowSurface(None)) - { - ERROR_LOG_FMT(VIDEO, "Error: CreateWindowSurface failed"); - XSetErrorHandler(oldHandler); - return nullptr; - } - - XSetErrorHandler(oldHandler); - return new_context; -} - -bool GLContextGLX::CreateWindowSurface(Window window_handle) -{ - if (window_handle) - { - // Get an appropriate visual - XVisualInfo* vi = glXGetVisualFromFBConfig(m_display, m_fbconfig); - m_render_window = GLX11Window::Create(m_display, window_handle, vi); - if (!m_render_window) - return false; - - m_backbuffer_width = m_render_window->GetWidth(); - m_backbuffer_height = m_render_window->GetHeight(); - m_drawable = static_cast(m_render_window->GetWindow()); - XFree(vi); - } - else if (m_supports_pbuffer) - { - m_pbuffer = glXCreateGLXPbufferSGIX(m_display, m_fbconfig, 1, 1, nullptr); - if (!m_pbuffer) - return false; - - m_drawable = static_cast(m_pbuffer); - } - - return true; -} - -void GLContextGLX::DestroyWindowSurface() -{ - m_render_window.reset(); - if (m_supports_pbuffer && m_pbuffer) - { - glXDestroyGLXPbufferSGIX(m_display, m_pbuffer); - m_pbuffer = 0; - } -} - -bool GLContextGLX::MakeCurrent() -{ - return glXMakeCurrent(m_display, m_drawable, m_context); -} - -bool GLContextGLX::ClearCurrent() -{ - return glXMakeCurrent(m_display, None, nullptr); -} - -void GLContextGLX::Update() -{ - m_render_window->UpdateDimensions(); - m_backbuffer_width = m_render_window->GetWidth(); - m_backbuffer_height = m_render_window->GetHeight(); -} diff --git a/Source/Core/Common/GL/GLInterface/GLX.h b/Source/Core/Common/GL/GLInterface/GLX.h deleted file mode 100644 index ec4bd29cb9..0000000000 --- a/Source/Core/Common/GL/GLInterface/GLX.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2008 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include -#include -#include - -#include "Common/GL/GLContext.h" -#include "Common/GL/GLX11Window.h" - -class GLContextGLX final : public GLContext -{ -public: - ~GLContextGLX() override; - - bool IsHeadless() const override; - - std::unique_ptr CreateSharedContext() override; - - bool MakeCurrent() override; - bool ClearCurrent() override; - - void Update() override; - - void SwapInterval(int Interval) override; - void Swap() override; - - void* GetFuncAddress(const std::string& name) override; - -protected: - bool Initialize(const WindowSystemInfo& wsi, bool stereo, bool core) override; - - Display* m_display = nullptr; - std::unique_ptr m_render_window; - - GLXDrawable m_drawable = {}; - GLXContext m_context = nullptr; - GLXFBConfig m_fbconfig = {}; - bool m_supports_pbuffer = false; - GLXPbufferSGIX m_pbuffer = 0; - std::vector m_attribs; - - bool CreateWindowSurface(Window window_handle); - void DestroyWindowSurface(); -}; diff --git a/Source/Core/VideoBackends/OGL/OGLMain.cpp b/Source/Core/VideoBackends/OGL/OGLMain.cpp index bb1f9158df..df0c28a21c 100644 --- a/Source/Core/VideoBackends/OGL/OGLMain.cpp +++ b/Source/Core/VideoBackends/OGL/OGLMain.cpp @@ -76,7 +76,7 @@ std::string VideoBackend::GetDisplayName() const void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi) { std::unique_ptr temp_gl_context = - GLContext::Create(wsi, g_Config.stereo_mode == StereoMode::QuadBuffer, true, false, + GLContext::Create(wsi, g_Config.stereo_mode == StereoMode::QuadBuffer, true, Config::Get(Config::GFX_PREFER_GLES)); if (!temp_gl_context) @@ -195,7 +195,7 @@ bool VideoBackend::FillBackendInfo(GLContext* context) bool VideoBackend::Initialize(const WindowSystemInfo& wsi) { std::unique_ptr main_gl_context = - GLContext::Create(wsi, g_Config.stereo_mode == StereoMode::QuadBuffer, true, false, + GLContext::Create(wsi, g_Config.stereo_mode == StereoMode::QuadBuffer, true, Config::Get(Config::GFX_PREFER_GLES)); if (!main_gl_context) return false;