Revert "Use EGL over GLX" (#15315)

This reverts commit aa273119f292e52df8d99f663df5337bac31556d.
This commit is contained in:
sfan5 2024-10-24 17:52:06 +02:00 committed by GitHub
parent e441b5d240
commit 2d135cc1bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 539 additions and 127 deletions

@ -40,26 +40,29 @@ bool CEGLManager::initialize(const SIrrlichtCreationParameters &params, const SE
if (EglWindow != 0 && EglDisplay != EGL_NO_DISPLAY)
return true;
// Window is depend on platform.
setWindow(Data);
// Window is depend on platform.
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
EglWindow = (NativeWindowType)Data.OpenGLWin32.HWnd;
Data.OpenGLWin32.HDc = GetDC((HWND)EglWindow);
EglDisplay = eglGetDisplay((NativeDisplayType)Data.OpenGLWin32.HDc);
#elif defined(_IRR_EMSCRIPTEN_PLATFORM_)
EglWindow = 0;
EglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
EglWindow = (NativeWindowType)Data.OpenGLLinux.X11Window;
EglDisplay = eglGetDisplay((NativeDisplayType)Data.OpenGLLinux.X11Display);
#endif
// We must check if EGL display is valid.
if (EglDisplay == EGL_NO_DISPLAY) {
os::Printer::log("Could not get EGL display.", ELL_ERROR);
os::Printer::log("Could not get EGL display.");
terminate();
return false;
}
// Initialize EGL here.
if (!eglInitialize(EglDisplay, &MajorVersion, &MinorVersion)) {
os::Printer::log("Could not initialize EGL display.", ELL_ERROR);
os::Printer::log("Could not initialize EGL display.");
EglDisplay = EGL_NO_DISPLAY;
terminate();
@ -70,22 +73,6 @@ bool CEGLManager::initialize(const SIrrlichtCreationParameters &params, const SE
return true;
}
void CEGLManager::setWindow(const SExposedVideoData &inData)
{
#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
Data.OpenGLWin32.HWnd = inData.OpenGLWin32.HWnd;
if (Data.OpenGLWin32.HWnd) {
EglWindow = (NativeWindowType)Data.OpenGLWin32.HWnd;
Data.OpenGLWin32.HDc = GetDC((HWND)EglWindow);
}
#elif defined(_IRR_EMSCRIPTEN_PLATFORM_)
EglWindow = 0;
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
Data.OpenGLLinux.X11Window = inData.OpenGLLinux.X11Window;
EglWindow = (NativeWindowType)Data.OpenGLLinux.X11Window;
#endif
}
void CEGLManager::terminate()
{
if (EglWindow == 0 && EglDisplay == EGL_NO_DISPLAY)
@ -118,16 +105,20 @@ bool CEGLManager::generateSurface()
if (EglSurface != EGL_NO_SURFACE)
return true;
if (!EglConfig) {
#if defined(_IRR_EMSCRIPTEN_PLATFORM_)
EglConfig = chooseConfig(ECS_IRR_CHOOSE);
#else
EglConfig = chooseConfig(ECS_EGL_CHOOSE_FIRST_LOWER_EXPECTATIONS);
#endif
}
// We should assign new WindowID on platforms, where WindowID may change at runtime,
// at this time only Android support this feature.
// this needs an update method instead!
if (!EglConfig) {
os::Printer::log("Could not choose EGL config.", ELL_ERROR);
#if defined(_IRR_EMSCRIPTEN_PLATFORM_)
// eglChooseConfig is currently only implemented as stub in emscripten (version 1.37.22 at point of writing)
// But the other solution would also be fine as it also only generates a single context so there is not much to choose from.
EglConfig = chooseConfig(ECS_IRR_CHOOSE);
#else
EglConfig = chooseConfig(ECS_EGL_CHOOSE_FIRST_LOWER_EXPECTATIONS);
#endif
if (EglConfig == 0) {
os::Printer::log("Could not get config for EGL display.");
return false;
}
@ -138,26 +129,11 @@ bool CEGLManager::generateSurface()
EglSurface = eglCreateWindowSurface(EglDisplay, EglConfig, 0, 0);
if (EGL_NO_SURFACE == EglSurface)
os::Printer::log("Could not create EGL surface.", ELL_ERROR);
os::Printer::log("Could not create EGL surface.");
#ifdef EGL_VERSION_1_2
if (MinorVersion > 1) {
EGLBoolean ok = 0;
switch (Params.DriverType) {
case EDT_OGLES2:
case EDT_WEBGL1:
ok = eglBindAPI(EGL_OPENGL_ES_API);
break;
case EDT_OPENGL:
ok = eglBindAPI(EGL_OPENGL_API);
default:
break;
}
if (!ok) {
os::Printer::log("Could not bind EGL API.", ELL_ERROR);
return false;
}
}
if (MinorVersion > 1)
eglBindAPI(EGL_OPENGL_ES_API);
#endif
if (Params.Vsync)
@ -166,26 +142,6 @@ bool CEGLManager::generateSurface()
return true;
}
EGLint CEGLManager::getNativeVisualID()
{
if (!EglConfig) {
#if defined(_IRR_EMSCRIPTEN_PLATFORM_)
EglConfig = chooseConfig(ECS_IRR_CHOOSE);
#else
EglConfig = chooseConfig(ECS_EGL_CHOOSE_FIRST_LOWER_EXPECTATIONS);
#endif
}
if (!EglConfig) {
os::Printer::log("Could not choose EGL config.", ELL_WARNING);
return 0;
}
EGLint ret = 0;
eglGetConfigAttrib(EglDisplay, EglConfig, EGL_NATIVE_VISUAL_ID, &ret);
return ret;
}
EGLConfig CEGLManager::chooseConfig(EConfigStyle confStyle)
{
EGLConfig configResult = 0;
@ -197,8 +153,6 @@ EGLConfig CEGLManager::chooseConfig(EConfigStyle confStyle)
case EDT_WEBGL1:
eglOpenGLBIT = EGL_OPENGL_ES2_BIT;
break;
case EDT_OPENGL:
eglOpenGLBIT = EGL_OPENGL_BIT;
default:
break;
}
@ -339,8 +293,6 @@ EGLConfig CEGLManager::chooseConfig(EConfigStyle confStyle)
}
delete[] configs;
} else {
_IRR_DEBUG_BREAK_IF(1)
}
return configResult;
@ -498,36 +450,33 @@ bool CEGLManager::generateContext()
if (EglContext != EGL_NO_CONTEXT)
return true;
std::vector<EGLint> ContextAttrib;
EGLint OpenGLESVersion = 0;
switch (Params.DriverType) {
case EDT_OGLES2:
case EDT_WEBGL1:
#ifdef EGL_VERSION_1_3
ContextAttrib.push_back(EGL_CONTEXT_CLIENT_VERSION);
ContextAttrib.push_back(2);
#endif
break;
case EDT_OPENGL:
#ifdef EGL_VERSION_1_5
ContextAttrib.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK);
ContextAttrib.push_back(EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT);
#endif
OpenGLESVersion = 2;
break;
default:
break;
}
ContextAttrib.push_back(EGL_NONE);
ContextAttrib.push_back(0);
EGLint ContextAttrib[] = {
#ifdef EGL_VERSION_1_3
EGL_CONTEXT_CLIENT_VERSION, OpenGLESVersion,
#endif
EGL_NONE, 0,
};
EglContext = eglCreateContext(EglDisplay, EglConfig, EGL_NO_CONTEXT, ContextAttrib.data());
EglContext = eglCreateContext(EglDisplay, EglConfig, EGL_NO_CONTEXT, ContextAttrib);
if (testEGLError()) {
os::Printer::log("Could not create EGL context.", ELL_ERROR);
return false;
}
os::Printer::log("EGL context created with OpenGLESVersion: ", core::stringc((int)OpenGLESVersion), ELL_DEBUG);
return true;
}

