summaryrefslogtreecommitdiffstats
path: root/src/egl/main/eglglvnd.c
diff options
context:
space:
mode:
authorKyle Brenneman <[email protected]>2017-01-04 11:31:58 -0700
committerEmil Velikov <[email protected]>2017-04-17 13:03:58 +0100
commitce562f9e3fab769d64b0e5453ec2b4f8710a31ce (patch)
tree5c372e39ba2c33611f145b91224f304a53ab6dd0 /src/egl/main/eglglvnd.c
parent370df207cadbc1ae60415b3b953f85088e6398d4 (diff)
EGL: Implement the libglvnd interface for EGL (v3)
The new interface mostly just sits on top of the existing library. The only change to the existing EGL code is to split the client extension string into platform extensions and everything else. On non-glvnd builds, eglQueryString will just concatenate the two strings. The EGL dispatch stubs are all generated. The script is based on the one used to generate entrypoints in libglvnd itself. v2: [Kyle] - Rebased against master. - Reworked the EGL makefile to use separate libraries - Made the EGL code generation scripts work with Python 2 and 3. - Change gen_egl_dispatch.py to use argparse for the command line arguments. - Assorted formatting and style cleanup in the Python scripts. v3: [Emil Velikov] - Rebase - Remove separate glvnd glx/egl configure toggles Signed-off-by: Emil Velikov <[email protected]>
Diffstat (limited to 'src/egl/main/eglglvnd.c')
-rw-r--r--src/egl/main/eglglvnd.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/egl/main/eglglvnd.c b/src/egl/main/eglglvnd.c
new file mode 100644
index 00000000000..6b984ed6c28
--- /dev/null
+++ b/src/egl/main/eglglvnd.c
@@ -0,0 +1,82 @@
+#include <string.h>
+#include <assert.h>
+
+#include <glvnd/libeglabi.h>
+
+#include "eglcurrent.h"
+#include "egldispatchstubs.h"
+#include "eglglobals.h"
+
+static const __EGLapiExports *__eglGLVNDApiExports = NULL;
+
+static const char * EGLAPIENTRY
+__eglGLVNDQueryString(EGLDisplay dpy, EGLenum name)
+{
+ // For client extensions, return the list of non-platform extensions. The
+ // platform extensions are returned by __eglGLVNDGetVendorString.
+ if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)
+ return _eglGlobal.ClientOnlyExtensionString;
+
+ // For everything else, forward to the normal eglQueryString function.
+ return eglQueryString(dpy, name);
+}
+
+static const char *
+__eglGLVNDGetVendorString(int name)
+{
+ if (name == __EGL_VENDOR_STRING_PLATFORM_EXTENSIONS) {
+ const char *str = _eglGlobal.PlatformExtensionString;
+ // The platform extension string may have a leading space. If it does,
+ // then skip over it.
+ while (*str == ' ') {
+ str++;
+ }
+ return str;
+ }
+
+ return NULL;
+}
+
+static EGLDisplay
+__eglGLVNDGetPlatformDisplay(EGLenum platform, void *native_display,
+ const EGLAttrib *attrib_list)
+{
+ if (platform == EGL_NONE) {
+ assert(native_display == (void *) EGL_DEFAULT_DISPLAY);
+ assert(attrib_list == NULL);
+ return eglGetDisplay((EGLNativeDisplayType) native_display);
+ } else {
+ return eglGetPlatformDisplay(platform, native_display, attrib_list);
+ }
+}
+
+static void *
+__eglGLVNDGetProcAddress(const char *procName)
+{
+ if (strcmp(procName, "eglQueryString") == 0)
+ return (void *) __eglGLVNDQueryString;
+
+ return (void *) eglGetProcAddress(procName);
+}
+
+EGLAPI EGLBoolean
+__egl_Main(uint32_t version, const __EGLapiExports *exports,
+ __EGLvendorInfo *vendor, __EGLapiImports *imports)
+{
+ if (EGL_VENDOR_ABI_GET_MAJOR_VERSION(version) !=
+ EGL_VENDOR_ABI_MAJOR_VERSION)
+ return EGL_FALSE;
+
+ __eglGLVNDApiExports = exports;
+ __eglInitDispatchStubs(exports);
+
+ imports->getPlatformDisplay = __eglGLVNDGetPlatformDisplay;
+ imports->getSupportsAPI = _eglIsApiValid;
+ imports->getVendorString = __eglGLVNDGetVendorString;
+ imports->getProcAddress = __eglGLVNDGetProcAddress;
+ imports->getDispatchAddress = __eglDispatchFindDispatchFunction;
+ imports->setDispatchIndex = __eglSetDispatchIndex;
+
+ return EGL_TRUE;
+}
+