• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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