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 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 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 44 void __eglSetDispatchIndex(const char *name, int dispatchIndex) 45 { 46 int index = FindProcIndex(name); 47 __EGL_DISPATCH_FUNC_INDICES[index] = dispatchIndex; 48 } 49 50 void *__eglDispatchFindDispatchFunction(const char *name) 51 { 52 int index = FindProcIndex(name); 53 return (void *) __EGL_DISPATCH_FUNCS[index]; 54 } 55 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 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 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 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