@ -31,10 +31,6 @@ public:
aren't create. */
bool initialize(const SIrrlichtCreationParameters &params, const SExposedVideoData &data) override;
// Set EGL window.
// Call this if window is not known at time of initialize()
void setWindow(const SExposedVideoData &data);
// Terminate EGL.
/* Terminate EGL context. This method break both existed surface and context. */
void terminate() override;
@ -70,9 +66,6 @@ public:
// Swap buffers.
bool swapBuffers() override;
// Returns native visual ID. Will choose config if not already done.
EGLint getNativeVisualID();
protected:
enum EConfigStyle
{

401
irr/src/CGLXManager.cpp Normal file

@ -0,0 +1,401 @@
// Copyright (C) 2013 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "CGLXManager.h"
#ifdef _IRR_COMPILE_WITH_GLX_MANAGER_
#include "os.h"
#define GL_GLEXT_LEGACY 1
#define GLX_GLXEXT_LEGACY 1
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glext.h>
#include <GL/glxext.h>
namespace irr
{
namespace video
{
CGLXManager::CGLXManager(const SIrrlichtCreationParameters &params, const SExposedVideoData &videodata, int screennr) :
Params(params), PrimaryContext(videodata), VisualInfo(0), glxFBConfig(0), GlxWin(0)
{
#ifdef _DEBUG
setDebugName("CGLXManager");
#endif
CurrentContext.OpenGLLinux.X11Display = PrimaryContext.OpenGLLinux.X11Display;
int major, minor;
Display *display = (Display *)PrimaryContext.OpenGLLinux.X11Display;
const bool isAvailableGLX = glXQueryExtension(display, &major, &minor);
if (isAvailableGLX && glXQueryVersion(display, &major, &minor)) {
#if defined(GLX_VERSION_1_3)
typedef GLXFBConfig *(*PFNGLXCHOOSEFBCONFIGPROC)(Display *dpy, int screen, const int *attrib_list, int *nelements);
PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte *>("glXChooseFBConfig"));
if (major == 1 && minor > 2 && glxChooseFBConfig) {
os::Printer::log("GLX >= 1.3", ELL_DEBUG);
// attribute array for the draw buffer
int visualAttrBuffer[] = {
GLX_RENDER_TYPE,
GLX_RGBA_BIT,
GLX_RED_SIZE,
4,
GLX_GREEN_SIZE,
4,
GLX_BLUE_SIZE,
4,
GLX_ALPHA_SIZE,
Params.WithAlphaChannel ? 1 : 0,
GLX_DEPTH_SIZE,
Params.ZBufferBits, // 10,11
GLX_DOUBLEBUFFER,
Params.Doublebuffer ? True : False,
GLX_STENCIL_SIZE,
Params.Stencilbuffer ? 1 : 0,
#if defined(GLX_VERSION_1_4) && defined(GLX_SAMPLE_BUFFERS) // we need to check the extension string!
GLX_SAMPLE_BUFFERS,
1,
GLX_SAMPLES,
Params.AntiAlias, // 18,19
#elif defined(GLX_ARB_multisample)
GLX_SAMPLE_BUFFERS_ARB,
1,
GLX_SAMPLES_ARB,
Params.AntiAlias, // 18,19
#elif defined(GLX_SGIS_multisample)
GLX_SAMPLE_BUFFERS_SGIS,
1,
GLX_SAMPLES_SGIS,
Params.AntiAlias, // 18,19
#endif
GLX_STEREO,
Params.Stereobuffer ? True : False,
None,
};
GLXFBConfig *configList = 0;
int nitems = 0;
if (Params.AntiAlias < 2) {
visualAttrBuffer[17] = 0;
visualAttrBuffer[19] = 0;
}
// first round with unchanged values
{
configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
if (!configList && Params.AntiAlias) {
while (!configList && (visualAttrBuffer[19] > 1)) {
visualAttrBuffer[19] -= 1;
configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
}
if (!configList) {
visualAttrBuffer[17] = 0;
visualAttrBuffer[19] = 0;
configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
if (configList) {
os::Printer::log("No FSAA available.", ELL_WARNING);
Params.AntiAlias = 0;
} else {
// reenable multisampling
visualAttrBuffer[17] = 1;
visualAttrBuffer[19] = Params.AntiAlias;
}
}
}
}
// Next try with flipped stencil buffer value
// If the first round was with stencil flag it's now without
// Other way round also makes sense because some configs
// only have depth buffer combined with stencil buffer
if (!configList) {
if (Params.Stencilbuffer)
os::Printer::log("No stencilbuffer available, disabling stencil shadows.", ELL_WARNING);
Params.Stencilbuffer = !Params.Stencilbuffer;
visualAttrBuffer[15] = Params.Stencilbuffer ? 1 : 0;
configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
if (!configList && Params.AntiAlias) {
while (!configList && (visualAttrBuffer[19] > 1)) {
visualAttrBuffer[19] -= 1;
configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
}
if (!configList) {
visualAttrBuffer[17] = 0;
visualAttrBuffer[19] = 0;
configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
if (configList) {
os::Printer::log("No FSAA available.", ELL_WARNING);
Params.AntiAlias = 0;
} else {
// reenable multisampling
visualAttrBuffer[17] = 1;
visualAttrBuffer[19] = Params.AntiAlias;
}
}
}
}
// Next try without double buffer
if (!configList && Params.Doublebuffer) {
os::Printer::log("No doublebuffering available.", ELL_WARNING);
Params.Doublebuffer = false;
visualAttrBuffer[13] = GLX_DONT_CARE;
Params.Stencilbuffer = false;
visualAttrBuffer[15] = 0;
configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
if (!configList && Params.AntiAlias) {
while (!configList && (visualAttrBuffer[19] > 1)) {
visualAttrBuffer[19] -= 1;
configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
}
if (!configList) {
visualAttrBuffer[17] = 0;
visualAttrBuffer[19] = 0;
configList = glxChooseFBConfig(display, screennr, visualAttrBuffer, &nitems);
if (configList) {
os::Printer::log("No FSAA available.", ELL_WARNING);
Params.AntiAlias = 0;
} else {
// reenable multisampling
visualAttrBuffer[17] = 1;
visualAttrBuffer[19] = Params.AntiAlias;
}
}
}
}
if (configList) {
glxFBConfig = configList[0];
XFree(configList);
typedef XVisualInfo *(*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display *dpy, GLXFBConfig config);
PFNGLXGETVISUALFROMFBCONFIGPROC glxGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte *>("glXGetVisualFromFBConfig"));
if (glxGetVisualFromFBConfig)
VisualInfo = glxGetVisualFromFBConfig(display, (GLXFBConfig)glxFBConfig);
}
} else
#endif
{
// attribute array for the draw buffer
int visualAttrBuffer[] = {
GLX_RGBA, GLX_USE_GL,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_ALPHA_SIZE, Params.WithAlphaChannel ? 1 : 0,
GLX_DEPTH_SIZE, Params.ZBufferBits,
GLX_STENCIL_SIZE, Params.Stencilbuffer ? 1 : 0, // 12,13
// The following attributes have no flags, but are
// either present or not. As a no-op we use
// GLX_USE_GL, which is silently ignored by glXChooseVisual
Params.Doublebuffer ? GLX_DOUBLEBUFFER : GLX_USE_GL, // 14
Params.Stereobuffer ? GLX_STEREO : GLX_USE_GL, // 15
None,
};
VisualInfo = glXChooseVisual(display, screennr, visualAttrBuffer);
if (!VisualInfo) {
if (Params.Stencilbuffer)
os::Printer::log("No stencilbuffer available, disabling.", ELL_WARNING);
Params.Stencilbuffer = !Params.Stencilbuffer;
visualAttrBuffer[13] = Params.Stencilbuffer ? 1 : 0;
VisualInfo = glXChooseVisual(display, screennr, visualAttrBuffer);
if (!VisualInfo && Params.Doublebuffer) {
os::Printer::log("No doublebuffering available.", ELL_WARNING);
Params.Doublebuffer = false;
visualAttrBuffer[14] = GLX_USE_GL;
VisualInfo = glXChooseVisual(display, screennr, visualAttrBuffer);
}
}
}
} else
os::Printer::log("No GLX support available. OpenGL driver will not work.", ELL_WARNING);
}
CGLXManager::~CGLXManager()
{
}
bool CGLXManager::initialize(const SIrrlichtCreationParameters &params, const SExposedVideoData &videodata)
{
// store params
Params = params;
// set display
CurrentContext.OpenGLLinux.X11Display = videodata.OpenGLLinux.X11Display;
// now get new window
CurrentContext.OpenGLLinux.X11Window = videodata.OpenGLLinux.X11Window;
if (!PrimaryContext.OpenGLLinux.X11Window) {
PrimaryContext.OpenGLLinux.X11Window = CurrentContext.OpenGLLinux.X11Window;
}
return true;
}
void CGLXManager::terminate()
{
memset((void *)&CurrentContext, 0, sizeof(CurrentContext));
}
bool CGLXManager::generateSurface()
{
if (glxFBConfig) {
GlxWin = glXCreateWindow((Display *)CurrentContext.OpenGLLinux.X11Display, (GLXFBConfig)glxFBConfig, CurrentContext.OpenGLLinux.X11Window, NULL);
if (!GlxWin) {
os::Printer::log("Could not create GLX window.", ELL_WARNING);
return false;
}
CurrentContext.OpenGLLinux.GLXWindow = GlxWin;
} else {
CurrentContext.OpenGLLinux.GLXWindow = CurrentContext.OpenGLLinux.X11Window;
}
return true;
}
void CGLXManager::destroySurface()
{
if (GlxWin)
glXDestroyWindow((Display *)CurrentContext.OpenGLLinux.X11Display, GlxWin);
}
#if defined(GLX_ARB_create_context)
static int IrrIgnoreError(Display *display, XErrorEvent *event)
{
char msg[256];
XGetErrorText(display, event->error_code, msg, 256);
os::Printer::log("Ignoring an X error", msg, ELL_DEBUG);
return 0;
}
#endif
bool CGLXManager::generateContext()
{
GLXContext context = 0;
if (glxFBConfig) {
if (GlxWin) {
#if defined(GLX_ARB_create_context)
PFNGLXCREATECONTEXTATTRIBSARBPROC glxCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress(reinterpret_cast<const GLubyte *>("glXCreateContextAttribsARB"));
if (glxCreateContextAttribsARB) {
os::Printer::log("GLX with GLX_ARB_create_context", ELL_DEBUG);
int contextAttrBuffer[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
// GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
None};
XErrorHandler old = XSetErrorHandler(IrrIgnoreError);
context = glxCreateContextAttribsARB((Display *)CurrentContext.OpenGLLinux.X11Display, (GLXFBConfig)glxFBConfig, NULL, True, contextAttrBuffer);
XSetErrorHandler(old);
// transparently fall back to legacy call
}
if (!context)
#endif
{
// create glx context
context = glXCreateNewContext((Display *)CurrentContext.OpenGLLinux.X11Display, (GLXFBConfig)glxFBConfig, GLX_RGBA_TYPE, NULL, True);
if (!context) {
os::Printer::log("Could not create GLX rendering context.", ELL_WARNING);
return false;
}
}
} else {
os::Printer::log("GLX window was not properly created.", ELL_WARNING);
return false;
}
} else {
context = glXCreateContext((Display *)CurrentContext.OpenGLLinux.X11Display, VisualInfo, NULL, True);
if (!context) {
os::Printer::log("Could not create GLX rendering context.", ELL_WARNING);
return false;
}
}
CurrentContext.OpenGLLinux.X11Context = context;
return true;
}
const SExposedVideoData &CGLXManager::getContext() const
{
return CurrentContext;
}
bool CGLXManager::activateContext(const SExposedVideoData &videoData, bool restorePrimaryOnZero)
{
// TODO: handle restorePrimaryOnZero
if (videoData.OpenGLLinux.X11Window) {
if (videoData.OpenGLLinux.X11Display && videoData.OpenGLLinux.X11Context) {
if (!glXMakeCurrent((Display *)videoData.OpenGLLinux.X11Display, videoData.OpenGLLinux.GLXWindow, (GLXContext)videoData.OpenGLLinux.X11Context)) {
os::Printer::log("Context activation failed.");
return false;
} else {
CurrentContext.OpenGLLinux.GLXWindow = videoData.OpenGLLinux.GLXWindow;
CurrentContext.OpenGLLinux.X11Window = videoData.OpenGLLinux.X11Window;
CurrentContext.OpenGLLinux.X11Display = videoData.OpenGLLinux.X11Display;
}
} else {
// in case we only got a window ID, try with the existing values for display and context
if (!glXMakeCurrent((Display *)PrimaryContext.OpenGLLinux.X11Display, videoData.OpenGLLinux.GLXWindow, (GLXContext)PrimaryContext.OpenGLLinux.X11Context)) {
os::Printer::log("Context activation failed.");
return false;
} else {
CurrentContext.OpenGLLinux.GLXWindow = videoData.OpenGLLinux.GLXWindow;
CurrentContext.OpenGLLinux.X11Window = videoData.OpenGLLinux.X11Window;
CurrentContext.OpenGLLinux.X11Display = PrimaryContext.OpenGLLinux.X11Display;
}
}
} else if (!restorePrimaryOnZero && !videoData.OpenGLLinux.X11Window && !videoData.OpenGLLinux.X11Display) {
if (!glXMakeCurrent((Display *)PrimaryContext.OpenGLLinux.X11Display, None, NULL)) {
os::Printer::log("Render Context reset failed.");
return false;
}
CurrentContext.OpenGLLinux.X11Window = 0;
CurrentContext.OpenGLLinux.X11Display = 0;
}
// set back to main context
else if (CurrentContext.OpenGLLinux.X11Display != PrimaryContext.OpenGLLinux.X11Display) {
if (!glXMakeCurrent((Display *)PrimaryContext.OpenGLLinux.X11Display, PrimaryContext.OpenGLLinux.X11Window, (GLXContext)PrimaryContext.OpenGLLinux.X11Context)) {
os::Printer::log("Context activation failed.");
return false;
} else {
CurrentContext = PrimaryContext;
}
}
return true;
}
void CGLXManager::destroyContext()
{
if (CurrentContext.OpenGLLinux.X11Context) {
if (GlxWin) {
if (!glXMakeContextCurrent((Display *)CurrentContext.OpenGLLinux.X11Display, None, None, NULL))
os::Printer::log("Could not release glx context.", ELL_WARNING);
} else {
if (!glXMakeCurrent((Display *)CurrentContext.OpenGLLinux.X11Display, None, NULL))
os::Printer::log("Could not release glx context.", ELL_WARNING);
}
glXDestroyContext((Display *)CurrentContext.OpenGLLinux.X11Display, (GLXContext)CurrentContext.OpenGLLinux.X11Context);
}
}
void *CGLXManager::getProcAddress(const std::string &procName)
{
return (void *)glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.c_str()));
}
bool CGLXManager::swapBuffers()
{
glXSwapBuffers((Display *)CurrentContext.OpenGLLinux.X11Display, CurrentContext.OpenGLLinux.GLXWindow);
return true;
}
}
}
#endif

