mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 22:29:39 -06:00
Reformat all the things. Have fun with merge conflicts.
This commit is contained in:
@ -7,191 +7,195 @@
|
||||
#include "Common/GL/GLInterface/GLX.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
|
||||
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
|
||||
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSPROC)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
|
||||
typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval);
|
||||
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSPROC)(Display*, GLXFBConfig, GLXContext, Bool,
|
||||
const int*);
|
||||
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int interval);
|
||||
|
||||
static PFNGLXCREATECONTEXTATTRIBSPROC glXCreateContextAttribs = nullptr;
|
||||
static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr;
|
||||
|
||||
static bool s_glxError;
|
||||
static int ctxErrorHandler(Display *dpy, XErrorEvent *ev)
|
||||
static int ctxErrorHandler(Display* dpy, XErrorEvent* ev)
|
||||
{
|
||||
s_glxError = true;
|
||||
return 0;
|
||||
s_glxError = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cInterfaceGLX::SwapInterval(int Interval)
|
||||
{
|
||||
if (glXSwapIntervalSGI)
|
||||
glXSwapIntervalSGI(Interval);
|
||||
else
|
||||
ERROR_LOG(VIDEO, "No support for SwapInterval (framerate clamped to monitor refresh rate).");
|
||||
if (glXSwapIntervalSGI)
|
||||
glXSwapIntervalSGI(Interval);
|
||||
else
|
||||
ERROR_LOG(VIDEO, "No support for SwapInterval (framerate clamped to monitor refresh rate).");
|
||||
}
|
||||
void* cInterfaceGLX::GetFuncAddress(const std::string& name)
|
||||
{
|
||||
return (void*)glXGetProcAddress((const GLubyte*)name.c_str());
|
||||
return (void*)glXGetProcAddress((const GLubyte*)name.c_str());
|
||||
}
|
||||
|
||||
void cInterfaceGLX::Swap()
|
||||
{
|
||||
glXSwapBuffers(dpy, win);
|
||||
glXSwapBuffers(dpy, win);
|
||||
}
|
||||
|
||||
// Create rendering window.
|
||||
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
|
||||
bool cInterfaceGLX::Create(void *window_handle, bool core)
|
||||
bool cInterfaceGLX::Create(void* window_handle, bool core)
|
||||
{
|
||||
dpy = XOpenDisplay(nullptr);
|
||||
int screen = DefaultScreen(dpy);
|
||||
dpy = XOpenDisplay(nullptr);
|
||||
int screen = DefaultScreen(dpy);
|
||||
|
||||
// checking glx version
|
||||
int glxMajorVersion, glxMinorVersion;
|
||||
glXQueryVersion(dpy, &glxMajorVersion, &glxMinorVersion);
|
||||
if (glxMajorVersion < 1 || (glxMajorVersion == 1 && glxMinorVersion < 4))
|
||||
{
|
||||
ERROR_LOG(VIDEO, "glX-Version %d.%d detected, but need at least 1.4",
|
||||
glxMajorVersion, glxMinorVersion);
|
||||
return false;
|
||||
}
|
||||
// checking glx version
|
||||
int glxMajorVersion, glxMinorVersion;
|
||||
glXQueryVersion(dpy, &glxMajorVersion, &glxMinorVersion);
|
||||
if (glxMajorVersion < 1 || (glxMajorVersion == 1 && glxMinorVersion < 4))
|
||||
{
|
||||
ERROR_LOG(VIDEO, "glX-Version %d.%d detected, but need at least 1.4", glxMajorVersion,
|
||||
glxMinorVersion);
|
||||
return false;
|
||||
}
|
||||
|
||||
// loading core context creation function
|
||||
glXCreateContextAttribs = (PFNGLXCREATECONTEXTATTRIBSPROC)GetFuncAddress("glXCreateContextAttribsARB");
|
||||
if (!glXCreateContextAttribs)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "glXCreateContextAttribsARB not found, do you support GLX_ARB_create_context?");
|
||||
return false;
|
||||
}
|
||||
// loading core context creation function
|
||||
glXCreateContextAttribs =
|
||||
(PFNGLXCREATECONTEXTATTRIBSPROC)GetFuncAddress("glXCreateContextAttribsARB");
|
||||
if (!glXCreateContextAttribs)
|
||||
{
|
||||
ERROR_LOG(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,
|
||||
None
|
||||
};
|
||||
int fbcount = 0;
|
||||
GLXFBConfig* fbc = glXChooseFBConfig(dpy, screen, visual_attribs, &fbcount);
|
||||
if (!fbc || !fbcount)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Failed to retrieve a framebuffer config");
|
||||
return false;
|
||||
}
|
||||
fbconfig = *fbc;
|
||||
XFree(fbc);
|
||||
// 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,
|
||||
None};
|
||||
int fbcount = 0;
|
||||
GLXFBConfig* fbc = glXChooseFBConfig(dpy, screen, visual_attribs, &fbcount);
|
||||
if (!fbc || !fbcount)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Failed to retrieve a framebuffer config");
|
||||
return false;
|
||||
}
|
||||
fbconfig = *fbc;
|
||||
XFree(fbc);
|
||||
|
||||
// Get an appropriate visual
|
||||
XVisualInfo* vi = glXGetVisualFromFBConfig(dpy, fbconfig);
|
||||
// Get an appropriate visual
|
||||
XVisualInfo* vi = glXGetVisualFromFBConfig(dpy, fbconfig);
|
||||
|
||||
s_glxError = false;
|
||||
XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler);
|
||||
s_glxError = false;
|
||||
XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler);
|
||||
|
||||
// Create a GLX context.
|
||||
// We try to get a 4.0 core profile, else we try 3.3, else try it with anything we get.
|
||||
int context_attribs[] =
|
||||
{
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
|
||||
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||
None
|
||||
};
|
||||
ctx = nullptr;
|
||||
if (core)
|
||||
{
|
||||
ctx = glXCreateContextAttribs(dpy, fbconfig, 0, True, context_attribs);
|
||||
XSync(dpy, False);
|
||||
}
|
||||
if (core && (!ctx || s_glxError))
|
||||
{
|
||||
int context_attribs_33[] =
|
||||
{
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
|
||||
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;
|
||||
ctx = glXCreateContextAttribs(dpy, fbconfig, 0, True, context_attribs_33);
|
||||
XSync(dpy, False);
|
||||
// Create a GLX context.
|
||||
// We try to get a 4.0 core profile, else we try 3.3, else try it with anything we get.
|
||||
int context_attribs[] = {GLX_CONTEXT_MAJOR_VERSION_ARB,
|
||||
4,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB,
|
||||
0,
|
||||
GLX_CONTEXT_PROFILE_MASK_ARB,
|
||||
GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
GLX_CONTEXT_FLAGS_ARB,
|
||||
GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||
None};
|
||||
ctx = nullptr;
|
||||
if (core)
|
||||
{
|
||||
ctx = glXCreateContextAttribs(dpy, fbconfig, 0, True, context_attribs);
|
||||
XSync(dpy, False);
|
||||
}
|
||||
if (core && (!ctx || s_glxError))
|
||||
{
|
||||
int context_attribs_33[] = {GLX_CONTEXT_MAJOR_VERSION_ARB,
|
||||
3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB,
|
||||
3,
|
||||
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;
|
||||
ctx = glXCreateContextAttribs(dpy, fbconfig, 0, True, context_attribs_33);
|
||||
XSync(dpy, False);
|
||||
}
|
||||
if (!ctx || s_glxError)
|
||||
{
|
||||
int context_attribs_legacy[] = {GLX_CONTEXT_MAJOR_VERSION_ARB, 1, GLX_CONTEXT_MINOR_VERSION_ARB,
|
||||
0, None};
|
||||
s_glxError = false;
|
||||
ctx = glXCreateContextAttribs(dpy, fbconfig, 0, True, context_attribs_legacy);
|
||||
XSync(dpy, False);
|
||||
}
|
||||
if (!ctx || s_glxError)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Unable to create GL context.");
|
||||
return false;
|
||||
}
|
||||
XSetErrorHandler(oldHandler);
|
||||
|
||||
}
|
||||
if (!ctx || s_glxError)
|
||||
{
|
||||
int context_attribs_legacy[] =
|
||||
{
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 1,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
|
||||
None
|
||||
};
|
||||
s_glxError = false;
|
||||
ctx = glXCreateContextAttribs(dpy, fbconfig, 0, True, context_attribs_legacy);
|
||||
XSync(dpy, False);
|
||||
XWindow.Initialize(dpy);
|
||||
|
||||
}
|
||||
if (!ctx || s_glxError)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Unable to create GL context.");
|
||||
return false;
|
||||
}
|
||||
XSetErrorHandler(oldHandler);
|
||||
Window parent = (Window)window_handle;
|
||||
|
||||
XWindow.Initialize(dpy);
|
||||
XWindowAttributes attribs;
|
||||
if (!XGetWindowAttributes(dpy, parent, &attribs))
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Window attribute retrieval failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
Window parent = (Window)window_handle;
|
||||
s_backbuffer_width = attribs.width;
|
||||
s_backbuffer_height = attribs.height;
|
||||
|
||||
XWindowAttributes attribs;
|
||||
if (!XGetWindowAttributes(dpy, parent, &attribs))
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Window attribute retrieval failed");
|
||||
return false;
|
||||
}
|
||||
win = XWindow.CreateXWindow(parent, vi);
|
||||
XFree(vi);
|
||||
|
||||
s_backbuffer_width = attribs.width;
|
||||
s_backbuffer_height = attribs.height;
|
||||
|
||||
win = XWindow.CreateXWindow(parent, vi);
|
||||
XFree(vi);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cInterfaceGLX::MakeCurrent()
|
||||
{
|
||||
bool success = glXMakeCurrent(dpy, win, ctx);
|
||||
if (success)
|
||||
{
|
||||
// load this function based on the current bound context
|
||||
glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)GLInterface->GetFuncAddress("glXSwapIntervalSGI");
|
||||
}
|
||||
return success;
|
||||
bool success = glXMakeCurrent(dpy, win, ctx);
|
||||
if (success)
|
||||
{
|
||||
// load this function based on the current bound context
|
||||
glXSwapIntervalSGI =
|
||||
(PFNGLXSWAPINTERVALSGIPROC)GLInterface->GetFuncAddress("glXSwapIntervalSGI");
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool cInterfaceGLX::ClearCurrent()
|
||||
{
|
||||
return glXMakeCurrent(dpy, None, nullptr);
|
||||
return glXMakeCurrent(dpy, None, nullptr);
|
||||
}
|
||||
|
||||
|
||||
// Close backend
|
||||
void cInterfaceGLX::Shutdown()
|
||||
{
|
||||
XWindow.DestroyXWindow();
|
||||
if (ctx)
|
||||
{
|
||||
glXDestroyContext(dpy, ctx);
|
||||
XCloseDisplay(dpy);
|
||||
ctx = nullptr;
|
||||
}
|
||||
XWindow.DestroyXWindow();
|
||||
if (ctx)
|
||||
{
|
||||
glXDestroyContext(dpy, ctx);
|
||||
XCloseDisplay(dpy);
|
||||
ctx = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user