summaryrefslogtreecommitdiffstats
path: root/src/egl/main/egldispatchstubs.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/egldispatchstubs.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/egldispatchstubs.c')
-rw-r--r--src/egl/main/egldispatchstubs.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/egl/main/egldispatchstubs.c b/src/egl/main/egldispatchstubs.c
new file mode 100644
index 00000000000..e02abd7a9e0
--- /dev/null
+++ b/src/egl/main/egldispatchstubs.c
@@ -0,0 +1,110 @@
+#include "egldispatchstubs.h"
+#include "g_egldispatchstubs.h"
+
+#include <string.h>
+
+#include "eglcurrent.h"
+
+static const __EGLapiExports *exports;
+
+const int __EGL_DISPATCH_FUNC_COUNT = __EGL_DISPATCH_COUNT;
+int __EGL_DISPATCH_FUNC_INDICES[__EGL_DISPATCH_COUNT + 1];
+
+static int FindProcIndex(const char *name)
+{
+ unsigned first = 0;
+ unsigned last = __EGL_DISPATCH_COUNT - 1;
+
+ while (first <= last) {
+ unsigned middle = (first + last) / 2;
+ int comp = strcmp(name,
+ __EGL_DISPATCH_FUNC_NAMES[middle]);
+
+ if (comp > 0)
+ first = middle + 1;
+ else if (comp < 0)
+ last = middle - 1;
+ else
+ return middle;
+ }
+
+ /* Just point to the dummy entry at the end of the respective table */
+ return __EGL_DISPATCH_COUNT;
+}
+
+void __eglInitDispatchStubs(const __EGLapiExports *exportsTable)
+{
+ int i;
+ exports = exportsTable;
+ for (i=0; i<__EGL_DISPATCH_FUNC_COUNT; i++) {
+ __EGL_DISPATCH_FUNC_INDICES[i] = -1;
+ }
+}
+
+void __eglSetDispatchIndex(const char *name, int dispatchIndex)
+{
+ int index = FindProcIndex(name);
+ __EGL_DISPATCH_FUNC_INDICES[index] = dispatchIndex;
+}
+
+void *__eglDispatchFindDispatchFunction(const char *name)
+{
+ int index = FindProcIndex(name);
+ return (void *) __EGL_DISPATCH_FUNCS[index];
+}
+
+static __eglMustCastToProperFunctionPointerType FetchVendorFunc(__EGLvendorInfo *vendor,
+ int index, EGLint errorCode)
+{
+ __eglMustCastToProperFunctionPointerType func = NULL;
+
+ if (vendor != NULL) {
+ func = exports->fetchDispatchEntry(vendor, __EGL_DISPATCH_FUNC_INDICES[index]);
+ }
+ if (func == NULL) {
+ if (errorCode != EGL_SUCCESS) {
+ _eglError(errorCode, __EGL_DISPATCH_FUNC_NAMES[index]);
+ }
+ return NULL;
+ }
+
+ if (!exports->setLastVendor(vendor)) {
+ // Don't bother trying to set an error code in libglvnd. If
+ // setLastVendor failed, then setEGLError would also fail.
+ _eglError(errorCode, __EGL_DISPATCH_FUNC_NAMES[index]);
+ return NULL;
+ }
+
+ return func;
+}
+
+__eglMustCastToProperFunctionPointerType __eglDispatchFetchByCurrent(int index)
+{
+ __EGLvendorInfo *vendor;
+
+ // Note: This is only used for the eglWait* functions. For those, if
+ // there's no current context, then they're supposed to do nothing but
+ // return success.
+ exports->threadInit();
+ vendor = exports->getCurrentVendor();
+ return FetchVendorFunc(vendor, index, EGL_SUCCESS);
+}
+
+__eglMustCastToProperFunctionPointerType __eglDispatchFetchByDisplay(EGLDisplay dpy, int index)
+{
+ __EGLvendorInfo *vendor;
+
+ exports->threadInit();
+ vendor = exports->getVendorFromDisplay(dpy);
+ return FetchVendorFunc(vendor, index, EGL_BAD_DISPLAY);
+}
+
+__eglMustCastToProperFunctionPointerType __eglDispatchFetchByDevice(EGLDeviceEXT dev, int index)
+{
+ __EGLvendorInfo *vendor;
+
+ exports->threadInit();
+ vendor = exports->getVendorFromDevice(dev);
+ return FetchVendorFunc(vendor, index, EGL_BAD_DEVICE_EXT);
+}
+