76
irr/src/CGLXManager.h Normal file

@ -0,0 +1,76 @@
// Copyright (C) 2013 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#pragma once
#ifdef _IRR_COMPILE_WITH_GLX_MANAGER_
#include "SIrrCreationParameters.h"
#include "SExposedVideoData.h"
#include "IContextManager.h"
#include "SColor.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
// we can't include glx.h here, because gl.h has incompatible types with ogl es headers and it
// cause redefinition errors, thats why we use ugly trick with void* types and casts.
namespace irr
{
namespace video
{
// GLX manager.
class CGLXManager : public IContextManager
{
public:
//! Constructor.
CGLXManager(const SIrrlichtCreationParameters &params, const SExposedVideoData &videodata, int screennr);
//! Destructor
~CGLXManager();
// Initialize
bool initialize(const SIrrlichtCreationParameters &params, const SExposedVideoData &data) override;
// Terminate
void terminate() override;
// Create surface.
bool generateSurface() override;
// Destroy surface.
void destroySurface() override;
// Create context.
bool generateContext() override;
// Destroy context.
void destroyContext() override;
//! Get current context
const SExposedVideoData &getContext() const override;
//! Change render context, disable old and activate new defined by videoData
bool activateContext(const SExposedVideoData &videoData, bool restorePrimaryOnZero) override;
// Get procedure address.
void *getProcAddress(const std::string &procName) override;
// Swap buffers.
bool swapBuffers() override;
XVisualInfo *getVisual() const { return VisualInfo; } // return XVisualInfo
private:
SIrrlichtCreationParameters Params;
SExposedVideoData PrimaryContext;
SExposedVideoData CurrentContext;
XVisualInfo *VisualInfo;
void *glxFBConfig; // GLXFBConfig
XID GlxWin; // GLXWindow
};
}
}
#endif

