• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * (C) Copyright 2016, NVIDIA CORPORATION.
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * on the rights to use, copy, modify, merge, publish, distribute, sub
9  * license, and/or sell copies of the Software, and to permit persons to whom
10  * the Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
19  * IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Kyle Brenneman <kbrenneman@nvidia.com>
26  */
27 
28 #include "egldispatchstubs.h"
29 #include "g_egldispatchstubs.h"
30 
31 #include <string.h>
32 #include <stdlib.h>
33 
34 #include "eglcurrent.h"
35 
36 static const __EGLapiExports *exports;
37 
38 const int __EGL_DISPATCH_FUNC_COUNT = __EGL_DISPATCH_COUNT;
39 int __EGL_DISPATCH_FUNC_INDICES[__EGL_DISPATCH_COUNT + 1];
40 
Compare(const void * l,const void * r)41 static int Compare(const void *l, const void *r)
42 {
43     const char *s = *(const char **)r;
44     return strcmp(l, s);
45 }
46 
FindProcIndex(const char * name)47 static int FindProcIndex(const char *name)
48 {
49     const char **match = bsearch(name, __EGL_DISPATCH_FUNC_NAMES,
50             __EGL_DISPATCH_COUNT, sizeof(const char *), Compare);
51 
52     if (match == NULL)
53         return __EGL_DISPATCH_COUNT;
54 
55     return match - __EGL_DISPATCH_FUNC_NAMES;
56 }
57 
__eglInitDispatchStubs(const __EGLapiExports * exportsTable)58 void __eglInitDispatchStubs(const __EGLapiExports *exportsTable)
59 {
60     int i;
61     exports = exportsTable;
62     for (i=0; i<__EGL_DISPATCH_FUNC_COUNT; i++) {
63         __EGL_DISPATCH_FUNC_INDICES[i] = -1;
64     }
65 }
66 
__eglSetDispatchIndex(const char * name,int dispatchIndex)67 void __eglSetDispatchIndex(const char *name, int dispatchIndex)
68 {
69     int index = FindProcIndex(name);
70     __EGL_DISPATCH_FUNC_INDICES[index] = dispatchIndex;
71 }
72 
__eglDispatchFindDispatchFunction(const char * name)73 void *__eglDispatchFindDispatchFunction(const char *name)
74 {
75     int index = FindProcIndex(name);
76     return (void *) __EGL_DISPATCH_FUNCS[index];
77 }
78 
FetchVendorFunc(__EGLvendorInfo * vendor,int index,EGLint errorCode)79 static __eglMustCastToProperFunctionPointerType FetchVendorFunc(__EGLvendorInfo *vendor,
80         int index, EGLint errorCode)
81 {
82     __eglMustCastToProperFunctionPointerType func = NULL;
83 
84     if (vendor != NULL) {
85         func = exports->fetchDispatchEntry(vendor, __EGL_DISPATCH_FUNC_INDICES[index]);
86     }
87     if (func == NULL) {
88         if (errorCode != EGL_SUCCESS) {
89             // Since we have no vendor, the follow-up eglGetError() call will
90             // end up using the GLVND error code. Set it here.
91             if (vendor == NULL) {
92                 exports->setEGLError(errorCode);
93             }
94             _eglError(errorCode, __EGL_DISPATCH_FUNC_NAMES[index]);
95         }
96         return NULL;
97     }
98 
99     if (!exports->setLastVendor(vendor)) {
100         // Don't bother trying to set an error code in libglvnd. If
101         // setLastVendor failed, then setEGLError would also fail.
102         _eglError(errorCode, __EGL_DISPATCH_FUNC_NAMES[index]);
103         return NULL;
104     }
105 
106     return func;
107 }
108 
__eglDispatchFetchByCurrent(int index)109 __eglMustCastToProperFunctionPointerType __eglDispatchFetchByCurrent(int index)
110 {
111     __EGLvendorInfo *vendor;
112 
113     // Note: This is only used for the eglWait* functions. For those, if
114     // there's no current context, then they're supposed to do nothing but
115     // return success.
116     exports->threadInit();
117     vendor = exports->getCurrentVendor();
118     return FetchVendorFunc(vendor, index, EGL_SUCCESS);
119 }
120 
__eglDispatchFetchByDisplay(EGLDisplay dpy,int index)121 __eglMustCastToProperFunctionPointerType __eglDispatchFetchByDisplay(EGLDisplay dpy, int index)
122 {
123     __EGLvendorInfo *vendor;
124 
125     exports->threadInit();
126     vendor = exports->getVendorFromDisplay(dpy);
127     return FetchVendorFunc(vendor, index, EGL_BAD_DISPLAY);
128 }
129 
__eglDispatchFetchByDevice(EGLDeviceEXT dev,int index)130 __eglMustCastToProperFunctionPointerType __eglDispatchFetchByDevice(EGLDeviceEXT dev, int index)
131 {
132     __EGLvendorInfo *vendor;
133 
134     exports->threadInit();
135     vendor = exports->getVendorFromDevice(dev);
136     return FetchVendorFunc(vendor, index, EGL_BAD_DEVICE_EXT);
137 }
138 
139