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