1 #include "egldispatchstubs.h"
2 #include "g_egldispatchstubs.h"
3
4 #include <string.h>
5 #include <stdlib.h>
6
7 #include "eglcurrent.h"
8
9 static const __EGLapiExports *exports;
10
11 const int __EGL_DISPATCH_FUNC_COUNT = __EGL_DISPATCH_COUNT;
12 int __EGL_DISPATCH_FUNC_INDICES[__EGL_DISPATCH_COUNT + 1];
13
Compare(const void * l,const void * r)14 static int Compare(const void *l, const void *r)
15 {
16 const char *s = *(const char **)r;
17 return strcmp(l, s);
18 }
19
FindProcIndex(const char * name)20 static int FindProcIndex(const char *name)
21 {
22 const char **match = bsearch(name, __EGL_DISPATCH_FUNC_NAMES,
23 __EGL_DISPATCH_COUNT, sizeof(const char *), Compare);
24
25 if (match == NULL)
26 return __EGL_DISPATCH_COUNT;
27
28 return match - __EGL_DISPATCH_FUNC_NAMES;
29 }
30
__eglInitDispatchStubs(const __EGLapiExports * exportsTable)31 void __eglInitDispatchStubs(const __EGLapiExports *exportsTable)
32 {
33 int i;
34 exports = exportsTable;
35 for (i=0; i<__EGL_DISPATCH_FUNC_COUNT; i++) {
36 __EGL_DISPATCH_FUNC_INDICES[i] = -1;
37 }
38 }
39
__eglSetDispatchIndex(const char * name,int dispatchIndex)40 void __eglSetDispatchIndex(const char *name, int dispatchIndex)
41 {
42 int index = FindProcIndex(name);
43 __EGL_DISPATCH_FUNC_INDICES[index] = dispatchIndex;
44 }
45
__eglDispatchFindDispatchFunction(const char * name)46 void *__eglDispatchFindDispatchFunction(const char *name)
47 {
48 int index = FindProcIndex(name);
49 return (void *) __EGL_DISPATCH_FUNCS[index];
50 }
51
FetchVendorFunc(__EGLvendorInfo * vendor,int index,EGLint errorCode)52 static __eglMustCastToProperFunctionPointerType FetchVendorFunc(__EGLvendorInfo *vendor,
53 int index, EGLint errorCode)
54 {
55 __eglMustCastToProperFunctionPointerType func = NULL;
56
57 if (vendor != NULL) {
58 func = exports->fetchDispatchEntry(vendor, __EGL_DISPATCH_FUNC_INDICES[index]);
59 }
60 if (func == NULL) {
61 if (errorCode != EGL_SUCCESS) {
62 // Since we have no vendor, the follow-up eglGetError() call will
63 // end up using the GLVND error code. Set it here.
64 if (vendor == NULL) {
65 exports->setEGLError(errorCode);
66 }
67 _eglError(errorCode, __EGL_DISPATCH_FUNC_NAMES[index]);
68 }
69 return NULL;
70 }
71
72 if (!exports->setLastVendor(vendor)) {
73 // Don't bother trying to set an error code in libglvnd. If
74 // setLastVendor failed, then setEGLError would also fail.
75 _eglError(errorCode, __EGL_DISPATCH_FUNC_NAMES[index]);
76 return NULL;
77 }
78
79 return func;
80 }
81
__eglDispatchFetchByCurrent(int index)82 __eglMustCastToProperFunctionPointerType __eglDispatchFetchByCurrent(int index)
83 {
84 __EGLvendorInfo *vendor;
85
86 // Note: This is only used for the eglWait* functions. For those, if
87 // there's no current context, then they're supposed to do nothing but
88 // return success.
89 exports->threadInit();
90 vendor = exports->getCurrentVendor();
91 return FetchVendorFunc(vendor, index, EGL_SUCCESS);
92 }
93
__eglDispatchFetchByDisplay(EGLDisplay dpy,int index)94 __eglMustCastToProperFunctionPointerType __eglDispatchFetchByDisplay(EGLDisplay dpy, int index)
95 {
96 __EGLvendorInfo *vendor;
97
98 exports->threadInit();
99 vendor = exports->getVendorFromDisplay(dpy);
100 return FetchVendorFunc(vendor, index, EGL_BAD_DISPLAY);
101 }
102
__eglDispatchFetchByDevice(EGLDeviceEXT dev,int index)103 __eglMustCastToProperFunctionPointerType __eglDispatchFetchByDevice(EGLDeviceEXT dev, int index)
104 {
105 __EGLvendorInfo *vendor;
106
107 exports->threadInit();
108 vendor = exports->getVendorFromDevice(dev);
109 return FetchVendorFunc(vendor, index, EGL_BAD_DEVICE_EXT);
110 }
111
112