diff options
Diffstat (limited to 'Source/Core/VideoBackends/OGL/GLInterface/GLX.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/OGL/GLInterface/GLX.cpp | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/Source/Core/VideoBackends/OGL/GLInterface/GLX.cpp b/Source/Core/VideoBackends/OGL/GLInterface/GLX.cpp new file mode 100644 index 0000000000..12912b0f5d --- /dev/null +++ b/Source/Core/VideoBackends/OGL/GLInterface/GLX.cpp @@ -0,0 +1,145 @@ +// Copyright 2014 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include <string> + +#include "VideoBackends/OGL/GLInterface/GLX.h" + +#include "VideoCommon/RenderBase.h" +#include "VideoCommon/VideoConfig.h" + +typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); +static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr; + +void cInterfaceGLX::SwapInterval(int Interval) +{ + 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()); +} + +void cInterfaceGLX::Swap() +{ + glXSwapBuffers(dpy, win); +} + +// Create rendering window. +// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() +bool cInterfaceGLX::Create(void *window_handle) +{ + int glxMajorVersion, glxMinorVersion; + + // attributes for a single buffered visual in RGBA format with at least + // 8 bits per color + int attrListSgl[] = {GLX_RGBA, GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + None}; + + // attributes for a double buffered visual in RGBA format with at least + // 8 bits per color + int attrListDbl[] = {GLX_RGBA, GLX_DOUBLEBUFFER, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + None }; + + int attrListDefault[] = { + GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, + None }; + + dpy = XOpenDisplay(nullptr); + int screen = DefaultScreen(dpy); + + glXQueryVersion(dpy, &glxMajorVersion, &glxMinorVersion); + NOTICE_LOG(VIDEO, "glX-Version %d.%d", glxMajorVersion, glxMinorVersion); + + // Get an appropriate visual + vi = glXChooseVisual(dpy, screen, attrListDbl); + if (vi == nullptr) + { + vi = glXChooseVisual(dpy, screen, attrListSgl); + if (vi != nullptr) + { + ERROR_LOG(VIDEO, "Only single buffered visual!"); + } + else + { + vi = glXChooseVisual(dpy, screen, attrListDefault); + if (vi == nullptr) + { + ERROR_LOG(VIDEO, "Could not choose visual (glXChooseVisual)"); + return false; + } + } + } + else + { + NOTICE_LOG(VIDEO, "Got double buffered visual!"); + } + + // Create a GLX context. + ctx = glXCreateContext(dpy, vi, nullptr, GL_TRUE); + if (!ctx) + { + PanicAlert("Unable to create GLX context."); + return false; + } + + XWindow.Initialize(dpy); + + Window parent = (Window)window_handle; + + XWindowAttributes attribs; + if (!XGetWindowAttributes(dpy, parent, &attribs)) + { + ERROR_LOG(VIDEO, "Window attribute retrieval failed"); + return false; + } + + s_backbuffer_width = attribs.width; + s_backbuffer_height = attribs.height; + + win = XWindow.CreateXWindow(parent, vi); + 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 cInterfaceGLX::ClearCurrent() +{ + return glXMakeCurrent(dpy, None, nullptr); +} + + +// Close backend +void cInterfaceGLX::Shutdown() +{ + XWindow.DestroyXWindow(); + if (ctx) + { + glXDestroyContext(dpy, ctx); + XCloseDisplay(dpy); + ctx = nullptr; + } +} + |
