Adds EGL support for Wayland.

Tested By: Freagarach, Mentula, phosit
Differential Revision: https://code.wildfiregames.com/D4642
This was SVN commit r26929.
This commit is contained in:
Vladislav Belov 2022-06-09 21:09:32 +00:00
parent d19b602ecc
commit 9845a99f77
6 changed files with 137 additions and 22 deletions

View File

@ -947,7 +947,7 @@ function setup_all_libs ()
if os.istarget("windows") then
files { glad_path.."src/wgl.cpp" }
elseif os.istarget("linux") or os.istarget("bsd") then
files { glad_path.."src/glx.cpp" }
files { glad_path.."src/egl.cpp", glad_path.."src/glx.cpp" }
end
end

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2021 Wildfire Games.
/* Copyright (C) 2022 Wildfire Games.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -43,6 +43,20 @@ void* GetX11Display(SDL_Window* window)
}
#endif
#if defined(SDL_VIDEO_DRIVER_WAYLAND) && !CONFIG2_GLES
void* GetWaylandDisplay(SDL_Window* window)
{
SDL_SysWMinfo wminfo;
SDL_VERSION(&wminfo.version);
const int ret = SDL_GetWindowWMInfo(window, &wminfo);
if (ret && wminfo.subsystem == SDL_SYSWM_WAYLAND)
{
return reinterpret_cast<void*>(wminfo.info.wl.display);
}
return nullptr;
}
#endif
const char* GetSDLSubsystem(SDL_Window* window)
{
SDL_SysWMinfo wminfo;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2021 Wildfire Games.
/* Copyright (C) 2022 Wildfire Games.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -61,4 +61,8 @@ const char* GetSDLSubsystem(SDL_Window* window);
void* GetX11Display(SDL_Window* window);
#endif
#if defined(SDL_VIDEO_DRIVER_WAYLAND) && !CONFIG2_GLES
void* GetWaylandDisplay(SDL_Window* window);
#endif
#endif // INCLUDED_SDL

View File

@ -31,12 +31,20 @@
#include "ps/CLogger.h"
#if !CONFIG2_GLES
# if OS_WIN
# include <glad/wgl.h>
# elif !OS_MACOSX && !OS_MAC
# include <glad/glx.h>
# include <SDL_syswm.h>
# if defined(SDL_VIDEO_DRIVER_X11)
# include <glad/glx.h>
# endif
# if defined(SDL_VIDEO_DRIVER_WAYLAND)
# include <glad/egl.h>
# endif
# endif
#endif
#endif // !CONFIG2_GLES
#include <stdio.h>
#include <string.h>
@ -213,8 +221,13 @@ static int GLVersion;
#if OS_WIN
static int WGLVersion;
#elif !CONFIG2_GLES && !OS_MACOSX && !OS_MAC
#if defined(SDL_VIDEO_DRIVER_X11)
static int GLXVersion;
#endif
#if defined(SDL_VIDEO_DRIVER_WAYLAND)
static int EGLVersion;
#endif
#endif
bool ogl_HaveVersion(int major, int minor)
{
@ -416,7 +429,7 @@ bool ogl_SquelchError(GLenum err_to_ignore)
#if OS_WIN
bool ogl_Init(void* (load)(const char*), void* hdc)
#elif !CONFIG2_GLES && !OS_MACOSX && !OS_MAC
bool ogl_Init(void* (load)(const char*), void* display)
bool ogl_Init(void* (load)(const char*), void* display, int subsystem)
#else
bool ogl_Init(void* (load)(const char*))
#endif
@ -446,12 +459,33 @@ bool ogl_Init(void* (load)(const char*))
return false;
}
# elif !OS_MACOSX && !OS_MAC
GLXVersion = gladLoadGLX(reinterpret_cast<Display*>(display), DefaultScreen(display), loadFunc);
if (!GLXVersion)
const SDL_SYSWM_TYPE sysWMType = static_cast<SDL_SYSWM_TYPE>(subsystem);
# if defined(SDL_VIDEO_DRIVER_X11)
if (sysWMType == SDL_SYSWM_X11)
{
LOAD_ERROR("Failed to load GLX functions.");
return false;
GLXVersion = gladLoadGLX(reinterpret_cast<Display*>(display), DefaultScreen(display), loadFunc);
if (!GLXVersion)
{
LOAD_ERROR("Failed to load GLX functions.");
return false;
}
}
# endif
# if defined(SDL_VIDEO_DRIVER_WAYLAND)
if (sysWMType == SDL_SYSWM_WAYLAND)
{
// TODO: investiage do we need Wayland display to load EGL.
// Because without eglGetDisplay we can't get one. But the
// function is loaded inside gladLoadEGL. So maybe we need to
// call it twice.
EGLVersion = gladLoadEGL(nullptr, loadFunc);
if (!EGLVersion)
{
LOAD_ERROR("Failed to load EGL functions.");
return false;
}
}
# endif
# endif
#else
GLVersion = gladLoadGLES2(loadFunc);
@ -484,15 +518,18 @@ bool ogl_Init(void* (load)(const char*))
void ogl_SetVsyncEnabled(bool enabled)
{
const int interval = enabled ? 1 : 0;
#if !CONFIG2_GLES && OS_WIN
int interval = enabled ? 1 : 0;
if (ogl_HaveExtension("WGL_EXT_swap_control"))
wglSwapIntervalEXT(interval);
#elif !CONFIG2_GLES && !OS_MACOSX && !OS_MAC
int interval = enabled ? 1 : 0;
if (ogl_HaveExtension("GLX_SGI_swap_control"))
#if defined(SDL_VIDEO_DRIVER_X11)
if (GLXVersion && ogl_HaveExtension("GLX_SGI_swap_control"))
glXSwapIntervalSGI(interval);
#else
UNUSED2(enabled);
UNUSED2(interval);
#endif
#else
UNUSED2(interval);
#endif
}

View File

@ -41,11 +41,12 @@
* initialization: import extension function pointers and do feature detect.
* call before using any other function.
* fails if OpenGL not ready for use.
* TODO: move loading functionality to GL backend.
**/
#if OS_WIN
extern bool ogl_Init(void* (load)(const char*), void* hdc);
#elif !OS_MACOSX && !OS_MAC && !CONFIG2_GLES
extern bool ogl_Init(void* (load)(const char*), void* display);
extern bool ogl_Init(void* (load)(const char*), void* display, int subsystem);
#else
extern bool ogl_Init(void* (load)(const char*));
#endif

