xref: /aosp_15_r20/external/mesa3d/src/glx/g_glxglvnddispatchfuncs.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 #include <stdlib.h>
2 
3 #include "glxclient.h"
4 #include "glxglvnd.h"
5 #include "glxglvnddispatchfuncs.h"
6 #include "g_glxglvnddispatchindices.h"
7 
8 #include "GL/mesa_glinterop.h"
9 
10 const int DI_FUNCTION_COUNT = DI_LAST_INDEX;
11 /* Allocate an extra 'dummy' to ease lookup. See FindGLXFunction() */
12 int __glXDispatchTableIndices[DI_LAST_INDEX + 1];
13 const __GLXapiExports *__glXGLVNDAPIExports;
14 
15 const char * const __glXDispatchTableStrings[DI_LAST_INDEX] = {
16 #define __ATTRIB(field) \
17     [DI_##field] = "glX"#field
18 
19     __ATTRIB(BindSwapBarrierSGIX),
20     __ATTRIB(BindTexImageEXT),
21     // glXChooseFBConfig implemented by libglvnd
22     __ATTRIB(ChooseFBConfigSGIX),
23     // glXChooseVisual implemented by libglvnd
24     // glXCopyContext implemented by libglvnd
25     __ATTRIB(CopySubBufferMESA),
26     // glXCreateContext implemented by libglvnd
27     __ATTRIB(CreateContextAttribsARB),
28     __ATTRIB(CreateContextWithConfigSGIX),
29     __ATTRIB(CreateGLXPbufferSGIX),
30     // glXCreateGLXPixmap implemented by libglvnd
31     __ATTRIB(CreateGLXPixmapMESA),
32     __ATTRIB(CreateGLXPixmapWithConfigSGIX),
33     // glXCreateNewContext implemented by libglvnd
34     // glXCreatePbuffer implemented by libglvnd
35     // glXCreatePixmap implemented by libglvnd
36     // glXCreateWindow implemented by libglvnd
37     // glXDestroyContext implemented by libglvnd
38     __ATTRIB(DestroyGLXPbufferSGIX),
39     // glXDestroyGLXPixmap implemented by libglvnd
40     // glXDestroyPbuffer implemented by libglvnd
41     // glXDestroyPixmap implemented by libglvnd
42     // glXDestroyWindow implemented by libglvnd
43     // glXFreeContextEXT implemented by libglvnd
44     __ATTRIB(GLInteropExportObjectMESA),
45     __ATTRIB(GLInteropFlushObjectsMESA),
46     __ATTRIB(GLInteropQueryDeviceInfoMESA),
47     // glXGetClientString implemented by libglvnd
48     // glXGetConfig implemented by libglvnd
49     __ATTRIB(GetContextIDEXT),
50     // glXGetCurrentContext implemented by libglvnd
51     // glXGetCurrentDisplay implemented by libglvnd
52     __ATTRIB(GetCurrentDisplayEXT),
53     // glXGetCurrentDrawable implemented by libglvnd
54     // glXGetCurrentReadDrawable implemented by libglvnd
55     __ATTRIB(GetDriverConfig),
56     // glXGetFBConfigAttrib implemented by libglvnd
57     __ATTRIB(GetFBConfigAttribSGIX),
58     __ATTRIB(GetFBConfigFromVisualSGIX),
59     // glXGetFBConfigs implemented by libglvnd
60     __ATTRIB(GetMscRateOML),
61     // glXGetProcAddress implemented by libglvnd
62     // glXGetProcAddressARB implemented by libglvnd
63     __ATTRIB(GetScreenDriver),
64     // glXGetSelectedEvent implemented by libglvnd
65     __ATTRIB(GetSelectedEventSGIX),
66     __ATTRIB(GetSwapIntervalMESA),
67     __ATTRIB(GetSyncValuesOML),
68     __ATTRIB(GetVideoSyncSGI),
69     // glXGetVisualFromFBConfig implemented by libglvnd
70     __ATTRIB(GetVisualFromFBConfigSGIX),
71     // glXImportContextEXT implemented by libglvnd
72     // glXIsDirect implemented by libglvnd
73     __ATTRIB(JoinSwapGroupSGIX),
74     // glXMakeContextCurrent implemented by libglvnd
75     // glXMakeCurrent implemented by libglvnd
76     // glXQueryContext implemented by libglvnd
77     __ATTRIB(QueryContextInfoEXT),
78     __ATTRIB(QueryCurrentRendererIntegerMESA),
79     __ATTRIB(QueryCurrentRendererStringMESA),
80     // glXQueryDrawable implemented by libglvnd
81     // glXQueryExtension implemented by libglvnd
82     // glXQueryExtensionsString implemented by libglvnd
83     __ATTRIB(QueryGLXPbufferSGIX),
84     __ATTRIB(QueryMaxSwapBarriersSGIX),
85     __ATTRIB(QueryRendererIntegerMESA),
86     __ATTRIB(QueryRendererStringMESA),
87     // glXQueryServerString implemented by libglvnd
88     // glXQueryVersion implemented by libglvnd
89     __ATTRIB(ReleaseBuffersMESA),
90     __ATTRIB(ReleaseTexImageEXT),
91     // glXSelectEvent implemented by libglvnd
92     __ATTRIB(SelectEventSGIX),
93     // glXSwapBuffers implemented by libglvnd
94     __ATTRIB(SwapBuffersMscOML),
95     __ATTRIB(SwapIntervalEXT),
96     __ATTRIB(SwapIntervalMESA),
97     __ATTRIB(SwapIntervalSGI),
98     // glXUseXFont implemented by libglvnd
99     __ATTRIB(WaitForMscOML),
100     __ATTRIB(WaitForSbcOML),
101     // glXWaitGL implemented by libglvnd
102     __ATTRIB(WaitVideoSyncSGI),
103     // glXWaitX implemented by libglvnd
104 
105 #undef __ATTRIB
106 };
107 
108 #define __FETCH_FUNCTION_PTR(func_name) \
109     p##func_name = (void *) \
110         __VND->fetchDispatchEntry(dd, __glXDispatchTableIndices[DI_##func_name])
111 
112 
dispatch_BindTexImageEXT(Display * dpy,GLXDrawable drawable,int buffer,const int * attrib_list)113 static void dispatch_BindTexImageEXT(Display *dpy, GLXDrawable drawable,
114                                      int buffer, const int *attrib_list)
115 {
116     PFNGLXBINDTEXIMAGEEXTPROC pBindTexImageEXT;
117     __GLXvendorInfo *dd;
118 
119     dd = GetDispatchFromDrawable(dpy, drawable);
120     if (dd == NULL)
121         return;
122 
123     __FETCH_FUNCTION_PTR(BindTexImageEXT);
124     if (pBindTexImageEXT == NULL)
125         return;
126 
127     pBindTexImageEXT(dpy, drawable, buffer, attrib_list);
128 }
129 
130 
131 
dispatch_ChooseFBConfigSGIX(Display * dpy,int screen,int * attrib_list,int * nelements)132 static GLXFBConfigSGIX *dispatch_ChooseFBConfigSGIX(Display *dpy, int screen,
133                                                     int *attrib_list,
134                                                     int *nelements)
135 {
136     PFNGLXCHOOSEFBCONFIGSGIXPROC pChooseFBConfigSGIX;
137     __GLXvendorInfo *dd;
138     GLXFBConfigSGIX *ret;
139 
140     dd = __VND->getDynDispatch(dpy, screen);
141     if (dd == NULL)
142         return NULL;
143 
144     __FETCH_FUNCTION_PTR(ChooseFBConfigSGIX);
145     if (pChooseFBConfigSGIX == NULL)
146         return NULL;
147 
148     ret = pChooseFBConfigSGIX(dpy, screen, attrib_list, nelements);
149     if (AddFBConfigsMapping(dpy, ret, nelements, dd)) {
150         free(ret);
151         return NULL;
152     }
153 
154     return ret;
155 }
156 
157 
158 
dispatch_CreateContextAttribsARB(Display * dpy,GLXFBConfig config,GLXContext share_list,Bool direct,const int * attrib_list)159 static GLXContext dispatch_CreateContextAttribsARB(Display *dpy,
160                                                    GLXFBConfig config,
161                                                    GLXContext share_list,
162                                                    Bool direct,
163                                                    const int *attrib_list)
164 {
165     PFNGLXCREATECONTEXTATTRIBSARBPROC pCreateContextAttribsARB;
166     __GLXvendorInfo *dd = NULL;
167     GLXContext ret;
168 
169     if (config) {
170        dd = GetDispatchFromFBConfig(dpy, config);
171     } else if (attrib_list) {
172        int i, screen;
173 
174        for (i = 0; attrib_list[i * 2] != None; i++) {
175           if (attrib_list[i * 2] == GLX_SCREEN) {
176              screen = attrib_list[i * 2 + 1];
177              dd = GetDispatchFromDrawable(dpy, RootWindow(dpy, screen));
178              break;
179           }
180        }
181     }
182     if (dd == NULL)
183         return None;
184 
185     __FETCH_FUNCTION_PTR(CreateContextAttribsARB);
186     if (pCreateContextAttribsARB == NULL)
187         return None;
188 
189     ret = pCreateContextAttribsARB(dpy, config, share_list, direct, attrib_list);
190     if (AddContextMapping(dpy, ret, dd)) {
191         /* XXX: Call glXDestroyContext which lives in libglvnd. If we're not
192          * allowed to call it from here, should we extend __glXDispatchTableIndices ?
193          */
194         return None;
195     }
196 
197     return ret;
198 }
199 
200 
201 
dispatch_CreateContextWithConfigSGIX(Display * dpy,GLXFBConfigSGIX config,int render_type,GLXContext share_list,Bool direct)202 static GLXContext dispatch_CreateContextWithConfigSGIX(Display *dpy,
203                                                        GLXFBConfigSGIX config,
204                                                        int render_type,
205                                                        GLXContext share_list,
206                                                        Bool direct)
207 {
208     PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC pCreateContextWithConfigSGIX;
209     __GLXvendorInfo *dd;
210     GLXContext ret;
211 
212     dd = GetDispatchFromFBConfig(dpy, config);
213     if (dd == NULL)
214         return None;
215 
216     __FETCH_FUNCTION_PTR(CreateContextWithConfigSGIX);
217     if (pCreateContextWithConfigSGIX == NULL)
218         return None;
219 
220     ret = pCreateContextWithConfigSGIX(dpy, config, render_type, share_list, direct);
221     if (AddContextMapping(dpy, ret, dd)) {
222         /* XXX: Call glXDestroyContext which lives in libglvnd. If we're not
223          * allowed to call it from here, should we extend __glXDispatchTableIndices ?
224          */
225         return None;
226     }
227 
228     return ret;
229 }
230 
231 
232 
dispatch_CreateGLXPbufferSGIX(Display * dpy,GLXFBConfig config,unsigned int width,unsigned int height,int * attrib_list)233 static GLXPbuffer dispatch_CreateGLXPbufferSGIX(Display *dpy,
234                                                 GLXFBConfig config,
235                                                 unsigned int width,
236                                                 unsigned int height,
237                                                 int *attrib_list)
238 {
239     PFNGLXCREATEGLXPBUFFERSGIXPROC pCreateGLXPbufferSGIX;
240     __GLXvendorInfo *dd;
241     GLXPbuffer ret;
242 
243     dd = GetDispatchFromFBConfig(dpy, config);
244     if (dd == NULL)
245         return None;
246 
247     __FETCH_FUNCTION_PTR(CreateGLXPbufferSGIX);
248     if (pCreateGLXPbufferSGIX == NULL)
249         return None;
250 
251     ret = pCreateGLXPbufferSGIX(dpy, config, width, height, attrib_list);
252     if (AddDrawableMapping(dpy, ret, dd)) {
253         PFNGLXDESTROYGLXPBUFFERSGIXPROC pDestroyGLXPbufferSGIX;
254 
255         __FETCH_FUNCTION_PTR(DestroyGLXPbufferSGIX);
256         if (pDestroyGLXPbufferSGIX)
257             pDestroyGLXPbufferSGIX(dpy, ret);
258 
259         return None;
260     }
261 
262     return ret;
263 }
264 
265 
266 
dispatch_CreateGLXPixmapWithConfigSGIX(Display * dpy,GLXFBConfigSGIX config,Pixmap pixmap)267 static GLXPixmap dispatch_CreateGLXPixmapWithConfigSGIX(Display *dpy,
268                                                         GLXFBConfigSGIX config,
269                                                         Pixmap pixmap)
270 {
271     PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC pCreateGLXPixmapWithConfigSGIX;
272     __GLXvendorInfo *dd;
273     GLXPixmap ret;
274 
275     dd = GetDispatchFromFBConfig(dpy, config);
276     if (dd == NULL)
277         return None;
278 
279     __FETCH_FUNCTION_PTR(CreateGLXPixmapWithConfigSGIX);
280     if (pCreateGLXPixmapWithConfigSGIX == NULL)
281         return None;
282 
283     ret = pCreateGLXPixmapWithConfigSGIX(dpy, config, pixmap);
284     if (AddDrawableMapping(dpy, ret, dd)) {
285         /* XXX: Call glXDestroyGLXPixmap which lives in libglvnd. If we're not
286          * allowed to call it from here, should we extend __glXDispatchTableIndices ?
287          */
288         return None;
289     }
290 
291     return ret;
292 }
293 
294 
295 
dispatch_DestroyGLXPbufferSGIX(Display * dpy,GLXPbuffer pbuf)296 static void dispatch_DestroyGLXPbufferSGIX(Display *dpy, GLXPbuffer pbuf)
297 {
298     PFNGLXDESTROYGLXPBUFFERSGIXPROC pDestroyGLXPbufferSGIX;
299     __GLXvendorInfo *dd;
300 
301     dd = GetDispatchFromDrawable(dpy, pbuf);
302     if (dd == NULL)
303         return;
304 
305     __FETCH_FUNCTION_PTR(DestroyGLXPbufferSGIX);
306     if (pDestroyGLXPbufferSGIX == NULL)
307         return;
308 
309     pDestroyGLXPbufferSGIX(dpy, pbuf);
310 }
311 
312 
313 
dispatch_GLInteropExportObjectMESA(Display * dpy,GLXContext ctx,struct mesa_glinterop_export_in * in,struct mesa_glinterop_export_out * out)314 static int dispatch_GLInteropExportObjectMESA(Display *dpy, GLXContext ctx,
315                                               struct mesa_glinterop_export_in *in,
316                                               struct mesa_glinterop_export_out *out)
317 {
318     PFNMESAGLINTEROPGLXEXPORTOBJECTPROC pGLInteropExportObjectMESA;
319     __GLXvendorInfo *dd;
320 
321     dd = GetDispatchFromContext(ctx);
322     if (dd == NULL)
323         return 0;
324 
325     __FETCH_FUNCTION_PTR(GLInteropExportObjectMESA);
326     if (pGLInteropExportObjectMESA == NULL)
327         return 0;
328 
329     return pGLInteropExportObjectMESA(dpy, ctx, in, out);
330 }
331 
332 
dispatch_GLInteropFlushObjectsMESA(Display * dpy,GLXContext ctx,unsigned count,struct mesa_glinterop_export_in * resources,struct mesa_glinterop_flush_out * out)333 static int dispatch_GLInteropFlushObjectsMESA(Display *dpy, GLXContext ctx,
334                                               unsigned count,
335                                               struct mesa_glinterop_export_in *resources,
336                                               struct mesa_glinterop_flush_out *out)
337 {
338     PFNMESAGLINTEROPGLXFLUSHOBJECTSPROC pGLInteropFlushObjectsMESA;
339     __GLXvendorInfo *dd;
340 
341     dd = GetDispatchFromContext(ctx);
342     if (dd == NULL)
343         return 0;
344 
345     __FETCH_FUNCTION_PTR(GLInteropFlushObjectsMESA);
346     if (pGLInteropFlushObjectsMESA == NULL)
347         return 0;
348 
349     return pGLInteropFlushObjectsMESA(dpy, ctx, count, resources, out);
350 }
351 
352 
dispatch_GLInteropQueryDeviceInfoMESA(Display * dpy,GLXContext ctx,struct mesa_glinterop_device_info * out)353 static int dispatch_GLInteropQueryDeviceInfoMESA(Display *dpy, GLXContext ctx,
354                                                  struct mesa_glinterop_device_info *out)
355 {
356     PFNMESAGLINTEROPGLXQUERYDEVICEINFOPROC pGLInteropQueryDeviceInfoMESA;
357     __GLXvendorInfo *dd;
358 
359     dd = GetDispatchFromContext(ctx);
360     if (dd == NULL)
361         return 0;
362 
363     __FETCH_FUNCTION_PTR(GLInteropQueryDeviceInfoMESA);
364     if (pGLInteropQueryDeviceInfoMESA == NULL)
365         return 0;
366 
367     return pGLInteropQueryDeviceInfoMESA(dpy, ctx, out);
368 }
369 
370 
dispatch_GetContextIDEXT(const GLXContext ctx)371 static GLXContextID dispatch_GetContextIDEXT(const GLXContext ctx)
372 {
373     PFNGLXGETCONTEXTIDEXTPROC pGetContextIDEXT;
374     __GLXvendorInfo *dd;
375 
376     dd = GetDispatchFromContext(ctx);
377     if (dd == NULL)
378         return None;
379 
380     __FETCH_FUNCTION_PTR(GetContextIDEXT);
381     if (pGetContextIDEXT == NULL)
382         return None;
383 
384     return pGetContextIDEXT(ctx);
385 }
386 
387 
388 
dispatch_GetCurrentDisplayEXT(void)389 static Display *dispatch_GetCurrentDisplayEXT(void)
390 {
391     PFNGLXGETCURRENTDISPLAYEXTPROC pGetCurrentDisplayEXT;
392     __GLXvendorInfo *dd;
393 
394     if (!__VND->getCurrentContext())
395         return NULL;
396 
397     dd = __VND->getCurrentDynDispatch();
398     if (dd == NULL)
399         return NULL;
400 
401     __FETCH_FUNCTION_PTR(GetCurrentDisplayEXT);
402     if (pGetCurrentDisplayEXT == NULL)
403         return NULL;
404 
405     return pGetCurrentDisplayEXT();
406 }
407 
408 
409 
dispatch_GetDriverConfig(const char * driverName)410 static const char *dispatch_GetDriverConfig(const char *driverName)
411 {
412 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
413     /*
414      * The options are constant for a given driverName, so we do not need
415      * a context (and apps expect to be able to call this without one).
416      */
417     return glXGetDriverConfig(driverName);
418 #else
419     return NULL;
420 #endif
421 }
422 
423 
424 
dispatch_GetFBConfigAttribSGIX(Display * dpy,GLXFBConfigSGIX config,int attribute,int * value_return)425 static int dispatch_GetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config,
426                                           int attribute, int *value_return)
427 {
428     PFNGLXGETFBCONFIGATTRIBSGIXPROC pGetFBConfigAttribSGIX;
429     __GLXvendorInfo *dd;
430 
431     dd = GetDispatchFromFBConfig(dpy, config);
432     if (dd == NULL)
433         return GLX_NO_EXTENSION;
434 
435     __FETCH_FUNCTION_PTR(GetFBConfigAttribSGIX);
436     if (pGetFBConfigAttribSGIX == NULL)
437         return GLX_NO_EXTENSION;
438 
439     return pGetFBConfigAttribSGIX(dpy, config, attribute, value_return);
440 }
441 
442 
443 
dispatch_GetFBConfigFromVisualSGIX(Display * dpy,XVisualInfo * vis)444 static GLXFBConfigSGIX dispatch_GetFBConfigFromVisualSGIX(Display *dpy,
445                                                           XVisualInfo *vis)
446 {
447     PFNGLXGETFBCONFIGFROMVISUALSGIXPROC pGetFBConfigFromVisualSGIX;
448     __GLXvendorInfo *dd;
449     GLXFBConfigSGIX ret = NULL;
450 
451     dd = GetDispatchFromVisual(dpy, vis);
452     if (dd == NULL)
453         return NULL;
454 
455     __FETCH_FUNCTION_PTR(GetFBConfigFromVisualSGIX);
456     if (pGetFBConfigFromVisualSGIX == NULL)
457         return NULL;
458 
459     ret = pGetFBConfigFromVisualSGIX(dpy, vis);
460     if (AddFBConfigMapping(dpy, ret, dd))
461         /* XXX: dealloc ret ? */
462         return NULL;
463 
464     return ret;
465 }
466 
467 
468 
dispatch_GetSelectedEventSGIX(Display * dpy,GLXDrawable drawable,unsigned long * mask)469 static void dispatch_GetSelectedEventSGIX(Display *dpy, GLXDrawable drawable,
470                                           unsigned long *mask)
471 {
472     PFNGLXGETSELECTEDEVENTSGIXPROC pGetSelectedEventSGIX;
473     __GLXvendorInfo *dd;
474 
475     dd = GetDispatchFromDrawable(dpy, drawable);
476     if (dd == NULL)
477         return;
478 
479     __FETCH_FUNCTION_PTR(GetSelectedEventSGIX);
480     if (pGetSelectedEventSGIX == NULL)
481         return;
482 
483     pGetSelectedEventSGIX(dpy, drawable, mask);
484 }
485 
486 
487 
dispatch_GetVideoSyncSGI(unsigned int * count)488 static int dispatch_GetVideoSyncSGI(unsigned int *count)
489 {
490     PFNGLXGETVIDEOSYNCSGIPROC pGetVideoSyncSGI;
491     __GLXvendorInfo *dd;
492 
493     if (!__VND->getCurrentContext())
494         return GLX_BAD_CONTEXT;
495 
496     dd = __VND->getCurrentDynDispatch();
497     if (dd == NULL)
498         return GLX_NO_EXTENSION;
499 
500     __FETCH_FUNCTION_PTR(GetVideoSyncSGI);
501     if (pGetVideoSyncSGI == NULL)
502         return GLX_NO_EXTENSION;
503 
504     return pGetVideoSyncSGI(count);
505 }
506 
507 
508 
dispatch_GetVisualFromFBConfigSGIX(Display * dpy,GLXFBConfigSGIX config)509 static XVisualInfo *dispatch_GetVisualFromFBConfigSGIX(Display *dpy,
510                                                        GLXFBConfigSGIX config)
511 {
512     PFNGLXGETVISUALFROMFBCONFIGSGIXPROC pGetVisualFromFBConfigSGIX;
513     __GLXvendorInfo *dd;
514 
515     dd = GetDispatchFromFBConfig(dpy, config);
516     if (dd == NULL)
517         return NULL;
518 
519     __FETCH_FUNCTION_PTR(GetVisualFromFBConfigSGIX);
520     if (pGetVisualFromFBConfigSGIX == NULL)
521         return NULL;
522 
523     return pGetVisualFromFBConfigSGIX(dpy, config);
524 }
525 
526 
527 
dispatch_QueryContextInfoEXT(Display * dpy,GLXContext ctx,int attribute,int * value)528 static int dispatch_QueryContextInfoEXT(Display *dpy, GLXContext ctx,
529                                         int attribute, int *value)
530 {
531     PFNGLXQUERYCONTEXTINFOEXTPROC pQueryContextInfoEXT;
532     __GLXvendorInfo *dd;
533 
534     dd = GetDispatchFromContext(ctx);
535     if (dd == NULL)
536         return GLX_NO_EXTENSION;
537 
538     __FETCH_FUNCTION_PTR(QueryContextInfoEXT);
539     if (pQueryContextInfoEXT == NULL)
540         return GLX_NO_EXTENSION;
541 
542     return pQueryContextInfoEXT(dpy, ctx, attribute, value);
543 }
544 
545 
546 
dispatch_QueryGLXPbufferSGIX(Display * dpy,GLXPbuffer pbuf,int attribute,unsigned int * value)547 static void dispatch_QueryGLXPbufferSGIX(Display *dpy, GLXPbuffer pbuf,
548                                          int attribute, unsigned int *value)
549 {
550     PFNGLXQUERYGLXPBUFFERSGIXPROC pQueryGLXPbufferSGIX;
551     __GLXvendorInfo *dd;
552 
553     dd = GetDispatchFromDrawable(dpy, pbuf);
554     if (dd == NULL)
555         return;
556 
557     __FETCH_FUNCTION_PTR(QueryGLXPbufferSGIX);
558     if (pQueryGLXPbufferSGIX == NULL)
559         return;
560 
561     pQueryGLXPbufferSGIX(dpy, pbuf, attribute, value);
562 }
563 
564 
565 
dispatch_ReleaseTexImageEXT(Display * dpy,GLXDrawable drawable,int buffer)566 static void dispatch_ReleaseTexImageEXT(Display *dpy, GLXDrawable drawable,
567                                         int buffer)
568 {
569     PFNGLXRELEASETEXIMAGEEXTPROC pReleaseTexImageEXT;
570     __GLXvendorInfo *dd;
571 
572     dd = GetDispatchFromDrawable(dpy, drawable);
573     if (dd == NULL)
574         return;
575 
576     __FETCH_FUNCTION_PTR(ReleaseTexImageEXT);
577     if (pReleaseTexImageEXT == NULL)
578         return;
579 
580     pReleaseTexImageEXT(dpy, drawable, buffer);
581 }
582 
583 
584 
dispatch_SelectEventSGIX(Display * dpy,GLXDrawable drawable,unsigned long mask)585 static void dispatch_SelectEventSGIX(Display *dpy, GLXDrawable drawable,
586                                      unsigned long mask)
587 {
588     PFNGLXSELECTEVENTSGIXPROC pSelectEventSGIX;
589     __GLXvendorInfo *dd;
590 
591     dd = GetDispatchFromDrawable(dpy, drawable);
592     if (dd == NULL)
593         return;
594 
595     __FETCH_FUNCTION_PTR(SelectEventSGIX);
596     if (pSelectEventSGIX == NULL)
597         return;
598 
599     pSelectEventSGIX(dpy, drawable, mask);
600 }
601 
602 
603 
dispatch_SwapIntervalSGI(int interval)604 static int dispatch_SwapIntervalSGI(int interval)
605 {
606     PFNGLXSWAPINTERVALSGIPROC pSwapIntervalSGI;
607     __GLXvendorInfo *dd;
608 
609     if (!__VND->getCurrentContext())
610         return GLX_BAD_CONTEXT;
611 
612     dd = __VND->getCurrentDynDispatch();
613     if (dd == NULL)
614         return GLX_NO_EXTENSION;
615 
616     __FETCH_FUNCTION_PTR(SwapIntervalSGI);
617     if (pSwapIntervalSGI == NULL)
618         return GLX_NO_EXTENSION;
619 
620     return pSwapIntervalSGI(interval);
621 }
622 
623 
624 
dispatch_WaitVideoSyncSGI(int divisor,int remainder,unsigned int * count)625 static int dispatch_WaitVideoSyncSGI(int divisor, int remainder,
626                                      unsigned int *count)
627 {
628     PFNGLXWAITVIDEOSYNCSGIPROC pWaitVideoSyncSGI;
629     __GLXvendorInfo *dd;
630 
631     if (!__VND->getCurrentContext())
632         return GLX_BAD_CONTEXT;
633 
634     dd = __VND->getCurrentDynDispatch();
635     if (dd == NULL)
636         return GLX_NO_EXTENSION;
637 
638     __FETCH_FUNCTION_PTR(WaitVideoSyncSGI);
639     if (pWaitVideoSyncSGI == NULL)
640         return GLX_NO_EXTENSION;
641 
642     return pWaitVideoSyncSGI(divisor, remainder, count);
643 }
644 
645 
646 
dispatch_BindSwapBarrierSGIX(Display * dpy,GLXDrawable drawable,int barrier)647 static void dispatch_BindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable,
648                                             int barrier)
649 {
650     PFNGLXBINDSWAPBARRIERSGIXPROC pBindSwapBarrierSGIX;
651     __GLXvendorInfo *dd;
652 
653     dd = GetDispatchFromDrawable(dpy, drawable);
654     if (dd == NULL)
655         return;
656 
657     __FETCH_FUNCTION_PTR(BindSwapBarrierSGIX);
658     if (pBindSwapBarrierSGIX == NULL)
659         return;
660 
661     pBindSwapBarrierSGIX(dpy, drawable, barrier);
662 }
663 
664 
665 
dispatch_CopySubBufferMESA(Display * dpy,GLXDrawable drawable,int x,int y,int width,int height)666 static void dispatch_CopySubBufferMESA(Display *dpy, GLXDrawable drawable,
667                                           int x, int y, int width, int height)
668 {
669     PFNGLXCOPYSUBBUFFERMESAPROC pCopySubBufferMESA;
670     __GLXvendorInfo *dd;
671 
672     dd = GetDispatchFromDrawable(dpy, drawable);
673     if (dd == NULL)
674         return;
675 
676     __FETCH_FUNCTION_PTR(CopySubBufferMESA);
677     if (pCopySubBufferMESA == NULL)
678         return;
679 
680     pCopySubBufferMESA(dpy, drawable, x, y, width, height);
681 }
682 
683 
684 
dispatch_CreateGLXPixmapMESA(Display * dpy,XVisualInfo * visinfo,Pixmap pixmap,Colormap cmap)685 static GLXPixmap dispatch_CreateGLXPixmapMESA(Display *dpy,
686                                                  XVisualInfo *visinfo,
687                                                  Pixmap pixmap, Colormap cmap)
688 {
689     PFNGLXCREATEGLXPIXMAPMESAPROC pCreateGLXPixmapMESA;
690     __GLXvendorInfo *dd;
691     GLXPixmap ret;
692 
693     dd = GetDispatchFromVisual(dpy, visinfo);
694     if (dd == NULL)
695         return None;
696 
697     __FETCH_FUNCTION_PTR(CreateGLXPixmapMESA);
698     if (pCreateGLXPixmapMESA == NULL)
699         return None;
700 
701     ret = pCreateGLXPixmapMESA(dpy, visinfo, pixmap, cmap);
702     if (AddDrawableMapping(dpy, ret, dd)) {
703         /* XXX: Call glXDestroyGLXPixmap which lives in libglvnd. If we're not
704          * allowed to call it from here, should we extend __glXDispatchTableIndices ?
705          */
706         return None;
707     }
708 
709     return ret;
710 }
711 
712 
713 
dispatch_GetMscRateOML(Display * dpy,GLXDrawable drawable,int32_t * numerator,int32_t * denominator)714 static GLboolean dispatch_GetMscRateOML(Display *dpy, GLXDrawable drawable,
715                                            int32_t *numerator, int32_t *denominator)
716 {
717     PFNGLXGETMSCRATEOMLPROC pGetMscRateOML;
718     __GLXvendorInfo *dd;
719 
720     dd = GetDispatchFromDrawable(dpy, drawable);
721     if (dd == NULL)
722         return GL_FALSE;
723 
724     __FETCH_FUNCTION_PTR(GetMscRateOML);
725     if (pGetMscRateOML == NULL)
726         return GL_FALSE;
727 
728     return pGetMscRateOML(dpy, drawable, numerator, denominator);
729 }
730 
731 
732 
dispatch_GetScreenDriver(Display * dpy,int scrNum)733 static const char *dispatch_GetScreenDriver(Display *dpy, int scrNum)
734 {
735     typedef const char *(*fn_glXGetScreenDriver_ptr)(Display *dpy, int scrNum);
736     fn_glXGetScreenDriver_ptr pGetScreenDriver;
737     __GLXvendorInfo *dd;
738 
739     dd = __VND->getDynDispatch(dpy, scrNum);
740     if (dd == NULL)
741         return NULL;
742 
743     __FETCH_FUNCTION_PTR(GetScreenDriver);
744     if (pGetScreenDriver == NULL)
745         return NULL;
746 
747     return pGetScreenDriver(dpy, scrNum);
748 }
749 
750 
751 
dispatch_GetSwapIntervalMESA(void)752 static int dispatch_GetSwapIntervalMESA(void)
753 {
754     PFNGLXGETSWAPINTERVALMESAPROC pGetSwapIntervalMESA;
755     __GLXvendorInfo *dd;
756 
757     if (!__VND->getCurrentContext())
758         return GLX_BAD_CONTEXT;
759 
760     dd = __VND->getCurrentDynDispatch();
761     if (dd == NULL)
762         return 0;
763 
764     __FETCH_FUNCTION_PTR(GetSwapIntervalMESA);
765     if (pGetSwapIntervalMESA == NULL)
766         return 0;
767 
768     return pGetSwapIntervalMESA();
769 }
770 
771 
772 
dispatch_GetSyncValuesOML(Display * dpy,GLXDrawable drawable,int64_t * ust,int64_t * msc,int64_t * sbc)773 static Bool dispatch_GetSyncValuesOML(Display *dpy, GLXDrawable drawable,
774                                          int64_t *ust, int64_t *msc, int64_t *sbc)
775 {
776     PFNGLXGETSYNCVALUESOMLPROC pGetSyncValuesOML;
777     __GLXvendorInfo *dd;
778 
779     dd = GetDispatchFromDrawable(dpy, drawable);
780     if (dd == NULL)
781         return False;
782 
783     __FETCH_FUNCTION_PTR(GetSyncValuesOML);
784     if (pGetSyncValuesOML == NULL)
785         return False;
786 
787     return pGetSyncValuesOML(dpy, drawable, ust, msc, sbc);
788 }
789 
790 
791 
dispatch_JoinSwapGroupSGIX(Display * dpy,GLXDrawable drawable,GLXDrawable member)792 static void dispatch_JoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable,
793                                           GLXDrawable member)
794 {
795     PFNGLXJOINSWAPGROUPSGIXPROC pJoinSwapGroupSGIX;
796     __GLXvendorInfo *dd;
797 
798     dd = GetDispatchFromDrawable(dpy, drawable);
799     if (dd == NULL)
800         return;
801 
802     __FETCH_FUNCTION_PTR(JoinSwapGroupSGIX);
803     if (pJoinSwapGroupSGIX == NULL)
804         return;
805 
806     pJoinSwapGroupSGIX(dpy, drawable, member);
807 }
808 
809 
810 
dispatch_QueryCurrentRendererIntegerMESA(int attribute,unsigned int * value)811 static Bool dispatch_QueryCurrentRendererIntegerMESA(int attribute,
812                                                         unsigned int *value)
813 {
814     PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC pQueryCurrentRendererIntegerMESA;
815     __GLXvendorInfo *dd;
816 
817     if (!__VND->getCurrentContext())
818         return False;
819 
820     dd = __VND->getCurrentDynDispatch();
821     if (dd == NULL)
822         return False;
823 
824     __FETCH_FUNCTION_PTR(QueryCurrentRendererIntegerMESA);
825     if (pQueryCurrentRendererIntegerMESA == NULL)
826         return False;
827 
828     return pQueryCurrentRendererIntegerMESA(attribute, value);
829 }
830 
831 
832 
dispatch_QueryCurrentRendererStringMESA(int attribute)833 static const char *dispatch_QueryCurrentRendererStringMESA(int attribute)
834 {
835     PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC pQueryCurrentRendererStringMESA;
836     __GLXvendorInfo *dd;
837 
838     if (!__VND->getCurrentContext())
839         return NULL;
840 
841     dd = __VND->getCurrentDynDispatch();
842     if (dd == NULL)
843         return NULL;
844 
845     __FETCH_FUNCTION_PTR(QueryCurrentRendererStringMESA);
846     if (pQueryCurrentRendererStringMESA == NULL)
847         return NULL;
848 
849     return pQueryCurrentRendererStringMESA(attribute);
850 }
851 
852 
853 
dispatch_QueryMaxSwapBarriersSGIX(Display * dpy,int screen,int * max)854 static Bool dispatch_QueryMaxSwapBarriersSGIX(Display *dpy, int screen,
855                                                  int *max)
856 {
857     PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC pQueryMaxSwapBarriersSGIX;
858     __GLXvendorInfo *dd;
859 
860     dd = __VND->getDynDispatch(dpy, screen);
861     if (dd == NULL)
862         return False;
863 
864     __FETCH_FUNCTION_PTR(QueryMaxSwapBarriersSGIX);
865     if (pQueryMaxSwapBarriersSGIX == NULL)
866         return False;
867 
868     return pQueryMaxSwapBarriersSGIX(dpy, screen, max);
869 }
870 
871 
872 
dispatch_QueryRendererIntegerMESA(Display * dpy,int screen,int renderer,int attribute,unsigned int * value)873 static Bool dispatch_QueryRendererIntegerMESA(Display *dpy, int screen,
874                                                  int renderer, int attribute,
875                                                  unsigned int *value)
876 {
877     PFNGLXQUERYRENDERERINTEGERMESAPROC pQueryRendererIntegerMESA;
878     __GLXvendorInfo *dd;
879 
880     dd = __VND->getDynDispatch(dpy, screen);
881     if (dd == NULL)
882         return False;
883 
884     __FETCH_FUNCTION_PTR(QueryRendererIntegerMESA);
885     if (pQueryRendererIntegerMESA == NULL)
886         return False;
887 
888     return pQueryRendererIntegerMESA(dpy, screen, renderer, attribute, value);
889 }
890 
891 
892 
dispatch_QueryRendererStringMESA(Display * dpy,int screen,int renderer,int attribute)893 static const char *dispatch_QueryRendererStringMESA(Display *dpy, int screen,
894                                                        int renderer, int attribute)
895 {
896     PFNGLXQUERYRENDERERSTRINGMESAPROC pQueryRendererStringMESA;
897     __GLXvendorInfo *dd = NULL;
898 
899     dd = __VND->getDynDispatch(dpy, screen);
900     if (dd == NULL)
901         return NULL;
902 
903     __FETCH_FUNCTION_PTR(QueryRendererStringMESA);
904     if (pQueryRendererStringMESA == NULL)
905         return NULL;
906 
907     return pQueryRendererStringMESA(dpy, screen, renderer, attribute);
908 }
909 
910 
911 
dispatch_ReleaseBuffersMESA(Display * dpy,GLXDrawable d)912 static Bool dispatch_ReleaseBuffersMESA(Display *dpy, GLXDrawable d)
913 {
914     PFNGLXRELEASEBUFFERSMESAPROC pReleaseBuffersMESA;
915     __GLXvendorInfo *dd;
916 
917     dd = GetDispatchFromDrawable(dpy, d);
918     if (dd == NULL)
919         return False;
920 
921     __FETCH_FUNCTION_PTR(ReleaseBuffersMESA);
922     if (pReleaseBuffersMESA == NULL)
923         return False;
924 
925     return pReleaseBuffersMESA(dpy, d);
926 }
927 
928 
929 
dispatch_SwapBuffersMscOML(Display * dpy,GLXDrawable drawable,int64_t target_msc,int64_t divisor,int64_t remainder)930 static int64_t dispatch_SwapBuffersMscOML(Display *dpy, GLXDrawable drawable,
931                                              int64_t target_msc, int64_t divisor,
932                                              int64_t remainder)
933 {
934     PFNGLXSWAPBUFFERSMSCOMLPROC pSwapBuffersMscOML;
935     __GLXvendorInfo *dd;
936 
937     dd = GetDispatchFromDrawable(dpy, drawable);
938     if (dd == NULL)
939         return 0;
940 
941     __FETCH_FUNCTION_PTR(SwapBuffersMscOML);
942     if (pSwapBuffersMscOML == NULL)
943         return 0;
944 
945     return pSwapBuffersMscOML(dpy, drawable, target_msc, divisor, remainder);
946 }
947 
948 
949 
dispatch_SwapIntervalMESA(unsigned int interval)950 static int dispatch_SwapIntervalMESA(unsigned int interval)
951 {
952     PFNGLXSWAPINTERVALMESAPROC pSwapIntervalMESA;
953     __GLXvendorInfo *dd;
954 
955     if (!__VND->getCurrentContext())
956         return GLX_BAD_CONTEXT;
957 
958     dd = __VND->getCurrentDynDispatch();
959     if (dd == NULL)
960         return 0;
961 
962     __FETCH_FUNCTION_PTR(SwapIntervalMESA);
963     if (pSwapIntervalMESA == NULL)
964         return 0;
965 
966     return pSwapIntervalMESA(interval);
967 }
968 
969 
970 
dispatch_SwapIntervalEXT(Display * dpy,GLXDrawable drawable,int interval)971 static void dispatch_SwapIntervalEXT(Display *dpy, GLXDrawable drawable, int interval)
972 {
973     PFNGLXSWAPINTERVALEXTPROC pSwapIntervalEXT;
974     __GLXvendorInfo *dd;
975 
976     dd = GetDispatchFromDrawable(dpy, drawable);
977     if (dd == NULL)
978         return;
979 
980     __FETCH_FUNCTION_PTR(SwapIntervalEXT);
981     if (pSwapIntervalEXT == NULL)
982         return;
983 
984     pSwapIntervalEXT(dpy, drawable, interval);
985 }
986 
987 
988 
dispatch_WaitForMscOML(Display * dpy,GLXDrawable drawable,int64_t target_msc,int64_t divisor,int64_t remainder,int64_t * ust,int64_t * msc,int64_t * sbc)989 static Bool dispatch_WaitForMscOML(Display *dpy, GLXDrawable drawable,
990                                       int64_t target_msc, int64_t divisor,
991                                       int64_t remainder, int64_t *ust,
992                                       int64_t *msc, int64_t *sbc)
993 {
994     PFNGLXWAITFORMSCOMLPROC pWaitForMscOML;
995     __GLXvendorInfo *dd;
996 
997     dd = GetDispatchFromDrawable(dpy, drawable);
998     if (dd == NULL)
999         return False;
1000 
1001     __FETCH_FUNCTION_PTR(WaitForMscOML);
1002     if (pWaitForMscOML == NULL)
1003         return False;
1004 
1005     return pWaitForMscOML(dpy, drawable, target_msc, divisor, remainder, ust, msc, sbc);
1006 }
1007 
1008 
1009 
dispatch_WaitForSbcOML(Display * dpy,GLXDrawable drawable,int64_t target_sbc,int64_t * ust,int64_t * msc,int64_t * sbc)1010 static Bool dispatch_WaitForSbcOML(Display *dpy, GLXDrawable drawable,
1011                                       int64_t target_sbc, int64_t *ust,
1012                                       int64_t *msc, int64_t *sbc)
1013 {
1014     PFNGLXWAITFORSBCOMLPROC pWaitForSbcOML;
1015     __GLXvendorInfo *dd;
1016 
1017     dd = GetDispatchFromDrawable(dpy, drawable);
1018     if (dd == NULL)
1019         return False;
1020 
1021     __FETCH_FUNCTION_PTR(WaitForSbcOML);
1022     if (pWaitForSbcOML == NULL)
1023         return False;
1024 
1025     return pWaitForSbcOML(dpy, drawable, target_sbc, ust, msc, sbc);
1026 }
1027 
1028 #undef __FETCH_FUNCTION_PTR
1029 
1030 
1031 /* Allocate an extra 'dummy' to ease lookup. See FindGLXFunction() */
1032 const void * const __glXDispatchFunctions[DI_LAST_INDEX + 1] = {
1033 #define __ATTRIB(field) \
1034     [DI_##field] = (void *)dispatch_##field
1035 
1036     __ATTRIB(BindSwapBarrierSGIX),
1037     __ATTRIB(BindTexImageEXT),
1038     __ATTRIB(ChooseFBConfigSGIX),
1039     __ATTRIB(CopySubBufferMESA),
1040     __ATTRIB(CreateContextAttribsARB),
1041     __ATTRIB(CreateContextWithConfigSGIX),
1042     __ATTRIB(CreateGLXPbufferSGIX),
1043     __ATTRIB(CreateGLXPixmapMESA),
1044     __ATTRIB(CreateGLXPixmapWithConfigSGIX),
1045     __ATTRIB(DestroyGLXPbufferSGIX),
1046     __ATTRIB(GLInteropExportObjectMESA),
1047     __ATTRIB(GLInteropFlushObjectsMESA),
1048     __ATTRIB(GLInteropQueryDeviceInfoMESA),
1049     __ATTRIB(GetContextIDEXT),
1050     __ATTRIB(GetCurrentDisplayEXT),
1051     __ATTRIB(GetDriverConfig),
1052     __ATTRIB(GetFBConfigAttribSGIX),
1053     __ATTRIB(GetFBConfigFromVisualSGIX),
1054     __ATTRIB(GetMscRateOML),
1055     __ATTRIB(GetScreenDriver),
1056     __ATTRIB(GetSelectedEventSGIX),
1057     __ATTRIB(GetSwapIntervalMESA),
1058     __ATTRIB(GetSyncValuesOML),
1059     __ATTRIB(GetVideoSyncSGI),
1060     __ATTRIB(GetVisualFromFBConfigSGIX),
1061     __ATTRIB(JoinSwapGroupSGIX),
1062     __ATTRIB(QueryContextInfoEXT),
1063     __ATTRIB(QueryCurrentRendererIntegerMESA),
1064     __ATTRIB(QueryCurrentRendererStringMESA),
1065     __ATTRIB(QueryGLXPbufferSGIX),
1066     __ATTRIB(QueryMaxSwapBarriersSGIX),
1067     __ATTRIB(QueryRendererIntegerMESA),
1068     __ATTRIB(QueryRendererStringMESA),
1069     __ATTRIB(ReleaseBuffersMESA),
1070     __ATTRIB(ReleaseTexImageEXT),
1071     __ATTRIB(SelectEventSGIX),
1072     __ATTRIB(SwapBuffersMscOML),
1073     __ATTRIB(SwapIntervalEXT),
1074     __ATTRIB(SwapIntervalMESA),
1075     __ATTRIB(SwapIntervalSGI),
1076     __ATTRIB(WaitForMscOML),
1077     __ATTRIB(WaitForSbcOML),
1078     __ATTRIB(WaitVideoSyncSGI),
1079 
1080     [DI_LAST_INDEX] = NULL,
1081 #undef __ATTRIB
1082 };
1083