@ -34,10 +34,14 @@
#include <X11/extensions/XInput2.h>
#endif
#if defined(_IRR_COMPILE_WITH_OPENGL_) || defined(_IRR_COMPILE_WITH_OGLES2_)
#if defined(_IRR_COMPILE_WITH_OGLES2_)
#include "CEGLManager.h"
#endif
#if defined(_IRR_COMPILE_WITH_OPENGL_)
#include "CGLXManager.h"
#endif
#ifdef _IRR_LINUX_XCURSOR_
#include <X11/Xcursor/Xcursor.h>
#endif
@ -148,20 +152,8 @@ CIrrDeviceLinux::CIrrDeviceLinux(const SIrrlichtCreationParameters &param) :
// without it, multi-threaded GL drivers may crash
XInitThreads();
// create window
if (CreationParams.DriverType != video::EDT_NULL) {
// initialize EGL so it can choose a config
#ifdef _IRR_COMPILE_WITH_X11_
#if defined(_IRR_COMPILE_WITH_OPENGL_) || defined(_IRR_COMPILE_WITH_OGLES2_)
video::SExposedVideoData data;
data.OpenGLLinux.X11Window = 0; // not created yet, but that's ok
data.OpenGLLinux.X11Display = XDisplay;
ContextManager = new video::CEGLManager();
if (!ContextManager->initialize(CreationParams, data))
return;
#endif
#endif
// create the window, only if we do not use the null device
if (!createWindow())
return;
@ -405,14 +397,14 @@ bool CIrrDeviceLinux::createWindow()
if (WMCheck != None)
HasNetWM = true;
#if defined(_IRR_COMPILE_WITH_OPENGL_) || defined(_IRR_COMPILE_WITH_OGLES2_)
if (ContextManager) {
auto *c = static_cast<video::CEGLManager*>(ContextManager);
os::Printer::log("Using X visual from EGL");
XVisualInfo templ;
int n;
templ.visualid = static_cast<VisualID>(c->getNativeVisualID());
VisualInfo = XGetVisualInfo(XDisplay, VisualIDMask, &templ, &n);
#if defined(_IRR_COMPILE_WITH_OPENGL_)
// don't use the XVisual with OpenGL, because it ignores all requested
// properties of the CreationParams
if (CreationParams.DriverType == video::EDT_OPENGL) {
video::SExposedVideoData data;
data.OpenGLLinux.X11Display = XDisplay;
ContextManager = new video::CGLXManager(CreationParams, data, Screennr);
VisualInfo = ((video::CGLXManager *)ContextManager)->getVisual();
}
#endif
@ -551,7 +543,9 @@ void CIrrDeviceLinux::createDriver()
{
video::SExposedVideoData data;
data.OpenGLLinux.X11Window = XWindow;
static_cast<video::CEGLManager*>(ContextManager)->setWindow(data);
data.OpenGLLinux.X11Display = XDisplay;
ContextManager->initialize(CreationParams, data);
VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, ContextManager);
}
@ -564,7 +558,10 @@ void CIrrDeviceLinux::createDriver()
{
video::SExposedVideoData data;
data.OpenGLLinux.X11Window = XWindow;
static_cast<video::CEGLManager*>(ContextManager)->setWindow(data);
data.OpenGLLinux.X11Display = XDisplay;
ContextManager = new video::CEGLManager();
ContextManager->initialize(CreationParams, data);
VideoDriver = video::createOGLES2Driver(CreationParams, FileSystem, ContextManager);
}
@ -577,7 +574,10 @@ void CIrrDeviceLinux::createDriver()
{
video::SExposedVideoData data;
data.OpenGLLinux.X11Window = XWindow;
static_cast<video::CEGLManager*>(ContextManager)->setWindow(data);
data.OpenGLLinux.X11Display = XDisplay;
ContextManager = new video::CEGLManager();
ContextManager->initialize(CreationParams, data);
VideoDriver = video::createWebGL1Driver(CreationParams, FileSystem, ContextManager);
}

@ -158,7 +158,7 @@ if(ENABLE_OPENGL)
if(DEVICE STREQUAL "WINDOWS")
add_definitions(-D_IRR_COMPILE_WITH_WGL_MANAGER_)
elseif(DEVICE STREQUAL "X11")
add_definitions(-D_IRR_COMPILE_WITH_EGL_MANAGER_)
add_definitions(-D_IRR_COMPILE_WITH_GLX_MANAGER_)
elseif(DEVICE STREQUAL "OSX")
add_definitions(-D_IRR_COMPILE_WITH_NSOGL_MANAGER_)
endif()
@ -213,15 +213,7 @@ if(ENABLE_GLES2)
find_package(OpenGLES2 REQUIRED)
endif()
if(ENABLE_OPENGL)
if(DEVICE STREQUAL "X11")
# use components so we can grab EGL
find_package(OpenGL REQUIRED COMPONENTS EGL OpenGL)
set(OPENGL_LIBRARIES OpenGL::GL)
set(EGL_INCLUDE_DIR OpenGL::EGL)
set(EGL_LIBRARY OpenGL::EGL)
else()
find_package(OpenGL REQUIRED)
endif()
find_package(OpenGL REQUIRED)
endif()
if(USE_SDL2)
if(NOT ANDROID)
@ -338,6 +330,7 @@ target_link_libraries(IRROBJ PRIVATE IRRMESHOBJ)
set(IRRDRVROBJ
CNullDriver.cpp
CGLXManager.cpp
CWGLManager.cpp
CEGLManager.cpp
CSDLManager.cpp