View File

@ -43,11 +43,17 @@ extern void* wutil_GetAppHDC();
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
// TODO: Support OpenGL platforms which don't use GLX as well.
#if defined(SDL_VIDEO_DRIVER_X11) && !CONFIG2_GLES
#if !CONFIG2_GLES && (defined(SDL_VIDEO_DRIVER_X11) || defined(SDL_VIDEO_DRIVER_WAYLAND))
#if defined(SDL_VIDEO_DRIVER_X11)
#include <glad/glx.h>
#include <SDL_syswm.h>
#endif
#if defined(SDL_VIDEO_DRIVER_WAYLAND)
#include <glad/egl.h>
#endif
#include <SDL_syswm.h>
#endif // !CONFIG2_GLES && (defined(SDL_VIDEO_DRIVER_X11) || defined(SDL_VIDEO_DRIVER_WAYLAND))
namespace Renderer
{
@ -236,8 +242,38 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window, const bool arb)
}
#if OS_WIN
ogl_Init(SDL_GL_GetProcAddress, wutil_GetAppHDC());
#elif defined(SDL_VIDEO_DRIVER_X11) && !CONFIG2_GLES
ogl_Init(SDL_GL_GetProcAddress, GetX11Display(device->m_Window));
#elif (defined(SDL_VIDEO_DRIVER_X11) || defined(SDL_VIDEO_DRIVER_WAYLAND)) && !CONFIG2_GLES
SDL_SysWMinfo wminfo;
// The info structure must be initialized with the SDL version.
SDL_VERSION(&wminfo.version);
if (!SDL_GetWindowWMInfo(window, &wminfo))
{
LOGERROR("Failed to query SDL WM info: %s", SDL_GetError());
return nullptr;
}
switch (wminfo.subsystem)
{
#if defined(SDL_VIDEO_DRIVER_WAYLAND)
case SDL_SYSWM_WAYLAND:
// TODO: maybe we need to load X11 functions
// dynamically as well.
ogl_Init(SDL_GL_GetProcAddress,
GetWaylandDisplay(device->m_Window),
static_cast<int>(wminfo.subsystem));
break;
#endif
#if defined(SDL_VIDEO_DRIVER_X11)
case SDL_SYSWM_X11:
ogl_Init(SDL_GL_GetProcAddress,
GetX11Display(device->m_Window),
static_cast<int>(wminfo.subsystem));
break;
#endif
default:
ogl_Init(SDL_GL_GetProcAddress, nullptr,
static_cast<int>(wminfo.subsystem));
break;
}
#else
ogl_Init(SDL_GL_GetProcAddress);
#endif
@ -246,8 +282,31 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window, const bool arb)
{
#if OS_WIN
ogl_Init(SDL_GL_GetProcAddress, wutil_GetAppHDC());
#elif defined(SDL_VIDEO_DRIVER_X11) && !CONFIG2_GLES
ogl_Init(SDL_GL_GetProcAddress, XOpenDisplay(NULL));
#elif (defined(SDL_VIDEO_DRIVER_X11) || defined(SDL_VIDEO_DRIVER_WAYLAND)) && !CONFIG2_GLES
bool initialized = false;
// Currently we don't have access to the backend type without
// the window. So we use hack to detect X11.
#if defined(SDL_VIDEO_DRIVER_X11)
Display* display = XOpenDisplay(NULL);
if (display)
{
ogl_Init(SDL_GL_GetProcAddress, display, static_cast<int>(SDL_SYSWM_X11));
initialized = true;
}
#endif
#if defined(SDL_VIDEO_DRIVER_WAYLAND)
if (!initialized)
{
// glad will find default EGLDisplay internally.
ogl_Init(SDL_GL_GetProcAddress, nullptr, static_cast<int>(SDL_SYSWM_WAYLAND));
initialized = true;
}
#endif
if (!initialized)
{
LOGERROR("Can't initialize GL");
return nullptr;
}
#else
ogl_Init(SDL_GL_GetProcAddress);
#endif