summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp')
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp398
1 files changed, 398 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp b/gfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp
new file mode 100755
index 000000000..4ec38dd81
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp
@@ -0,0 +1,398 @@
+//
+// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FunctionsGLX.cpp: Implements the FunctionsGLX class.
+
+#define ANGLE_SKIP_GLX_DEFINES 1
+#include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
+#undef ANGLE_SKIP_GLX_DEFINES
+
+// We can only include glx.h in files which do not include ANGLE's GLES
+// headers, to avoid doubly-defined GLenum macros, typedefs, etc.
+#include <GL/glx.h>
+
+#include <dlfcn.h>
+#include <algorithm>
+
+#include "common/string_utils.h"
+#include "libANGLE/renderer/gl/glx/functionsglx_typedefs.h"
+
+namespace rx
+{
+
+void* FunctionsGLX::sLibHandle = nullptr;
+
+template<typename T>
+static bool GetProc(PFNGETPROCPROC getProc, T *member, const char *name)
+{
+ *member = reinterpret_cast<T>(getProc(name));
+ return *member != nullptr;
+}
+
+struct FunctionsGLX::GLXFunctionTable
+{
+ GLXFunctionTable()
+ : createContextPtr(nullptr),
+ destroyContextPtr(nullptr),
+ makeCurrentPtr(nullptr),
+ swapBuffersPtr(nullptr),
+ queryExtensionPtr(nullptr),
+ queryVersionPtr(nullptr),
+ getCurrentContextPtr(nullptr),
+ getCurrentDrawablePtr(nullptr),
+ waitXPtr(nullptr),
+ waitGLPtr(nullptr),
+ getClientStringPtr(nullptr),
+ queryExtensionsStringPtr(nullptr),
+ getFBConfigsPtr(nullptr),
+ chooseFBConfigPtr(nullptr),
+ getFBConfigAttribPtr(nullptr),
+ getVisualFromFBConfigPtr(nullptr),
+ createWindowPtr(nullptr),
+ destroyWindowPtr(nullptr),
+ createPbufferPtr(nullptr),
+ destroyPbufferPtr(nullptr),
+ queryDrawablePtr(nullptr),
+ createContextAttribsARBPtr(nullptr),
+ swapIntervalEXTPtr(nullptr),
+ swapIntervalMESAPtr(nullptr),
+ swapIntervalSGIPtr(nullptr)
+ {
+ }
+
+ // GLX 1.0
+ PFNGLXCREATECONTEXTPROC createContextPtr;
+ PFNGLXDESTROYCONTEXTPROC destroyContextPtr;
+ PFNGLXMAKECURRENTPROC makeCurrentPtr;
+ PFNGLXSWAPBUFFERSPROC swapBuffersPtr;
+ PFNGLXQUERYEXTENSIONPROC queryExtensionPtr;
+ PFNGLXQUERYVERSIONPROC queryVersionPtr;
+ PFNGLXGETCURRENTCONTEXTPROC getCurrentContextPtr;
+ PFNGLXGETCURRENTDRAWABLEPROC getCurrentDrawablePtr;
+ PFNGLXWAITXPROC waitXPtr;
+ PFNGLXWAITGLPROC waitGLPtr;
+
+ // GLX 1.1
+ PFNGLXGETCLIENTSTRINGPROC getClientStringPtr;
+ PFNGLXQUERYEXTENSIONSSTRINGPROC queryExtensionsStringPtr;
+
+ //GLX 1.3
+ PFNGLXGETFBCONFIGSPROC getFBConfigsPtr;
+ PFNGLXCHOOSEFBCONFIGPROC chooseFBConfigPtr;
+ PFNGLXGETFBCONFIGATTRIBPROC getFBConfigAttribPtr;
+ PFNGLXGETVISUALFROMFBCONFIGPROC getVisualFromFBConfigPtr;
+ PFNGLXCREATEWINDOWPROC createWindowPtr;
+ PFNGLXDESTROYWINDOWPROC destroyWindowPtr;
+ PFNGLXCREATEPBUFFERPROC createPbufferPtr;
+ PFNGLXDESTROYPBUFFERPROC destroyPbufferPtr;
+ PFNGLXQUERYDRAWABLEPROC queryDrawablePtr;
+
+ // GLX_ARB_create_context
+ PFNGLXCREATECONTEXTATTRIBSARBPROC createContextAttribsARBPtr;
+
+ // GLX_EXT_swap_control
+ PFNGLXSWAPINTERVALEXTPROC swapIntervalEXTPtr;
+
+ // GLX_MESA_swap_control
+ PFNGLXSWAPINTERVALMESAPROC swapIntervalMESAPtr;
+
+ // GLX_SGI_swap_control
+ PFNGLXSWAPINTERVALSGIPROC swapIntervalSGIPtr;
+};
+
+FunctionsGLX::FunctionsGLX()
+ : majorVersion(0),
+ minorVersion(0),
+ mXDisplay(nullptr),
+ mXScreen(-1),
+ mFnPtrs(new GLXFunctionTable())
+{
+}
+
+FunctionsGLX::~FunctionsGLX()
+{
+ delete mFnPtrs;
+ terminate();
+}
+
+bool FunctionsGLX::initialize(Display *xDisplay, int screen, std::string *errorString)
+{
+ terminate();
+ mXDisplay = xDisplay;
+ mXScreen = screen;
+
+#if !defined(ANGLE_LINK_GLX)
+ // Some OpenGL implementations can't handle having this library
+ // handle closed while there's any X window still open against
+ // which a GLXWindow was ever created.
+ if (!sLibHandle)
+ {
+ sLibHandle = dlopen("libGL.so.1", RTLD_NOW);
+ if (!sLibHandle)
+ {
+ *errorString = std::string("Could not dlopen libGL.so.1: ") + dlerror();
+ return false;
+ }
+ }
+
+ getProc = reinterpret_cast<PFNGETPROCPROC>(dlsym(sLibHandle, "glXGetProcAddress"));
+ if (!getProc)
+ {
+ getProc = reinterpret_cast<PFNGETPROCPROC>(dlsym(sLibHandle, "glXGetProcAddressARB"));
+ }
+ if (!getProc)
+ {
+ *errorString = "Could not retrieve glXGetProcAddress";
+ return false;
+ }
+#else
+ getProc = reinterpret_cast<PFNGETPROCPROC>(glXGetProcAddress);
+#endif
+
+#define GET_PROC_OR_ERROR(MEMBER, NAME) \
+ if (!GetProc(getProc, MEMBER, #NAME)) \
+ { \
+ *errorString = "Could not load GLX entry point " #NAME; \
+ return false; \
+ }
+#if !defined(ANGLE_LINK_GLX)
+#define GET_FNPTR_OR_ERROR(MEMBER, NAME) GET_PROC_OR_ERROR(MEMBER, NAME)
+#else
+#define GET_FNPTR_OR_ERROR(MEMBER, NAME) *MEMBER = NAME;
+#endif
+
+ // GLX 1.0
+ GET_FNPTR_OR_ERROR(&mFnPtrs->createContextPtr, glXCreateContext);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->destroyContextPtr, glXDestroyContext);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->makeCurrentPtr, glXMakeCurrent);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->swapBuffersPtr, glXSwapBuffers);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->queryExtensionPtr, glXQueryExtension);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->queryVersionPtr, glXQueryVersion);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->getCurrentContextPtr, glXGetCurrentContext);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->getCurrentDrawablePtr, glXGetCurrentDrawable);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->waitXPtr, glXWaitX);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->waitGLPtr, glXWaitGL);
+
+ // GLX 1.1
+ GET_FNPTR_OR_ERROR(&mFnPtrs->getClientStringPtr, glXGetClientString);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->queryExtensionsStringPtr, glXQueryExtensionsString);
+
+ // Check we have a working GLX
+ {
+ int errorBase;
+ int eventBase;
+ if (!queryExtension(&errorBase, &eventBase))
+ {
+ *errorString = "GLX is not present.";
+ return false;
+ }
+ }
+
+ // Check we have a supported version of GLX
+ if (!queryVersion(&majorVersion, &minorVersion))
+ {
+ *errorString = "Could not query the GLX version.";
+ return false;
+ }
+ if (majorVersion != 1 || minorVersion < 3)
+ {
+ *errorString = "Unsupported GLX version (requires at least 1.3).";
+ return false;
+ }
+
+ const char *extensions = queryExtensionsString();
+ if (!extensions)
+ {
+ *errorString = "glXQueryExtensionsString returned NULL";
+ return false;
+ }
+ angle::SplitStringAlongWhitespace(extensions, &mExtensions);
+
+ // GLX 1.3
+ GET_FNPTR_OR_ERROR(&mFnPtrs->getFBConfigsPtr, glXGetFBConfigs);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->chooseFBConfigPtr, glXChooseFBConfig);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->getFBConfigAttribPtr, glXGetFBConfigAttrib);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->getVisualFromFBConfigPtr, glXGetVisualFromFBConfig);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->createWindowPtr, glXCreateWindow);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->destroyWindowPtr, glXDestroyWindow);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->createPbufferPtr, glXCreatePbuffer);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->destroyPbufferPtr, glXDestroyPbuffer);
+ GET_FNPTR_OR_ERROR(&mFnPtrs->queryDrawablePtr, glXQueryDrawable);
+
+ // Extensions
+ if (hasExtension("GLX_ARB_create_context"))
+ {
+ GET_PROC_OR_ERROR(&mFnPtrs->createContextAttribsARBPtr, glXCreateContextAttribsARB);
+ }
+ if (hasExtension("GLX_EXT_swap_control"))
+ {
+ GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalEXTPtr, glXSwapIntervalEXT);
+ }
+ if (hasExtension("GLX_MESA_swap_control"))
+ {
+ GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalMESAPtr, glXSwapIntervalMESA);
+ }
+ if (hasExtension("GLX_SGI_swap_control"))
+ {
+ GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalSGIPtr, glXSwapIntervalSGI);
+ }
+
+#undef GET_FNPTR_OR_ERROR
+#undef GET_PROC_OR_ERROR
+
+ *errorString = "";
+ return true;
+}
+
+void FunctionsGLX::terminate()
+{
+}
+
+bool FunctionsGLX::hasExtension(const char *extension) const
+{
+ return std::find(mExtensions.begin(), mExtensions.end(), extension) != mExtensions.end();
+}
+
+Display *FunctionsGLX::getDisplay() const
+{
+ return mXDisplay;
+}
+
+int FunctionsGLX::getScreen() const
+{
+ return mXScreen;
+}
+
+// GLX functions
+
+// GLX 1.0
+glx::Context FunctionsGLX::createContext(XVisualInfo *visual, glx::Context share, bool direct) const
+{
+ GLXContext shareCtx = reinterpret_cast<GLXContext>(share);
+ GLXContext context = mFnPtrs->createContextPtr(mXDisplay, visual, shareCtx, direct);
+ return reinterpret_cast<glx::Context>(context);
+}
+void FunctionsGLX::destroyContext(glx::Context context) const
+{
+ GLXContext ctx = reinterpret_cast<GLXContext>(context);
+ mFnPtrs->destroyContextPtr(mXDisplay, ctx);
+}
+Bool FunctionsGLX::makeCurrent(glx::Drawable drawable, glx::Context context) const
+{
+ GLXContext ctx = reinterpret_cast<GLXContext>(context);
+ return mFnPtrs->makeCurrentPtr(mXDisplay, drawable, ctx);
+}
+void FunctionsGLX::swapBuffers(glx::Drawable drawable) const
+{
+ mFnPtrs->swapBuffersPtr(mXDisplay, drawable);
+}
+Bool FunctionsGLX::queryExtension(int *errorBase, int *event) const
+{
+ return mFnPtrs->queryExtensionPtr(mXDisplay, errorBase, event);
+}
+Bool FunctionsGLX::queryVersion(int *major, int *minor) const
+{
+ return mFnPtrs->queryVersionPtr(mXDisplay, major, minor);
+}
+glx::Context FunctionsGLX::getCurrentContext() const
+{
+ GLXContext context = mFnPtrs->getCurrentContextPtr();
+ return reinterpret_cast<glx::Context>(context);
+}
+glx::Drawable FunctionsGLX::getCurrentDrawable() const
+{
+ GLXDrawable drawable = mFnPtrs->getCurrentDrawablePtr();
+ return reinterpret_cast<glx::Drawable>(drawable);
+}
+void FunctionsGLX::waitX() const
+{
+ mFnPtrs->waitXPtr();
+}
+void FunctionsGLX::waitGL() const
+{
+ mFnPtrs->waitGLPtr();
+}
+
+// GLX 1.1
+const char *FunctionsGLX::getClientString(int name) const
+{
+ return mFnPtrs->getClientStringPtr(mXDisplay, name);
+}
+
+const char *FunctionsGLX::queryExtensionsString() const
+{
+ return mFnPtrs->queryExtensionsStringPtr(mXDisplay, mXScreen);
+}
+
+// GLX 1.4
+glx::FBConfig *FunctionsGLX::getFBConfigs(int *nElements) const
+{
+ GLXFBConfig *configs = mFnPtrs->getFBConfigsPtr(mXDisplay, mXScreen, nElements);
+ return reinterpret_cast<glx::FBConfig*>(configs);
+}
+glx::FBConfig *FunctionsGLX::chooseFBConfig(const int *attribList, int *nElements) const
+{
+ GLXFBConfig *configs = mFnPtrs->chooseFBConfigPtr(mXDisplay, mXScreen, attribList, nElements);
+ return reinterpret_cast<glx::FBConfig*>(configs);
+}
+int FunctionsGLX::getFBConfigAttrib(glx::FBConfig config, int attribute, int *value) const
+{
+ GLXFBConfig cfg = reinterpret_cast<GLXFBConfig>(config);
+ return mFnPtrs->getFBConfigAttribPtr(mXDisplay, cfg, attribute, value);
+}
+XVisualInfo *FunctionsGLX::getVisualFromFBConfig(glx::FBConfig config) const
+{
+ GLXFBConfig cfg = reinterpret_cast<GLXFBConfig>(config);
+ return mFnPtrs->getVisualFromFBConfigPtr(mXDisplay, cfg);
+}
+GLXWindow FunctionsGLX::createWindow(glx::FBConfig config, Window window, const int *attribList) const
+{
+ GLXFBConfig cfg = reinterpret_cast<GLXFBConfig>(config);
+ return mFnPtrs->createWindowPtr(mXDisplay, cfg, window, attribList);
+}
+void FunctionsGLX::destroyWindow(glx::Window window) const
+{
+ mFnPtrs->destroyWindowPtr(mXDisplay, window);
+}
+glx::Pbuffer FunctionsGLX::createPbuffer(glx::FBConfig config, const int *attribList) const
+{
+ GLXFBConfig cfg = reinterpret_cast<GLXFBConfig>(config);
+ return mFnPtrs->createPbufferPtr(mXDisplay, cfg, attribList);
+}
+void FunctionsGLX::destroyPbuffer(glx::Pbuffer pbuffer) const
+{
+ mFnPtrs->destroyPbufferPtr(mXDisplay, pbuffer);
+}
+void FunctionsGLX::queryDrawable(glx::Drawable drawable, int attribute, unsigned int *value) const
+{
+ mFnPtrs->queryDrawablePtr(mXDisplay, drawable, attribute, value);
+}
+
+// GLX_ARB_create_context
+glx::Context FunctionsGLX::createContextAttribsARB(glx::FBConfig config, glx::Context shareContext, Bool direct, const int *attribList) const
+{
+ GLXContext shareCtx = reinterpret_cast<GLXContext>(shareContext);
+ GLXFBConfig cfg = reinterpret_cast<GLXFBConfig>(config);
+ GLXContext ctx = mFnPtrs->createContextAttribsARBPtr(mXDisplay, cfg, shareCtx, direct, attribList);
+ return reinterpret_cast<glx::Context>(ctx);
+}
+
+void FunctionsGLX::swapIntervalEXT(glx::Drawable drawable, int intervals) const
+{
+ mFnPtrs->swapIntervalEXTPtr(mXDisplay, drawable, intervals);
+}
+
+int FunctionsGLX::swapIntervalMESA(int intervals) const
+{
+ return mFnPtrs->swapIntervalMESAPtr(intervals);
+}
+
+int FunctionsGLX::swapIntervalSGI(int intervals) const
+{
+ return mFnPtrs->swapIntervalSGIPtr(intervals);
+}
+
+}