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