libglvnd: Changes to 'upstream-unstable'
Makefile.am | 2
README.md | 111
configure.ac | 173
dbg_configure.sh | 3
include/GL/glxmd.h | 54
include/compiler.h | 12
include/glheader.h | 3
include/lkdhash.h | 43
m4/ax_check_enable_debug.m4 | 124
m4/ax_check_link_flag.m4 | 71
src/GL/GL.c | 42
src/GL/Makefile.am | 54
src/GL/libgl.c | 70
src/GL/libgl.h | 8
src/GLESv1/Makefile.am | 43
src/GLESv2/Makefile.am | 43
src/GLX/Makefile.am | 19
src/GLX/gen_stubs.pl | 275
src/GLX/glx_funcs.spec | 353
src/GLX/libglx.c | 1882
src/GLX/libglxabi.h | 400
src/GLX/libglxabipriv.h | 135
src/GLX/libglxcurrent.h | 54
src/GLX/libglxgl.h | 31
src/GLX/libglxgldispatch.c | 104
src/GLX/libglxgldispatch.h | 52
src/GLX/libglxmapping.c | 866
src/GLX/libglxmapping.h | 90
src/GLX/libglxnoop.c | 78
src/GLX/libglxnoopdefs.h | 286
src/GLX/libglxstring.c | 63
src/GLX/libglxstring.h | 44
src/GLX/libglxthread.h | 2
src/GLdispatch/GLdispatch.c | 681
src/GLdispatch/GLdispatch.h | 198
src/GLdispatch/GLdispatchABI.h | 147
src/GLdispatch/GLdispatchPrivate.h | 31
src/GLdispatch/Makefile.am | 14
src/GLdispatch/export_list.sym | 17
src/GLdispatch/vnd-glapi/Makefile.am | 38
src/GLdispatch/vnd-glapi/SConscript | 121
src/GLdispatch/vnd-glapi/entry_files.mk | 37
src/GLdispatch/vnd-glapi/mapi/Android.mk | 78
src/GLdispatch/vnd-glapi/mapi/Makefile.am | 46
src/GLdispatch/vnd-glapi/mapi/Makefile.sources | 36
src/GLdispatch/vnd-glapi/mapi/entry.c | 97
src/GLdispatch/vnd-glapi/mapi/entry.h | 67
src/GLdispatch/vnd-glapi/mapi/entry_armv7_tsd.c | 234
src/GLdispatch/vnd-glapi/mapi/entry_common.c | 76
src/GLdispatch/vnd-glapi/mapi/entry_common.h | 48
src/GLdispatch/vnd-glapi/mapi/entry_pure_c.c | 97
src/GLdispatch/vnd-glapi/mapi/entry_x86-64_tls.h | 112
src/GLdispatch/vnd-glapi/mapi/entry_x86_64_common.c | 79
src/GLdispatch/vnd-glapi/mapi/entry_x86_64_tls.c | 108
src/GLdispatch/vnd-glapi/mapi/entry_x86_64_tsd.c | 126
src/GLdispatch/vnd-glapi/mapi/entry_x86_tls.c | 141
src/GLdispatch/vnd-glapi/mapi/entry_x86_tls.h | 132
src/GLdispatch/vnd-glapi/mapi/entry_x86_tsd.c | 108
src/GLdispatch/vnd-glapi/mapi/entry_x86_tsd.h | 103
src/GLdispatch/vnd-glapi/mapi/es1api/ABI-check | 254
src/GLdispatch/vnd-glapi/mapi/es1api/Makefile.am | 66
src/GLdispatch/vnd-glapi/mapi/es1api/glesv1_cm.pc.in | 12
src/GLdispatch/vnd-glapi/mapi/es2api/ABI-check | 292
src/GLdispatch/vnd-glapi/mapi/es2api/Makefile.am | 70
src/GLdispatch/vnd-glapi/mapi/es2api/glesv2.pc.in | 12
src/GLdispatch/vnd-glapi/mapi/glapi/Makefile.am | 61
src/GLdispatch/vnd-glapi/mapi/glapi/Makefile.sources | 20
src/GLdispatch/vnd-glapi/mapi/glapi/SConscript | 102
src/GLdispatch/vnd-glapi/mapi/glapi/gen/AMD_draw_buffers_blend.xml | 38
src/GLdispatch/vnd-glapi/mapi/glapi/gen/APPLE_object_purgeable.xml | 37
src/GLdispatch/vnd-glapi/mapi/glapi/gen/APPLE_vertex_array_object.xml | 29
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_ES2_compatibility.xml | 58
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_ES3_compatibility.xml | 23
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_base_instance.xml | 43
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_blend_func_extended.xml | 32
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_color_buffer_float.xml | 24
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_copy_buffer.xml | 24
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_debug_output.xml | 93
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_depth_buffer_float.xml | 15
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_depth_clamp.xml | 12
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_draw_buffers.xml | 123
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_draw_buffers_blend.xml | 38
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_draw_elements_base_vertex.xml | 52
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_draw_instanced.xml | 49
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_framebuffer_object.xml | 300
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_geometry_shader4.xml | 57
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_get_program_binary.xml | 36
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_instanced_arrays.xml | 21
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_internalformat_query.xml | 21
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_invalidate_subdata.xml | 48
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_map_buffer_range.xml | 34
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_robustness.xml | 185
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_sampler_objects.xml | 96
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_seamless_cube_map.xml | 12
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_sync.xml | 84
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_texture_buffer_object.xml | 22
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_texture_buffer_range.xml | 22
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_texture_compression_rgtc.xml | 15
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_texture_cube_map_array.xml | 18
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_texture_float.xml | 36
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_texture_multisample.xml | 69
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_texture_rg.xml | 42
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_texture_rgb10_a2ui.xml | 12
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_texture_storage.xml | 67
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_texture_storage_multisample.xml | 31
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_uniform_buffer_object.xml | 97
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_vertex_array_object.xml | 34
src/GLdispatch/vnd-glapi/mapi/glapi/gen/ARB_vertex_type_2_10_10_10_rev.xml | 256
src/GLdispatch/vnd-glapi/mapi/glapi/gen/EXT_draw_buffers2.xml | 49
src/GLdispatch/vnd-glapi/mapi/glapi/gen/EXT_framebuffer_object.xml | 217
src/GLdispatch/vnd-glapi/mapi/glapi/gen/EXT_gpu_shader4.xml | 249
src/GLdispatch/vnd-glapi/mapi/glapi/gen/EXT_packed_depth_stencil.xml | 18
src/GLdispatch/vnd-glapi/mapi/glapi/gen/EXT_provoking_vertex.xml | 35
src/GLdispatch/vnd-glapi/mapi/glapi/gen/EXT_separate_shader_objects.xml | 26
src/GLdispatch/vnd-glapi/mapi/glapi/gen/EXT_texture_array.xml | 41
src/GLdispatch/vnd-glapi/mapi/glapi/gen/EXT_texture_integer.xml | 98
src/GLdispatch/vnd-glapi/mapi/glapi/gen/EXT_transform_feedback.xml | 118
src/GLdispatch/vnd-glapi/mapi/glapi/gen/GL3x.xml | 635
src/GLdispatch/vnd-glapi/mapi/glapi/gen/GL4x.xml | 757
src/GLdispatch/vnd-glapi/mapi/glapi/gen/Makefile.am | 285
src/GLdispatch/vnd-glapi/mapi/glapi/gen/NV_conditional_render.xml | 26
src/GLdispatch/vnd-glapi/mapi/glapi/gen/NV_primitive_restart.xml | 24
src/GLdispatch/vnd-glapi/mapi/glapi/gen/NV_texture_barrier.xml | 13
src/GLdispatch/vnd-glapi/mapi/glapi/gen/OES_EGL_image.xml | 22
src/GLdispatch/vnd-glapi/mapi/glapi/gen/OES_fixed_point.xml | 300
src/GLdispatch/vnd-glapi/mapi/glapi/gen/OES_single_precision.xml | 53
src/GLdispatch/vnd-glapi/mapi/glapi/gen/SConscript | 63
src/GLdispatch/vnd-glapi/mapi/glapi/gen/es_EXT.xml | 840
src/GLdispatch/vnd-glapi/mapi/glapi/gen/extension_helper.py | 324
src/GLdispatch/vnd-glapi/mapi/glapi/gen/glX_API.xml | 234
src/GLdispatch/vnd-glapi/mapi/glapi/gen/glX_XML.py | 570
src/GLdispatch/vnd-glapi/mapi/glapi/gen/glX_doc.py | 280
src/GLdispatch/vnd-glapi/mapi/glapi/gen/glX_proto_common.py | 95
src/GLdispatch/vnd-glapi/mapi/glapi/gen/glX_proto_recv.py | 555
src/GLdispatch/vnd-glapi/mapi/glapi/gen/glX_proto_send.py | 1122
src/GLdispatch/vnd-glapi/mapi/glapi/gen/glX_proto_size.py | 703
src/GLdispatch/vnd-glapi/mapi/glapi/gen/glX_server_table.py | 410
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_API.dtd | 146
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_API.xml |13005 --
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_SPARC_asm.py | 273
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_XML.py | 1078
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_and_es_API.xml | 328
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_and_glX_API.xml | 7
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_apitemp.py | 327
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_enums.py | 261
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_genexec.py | 219
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_gentable.py | 202
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_inittable.py | 198
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_offsets.py | 120
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_procs.py | 215
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_table.py | 238
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_x86-64_asm.py | 322
src/GLdispatch/vnd-glapi/mapi/glapi/gen/gl_x86_asm.py | 256
src/GLdispatch/vnd-glapi/mapi/glapi/gen/glapi_gen.mk | 57
src/GLdispatch/vnd-glapi/mapi/glapi/gen/license.py | 47
src/GLdispatch/vnd-glapi/mapi/glapi/gen/mesadef.py | 215
src/GLdispatch/vnd-glapi/mapi/glapi/gen/next_available_offset.sh | 39
src/GLdispatch/vnd-glapi/mapi/glapi/gen/remap_helper.py | 192
src/GLdispatch/vnd-glapi/mapi/glapi/gen/typeexpr.py | 292
src/GLdispatch/vnd-glapi/mapi/glapi/glapi.c | 75
src/GLdispatch/vnd-glapi/mapi/glapi/glapi.h | 240
src/GLdispatch/vnd-glapi/mapi/glapi/glapi_dispatch.c | 92
src/GLdispatch/vnd-glapi/mapi/glapi/glapi_entrypoint.c | 345
src/GLdispatch/vnd-glapi/mapi/glapi/glapi_getproc.c | 666
src/GLdispatch/vnd-glapi/mapi/glapi/glapi_nop.c | 121
src/GLdispatch/vnd-glapi/mapi/glapi/glapi_priv.h | 114
src/GLdispatch/vnd-glapi/mapi/glapi/glthread.c | 7
src/GLdispatch/vnd-glapi/mapi/glapi/glthread.h | 28
src/GLdispatch/vnd-glapi/mapi/glapi/tests/Makefile.am | 19
src/GLdispatch/vnd-glapi/mapi/glapi/tests/check_table.cpp | 1661
src/GLdispatch/vnd-glapi/mapi/mapi.c | 190
src/GLdispatch/vnd-glapi/mapi/mapi.h | 65
src/GLdispatch/vnd-glapi/mapi/mapi_abi.py | 9
src/GLdispatch/vnd-glapi/mapi/mapi_glapi.c | 157
src/GLdispatch/vnd-glapi/mapi/mapi_tmp.h | 13
src/GLdispatch/vnd-glapi/mapi/shared-glapi/Makefile.am | 32
src/GLdispatch/vnd-glapi/mapi/shared-glapi/SConscript | 121
src/GLdispatch/vnd-glapi/mapi/shared-glapi/tests/Makefile.am | 18
src/GLdispatch/vnd-glapi/mapi/shared-glapi/tests/check_table.cpp | 471
src/GLdispatch/vnd-glapi/mapi/stub.c | 262
src/GLdispatch/vnd-glapi/mapi/stub.h | 22
src/GLdispatch/vnd-glapi/mapi/table.h | 9
src/GLdispatch/vnd-glapi/mapi/u_current.c | 330
src/GLdispatch/vnd-glapi/mapi/u_current.h | 98
src/GLdispatch/vnd-glapi/mapi/u_current_tls.c | 66
src/GLdispatch/vnd-glapi/mapi/u_current_tsd.c | 89
src/GLdispatch/vnd-glapi/mapi/u_execmem.c | 78
src/GLdispatch/vnd-glapi/mapi/u_execmem.h | 26
src/GLdispatch/vnd-glapi/mapi/u_thread.h | 231
src/GLdispatch/vnd-glapi/mapi/vgapi/Makefile.am | 61
src/GLdispatch/vnd-glapi/mapi/vgapi/SConscript | 61
src/GLdispatch/vnd-glapi/mapi/vgapi/vg.pc.in | 12
src/GLdispatch/vnd-glapi/mapi/vgapi/vgapi.csv | 93
src/GLdispatch/vnd-glapi/tests/Makefile.am | 18
src/GLdispatch/vnd-glapi/tests/check_table.cpp | 471
src/Makefile.am | 11
src/OpenGL/Makefile.am | 21
src/OpenGL/OpenGL.c | 37
src/OpenGL/entrypoint_common.mk | 89
src/OpenGL/libopengl.c | 66
src/generate/genCommon.py | 217
src/generate/gen_gldispatch_mapi.py | 191
src/generate/gen_libOpenGL_exports.py | 48
src/generate/gen_libgl_glxstubs.py | 189
src/generate/gl_inittable.py | 164
src/generate/gl_table.py | 63
src/generate/glvnd_gen.mk | 84
src/generate/xml/gl.xml |46232 ++++++++++
src/generate/xml/gl_other.xml | 468
src/generate/xml/glx.xml | 2161
src/generate/xml/glx_other.xml | 40
src/util/Makefile.am | 2
src/util/glvnd_genentry.c | 298
src/util/glvnd_genentry.h | 115
src/util/glvnd_pthread/glvnd_pthread.c | 218
src/util/glvnd_pthread/glvnd_pthread.h | 55
src/util/trace/trace.c | 1
src/util/uthash/doc/ChangeLog.html | 3002
src/util/uthash/doc/userguide.html | 6062 -
src/util/uthash/doc/utarray.html | 2524
src/util/uthash/doc/utlist.html | 2372
src/util/uthash/doc/utstring.html | 2142
src/util/uthash/src/uthash.h | 2
src/util/uthash/tests/test74.c | 82
src/util/uthash/tests/test75.c | 82
src/util/uthash/tests/test76.c | 116
src/util/uthash/tests/test77.c | 142
src/util/utils_misc.c | 252
src/util/utils_misc.h | 57
src/x11glvnd/Makefile.am | 12
src/x11glvnd/x11glvnd.h | 38
src/x11glvnd/x11glvndclient.c | 133
src/x11glvnd/x11glvndproto.h | 45
src/x11glvnd/x11glvndserver.c | 268
tests/GLX_dummy/GLX_dummy.c | 288
tests/GLX_dummy/Makefile.am | 26
tests/Makefile.am | 17
tests/testglxgetprocaddress.c | 25
tests/testglxmakecurrent.c | 14
tests/testglxnscreens.c | 3
tests/testpatchentrypoints.c | 100
tests/testpatchentrypoints.sh | 7
242 files changed, 66755 insertions(+), 46152 deletions(-)
New commits:
commit da090a2e381982d770a56f0018bc95a4a2604126
Author: Aaron Plattner <aplattner@nvidia.com>
Date: Fri Jan 8 12:25:46 2016 -0800
GLX: Return dummy strings for glXGetClientString(NULL, ...)
KDE calls glXGetClientString with a NULL dpy argument, which crashes in the call
to XScreenCount(dpy). Work around it by explicitly checking for this and
returning some static strings.
Note that one oddity is that querying the GLX_VERSION with a NULL dpy will
return the maximum version supported by libglvnd, but specifying a display will
return the maximum supported by any vendor on the display (up to libglvnd's
supported maximum).
Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
diff --git a/src/GLX/libglx.c b/src/GLX/libglx.c
index f656c44..b432bd1 100644
--- a/src/GLX/libglx.c
+++ b/src/GLX/libglx.c
@@ -55,6 +55,7 @@
/* current version numbers */
#define GLX_MAJOR_VERSION 1
#define GLX_MINOR_VERSION 4
+#define GLX_VERSION_STRING "1.4"
GLVNDPthreadFuncs __glXPthreadFuncs;
@@ -1278,16 +1279,36 @@ static char *MergeVersionStrings(char *currentString, const char *newString)
}
}
+static const char *GetClientStringNoVendor(int name)
+{
+ switch (name) {
+ case GLX_VENDOR:
+ return "libglvnd (no display specified)";
+ case GLX_VERSION:
+ return GLX_VERSION_STRING " (no display specified)";
+ case GLX_EXTENSIONS:
+ return "";
+ default:
+ return NULL;
+ }
+}
+
PUBLIC const char *glXGetClientString(Display *dpy, int name)
{
__glXThreadInitialize();
__GLXdisplayInfo *dpyInfo = NULL;
- int num_screens = XScreenCount(dpy);
+ int num_screens;
int screen;
int index = name - 1;
const char **vendorStrings = NULL;
+ if (dpy == NULL) {
+ return GetClientStringNoVendor(name);
+ }
+
+ num_screens = XScreenCount(dpy);
+
if (num_screens == 1) {
// There's only one screen, so we don't have to mess around with
// merging the strings from multiple vendors.
commit c254ef4ada93c47ff1256b4927644eba0a311bcf
Author: Kyle Brenneman <kbrenneman@nvidia.com>
Date: Wed Jan 6 10:23:32 2016 -0700
GLX: Use an assert to check for mismatched handle-to-vendor mappings.
In AddVendorPointerMapping and AddVendorXIDMapping, if there is an existing
mapping, then add an assert that the new vendor library matches the old one.
Handles have to map to at most one vendor, so if we get two different vendors
then there's a bug either in libGLX or in the vendor libraries.
diff --git a/src/GLX/libglxmapping.c b/src/GLX/libglxmapping.c
index 9cd1c7e..daffa0a 100644
--- a/src/GLX/libglxmapping.c
+++ b/src/GLX/libglxmapping.c
@@ -876,7 +876,10 @@ static void AddVendorPointerMapping(__GLXvendorPointerHashtable *table,
pEntry->vendor = vendor;
HASH_ADD_PTR(_LH(*table), ptr, pEntry);
} else {
- pEntry->vendor = vendor;
+ // Any GLXContext or GLXFBConfig handles must be unique to a single
+ // vendor at a time. If we get two different vendors, then there's
+ // either a bug in libGLX or in at least one of the vendor libraries.
+ assert(pEntry->vendor == vendor);
}
LKDHASH_UNLOCK(__glXPthreadFuncs, *table);
@@ -1008,7 +1011,9 @@ static void AddVendorXIDMapping(Display *dpy, __GLXdisplayInfo *dpyInfo, XID xid
pEntry->vendor = vendor;
HASH_ADD(hh, _LH(dpyInfo->xidVendorHash), xid, sizeof(xid), pEntry);
} else {
- pEntry->vendor = vendor;
+ // Like GLXContext and GLXFBConfig handles, any GLXDrawables must map
+ // to a single vendor library.
+ assert(pEntry->vendor == vendor);
}
LKDHASH_UNLOCK(__glXPthreadFuncs, dpyInfo->xidVendorHash);
commit 6d8d0efb3fc08131d11c8436d1cca01785f6ac22
Author: Kyle Brenneman <kbrenneman@nvidia.com>
Date: Mon Jan 4 15:12:23 2016 -0700
GLX: Fix a bunch of outdated names.
Renamed a bunch of structures and functions to reflect the fact that libGLX
maintains mappings of most objects directly to vendors now, not objects to
screens.
diff --git a/src/GLX/libglxmapping.c b/src/GLX/libglxmapping.c
index e3b99bb..9cd1c7e 100644
--- a/src/GLX/libglxmapping.c
+++ b/src/GLX/libglxmapping.c
@@ -132,7 +132,7 @@ typedef struct __GLXdisplayInfoHashRec {
static DEFINE_INITIALIZED_LKDHASH(__GLXdisplayInfoHash, __glXDisplayInfoHash);
-struct __GLXscreenXIDMappingHashRec {
+struct __GLXvendorXIDMappingHashRec {
XID xid;
__GLXvendorInfo *vendor;
UT_hash_handle hh;
@@ -736,7 +736,7 @@ static __GLXdisplayInfoHash *InitDisplayInfoEntry(Display *dpy)
pEntry->dpy = dpy;
pEntry->info.vendors = (__GLXvendorInfo **) (pEntry + 1);
- LKDHASH_INIT(__glXPthreadFuncs, pEntry->info.xidScreenHash);
+ LKDHASH_INIT(__glXPthreadFuncs, pEntry->info.xidVendorHash);
__glXPthreadFuncs.rwlock_init(&pEntry->info.vendorLock, NULL);
// Check whether the server supports the GLX extension, and record the
@@ -775,8 +775,8 @@ static void CleanupDisplayInfoEntry(void *unused, __GLXdisplayInfoHash *pEntry)
free(pEntry->info.clientStrings[i]);
}
- LKDHASH_TEARDOWN(__glXPthreadFuncs, __GLXscreenXIDMappingHash,
- pEntry->info.xidScreenHash, NULL, NULL, False);
+ LKDHASH_TEARDOWN(__glXPthreadFuncs, __GLXvendorXIDMappingHash,
+ pEntry->info.xidVendorHash, NULL, NULL, False);
}
__GLXdisplayInfo *__glXLookupDisplay(Display *dpy)
@@ -847,16 +847,16 @@ typedef struct {
void *ptr;
__GLXvendorInfo *vendor;
UT_hash_handle hh;
-} __GLXscreenPointerMappingHash;
+} __GLXvendorPointerMappingHash;
-typedef DEFINE_LKDHASH(__GLXscreenPointerMappingHash, __GLXscreenPointerHashtable);
-static __GLXscreenPointerHashtable contextHashtable = { NULL, GLVND_RWLOCK_INITIALIZER };
-static __GLXscreenPointerHashtable fbconfigHashtable = { NULL, GLVND_RWLOCK_INITIALIZER };
+typedef DEFINE_LKDHASH(__GLXvendorPointerMappingHash, __GLXvendorPointerHashtable);
+static __GLXvendorPointerHashtable contextHashtable = { NULL, GLVND_RWLOCK_INITIALIZER };
+static __GLXvendorPointerHashtable fbconfigHashtable = { NULL, GLVND_RWLOCK_INITIALIZER };
-static void AddScreenPointerMapping(__GLXscreenPointerHashtable *table,
+static void AddVendorPointerMapping(__GLXvendorPointerHashtable *table,
void *ptr, __GLXvendorInfo *vendor)
{
- __GLXscreenPointerMappingHash *pEntry;
+ __GLXvendorPointerMappingHash *pEntry;
if (ptr == NULL) {
return;
@@ -882,9 +882,9 @@ static void AddScreenPointerMapping(__GLXscreenPointerHashtable *table,
LKDHASH_UNLOCK(__glXPthreadFuncs, *table);
}
-static void RemoveScreenPointerMapping(__GLXscreenPointerHashtable *table, void *ptr)
+static void RemoveVendorPointerMapping(__GLXvendorPointerHashtable *table, void *ptr)
{
- __GLXscreenPointerMappingHash *pEntry;
+ __GLXvendorPointerMappingHash *pEntry;
if (ptr == NULL) {
return;
@@ -902,10 +902,10 @@ static void RemoveScreenPointerMapping(__GLXscreenPointerHashtable *table, void
LKDHASH_UNLOCK(__glXPthreadFuncs, *table);
}
-static int VendorFromPointer(__GLXscreenPointerHashtable *table, void *ptr,
+static int VendorFromPointer(__GLXvendorPointerHashtable *table, void *ptr,
__GLXvendorInfo **retVendor)
{
- __GLXscreenPointerMappingHash *pEntry;
+ __GLXvendorPointerMappingHash *pEntry;
__GLXvendorInfo *vendor = NULL;
LKDHASH_RDLOCK(__glXPthreadFuncs, *table);
@@ -929,13 +929,13 @@ static int VendorFromPointer(__GLXscreenPointerHashtable *table, void *ptr,
*/
void __glXAddVendorContextMapping(Display *dpy, GLXContext context, __GLXvendorInfo *vendor)
{
- AddScreenPointerMapping(&contextHashtable, context, vendor);
+ AddVendorPointerMapping(&contextHashtable, context, vendor);
}
void __glXRemoveVendorContextMapping(Display *dpy, GLXContext context)
{
- RemoveScreenPointerMapping(&contextHashtable, context);
+ RemoveVendorPointerMapping(&contextHashtable, context);
}
@@ -947,13 +947,13 @@ int __glXVendorFromContext(GLXContext context, __GLXvendorInfo **retVendor)
void __glXAddVendorFBConfigMapping(Display *dpy, GLXFBConfig config, __GLXvendorInfo *vendor)
{
- AddScreenPointerMapping(&fbconfigHashtable, config, vendor);
+ AddVendorPointerMapping(&fbconfigHashtable, config, vendor);
}
void __glXRemoveVendorFBConfigMapping(Display *dpy, GLXFBConfig config)
{
- RemoveScreenPointerMapping(&fbconfigHashtable, config);
+ RemoveVendorPointerMapping(&fbconfigHashtable, config);
}
@@ -982,13 +982,13 @@ int __glXVendorFromVisual(Display *dpy, const XVisualInfo *visual, __GLXvendorIn
/****************************************************************************/
/*
- * __glXScreenXIDMappingHash is a hash table which maps XIDs to screens.
+ * __GLXvendorXIDMappingHash is a hash table which maps XIDs to vendors.
*/
-static void AddScreenXIDMapping(Display *dpy, __GLXdisplayInfo *dpyInfo, XID xid, __GLXvendorInfo *vendor)
+static void AddVendorXIDMapping(Display *dpy, __GLXdisplayInfo *dpyInfo, XID xid, __GLXvendorInfo *vendor)
{
- __GLXscreenXIDMappingHash *pEntry = NULL;
+ __GLXvendorXIDMappingHash *pEntry = NULL;
if (xid == None) {
return;
@@ -998,66 +998,66 @@ static void AddScreenXIDMapping(Display *dpy, __GLXdisplayInfo *dpyInfo, XID xid
return;
}
- LKDHASH_WRLOCK(__glXPthreadFuncs, dpyInfo->xidScreenHash);
+ LKDHASH_WRLOCK(__glXPthreadFuncs, dpyInfo->xidVendorHash);
- HASH_FIND(hh, _LH(dpyInfo->xidScreenHash), &xid, sizeof(xid), pEntry);
+ HASH_FIND(hh, _LH(dpyInfo->xidVendorHash), &xid, sizeof(xid), pEntry);
if (pEntry == NULL) {
pEntry = malloc(sizeof(*pEntry));
pEntry->xid = xid;
pEntry->vendor = vendor;
- HASH_ADD(hh, _LH(dpyInfo->xidScreenHash), xid, sizeof(xid), pEntry);
+ HASH_ADD(hh, _LH(dpyInfo->xidVendorHash), xid, sizeof(xid), pEntry);
} else {
pEntry->vendor = vendor;
}
- LKDHASH_UNLOCK(__glXPthreadFuncs, dpyInfo->xidScreenHash);
+ LKDHASH_UNLOCK(__glXPthreadFuncs, dpyInfo->xidVendorHash);
}
-static void RemoveScreenXIDMapping(Display *dpy, __GLXdisplayInfo *dpyInfo, XID xid)
+static void RemoveVendorXIDMapping(Display *dpy, __GLXdisplayInfo *dpyInfo, XID xid)
{
- __GLXscreenXIDMappingHash *pEntry;
+ __GLXvendorXIDMappingHash *pEntry;
if (xid == None) {
return;
}
- LKDHASH_WRLOCK(__glXPthreadFuncs, dpyInfo->xidScreenHash);
+ LKDHASH_WRLOCK(__glXPthreadFuncs, dpyInfo->xidVendorHash);
- HASH_FIND(hh, _LH(dpyInfo->xidScreenHash), &xid, sizeof(xid), pEntry);
+ HASH_FIND(hh, _LH(dpyInfo->xidVendorHash), &xid, sizeof(xid), pEntry);
if (pEntry != NULL) {
- HASH_DELETE(hh, _LH(dpyInfo->xidScreenHash), pEntry);
+ HASH_DELETE(hh, _LH(dpyInfo->xidVendorHash), pEntry);
free(pEntry);
}
- LKDHASH_UNLOCK(__glXPthreadFuncs, dpyInfo->xidScreenHash);
+ LKDHASH_UNLOCK(__glXPthreadFuncs, dpyInfo->xidVendorHash);
}
-static void ScreenFromXID(Display *dpy, __GLXdisplayInfo *dpyInfo, XID xid,
+static void VendorFromXID(Display *dpy, __GLXdisplayInfo *dpyInfo, XID xid,
__GLXvendorInfo **retVendor)
{
- __GLXscreenXIDMappingHash *pEntry;
+ __GLXvendorXIDMappingHash *pEntry;
__GLXvendorInfo *vendor = NULL;
- LKDHASH_RDLOCK(__glXPthreadFuncs, dpyInfo->xidScreenHash);
+ LKDHASH_RDLOCK(__glXPthreadFuncs, dpyInfo->xidVendorHash);
- HASH_FIND(hh, _LH(dpyInfo->xidScreenHash), &xid, sizeof(xid), pEntry);
+ HASH_FIND(hh, _LH(dpyInfo->xidVendorHash), &xid, sizeof(xid), pEntry);
if (pEntry) {
vendor = pEntry->vendor;
- LKDHASH_UNLOCK(__glXPthreadFuncs, dpyInfo->xidScreenHash);
+ LKDHASH_UNLOCK(__glXPthreadFuncs, dpyInfo->xidVendorHash);
} else {
- LKDHASH_UNLOCK(__glXPthreadFuncs, dpyInfo->xidScreenHash);
+ LKDHASH_UNLOCK(__glXPthreadFuncs, dpyInfo->xidVendorHash);
if (dpyInfo->x11glvndSupported) {
int screen = XGLVQueryXIDScreenMapping(dpy, xid);
if (screen >= 0 && screen < ScreenCount(dpy)) {
vendor = __glXLookupVendorByScreen(dpy, screen);
if (vendor != NULL) {
- AddScreenXIDMapping(dpy, dpyInfo, xid, vendor);
+ AddVendorXIDMapping(dpy, dpyInfo, xid, vendor);
}
}
}
@@ -1073,7 +1073,7 @@ void __glXAddVendorDrawableMapping(Display *dpy, GLXDrawable drawable, __GLXvend
{
__GLXdisplayInfo *dpyInfo = __glXLookupDisplay(dpy);
if (dpyInfo != NULL) {
- AddScreenXIDMapping(dpy, dpyInfo, drawable, vendor);
+ AddVendorXIDMapping(dpy, dpyInfo, drawable, vendor);
}
}
@@ -1082,7 +1082,7 @@ void __glXRemoveVendorDrawableMapping(Display *dpy, GLXDrawable drawable)
{
__GLXdisplayInfo *dpyInfo = __glXLookupDisplay(dpy);
if (dpyInfo != NULL) {
- RemoveScreenXIDMapping(dpy, dpyInfo, drawable);
+ RemoveVendorXIDMapping(dpy, dpyInfo, drawable);
}
}
@@ -1093,7 +1093,7 @@ int __glXVendorFromDrawable(Display *dpy, GLXDrawable drawable, __GLXvendorInfo
__GLXvendorInfo *vendor = NULL;
if (dpyInfo != NULL) {
if (dpyInfo->x11glvndSupported) {
- ScreenFromXID(dpy, dpyInfo, drawable, &vendor);
+ VendorFromXID(dpy, dpyInfo, drawable, &vendor);
} else {
// We'll use the same vendor for every screen in this case.
vendor = __glXLookupVendorByScreen(dpy, 0);
@@ -1130,7 +1130,7 @@ void __glXMappingTeardown(Bool doReset)
__glXPthreadFuncs.rwlock_init(&__glXDisplayInfoHash.lock, NULL);
HASH_ITER(hh, _LH(__glXDisplayInfoHash), dpyInfoEntry, dpyInfoTmp) {
- __glXPthreadFuncs.rwlock_init(&dpyInfoEntry->info.xidScreenHash.lock, NULL);
+ __glXPthreadFuncs.rwlock_init(&dpyInfoEntry->info.xidVendorHash.lock, NULL);
__glXPthreadFuncs.rwlock_init(&dpyInfoEntry->info.vendorLock, NULL);
}
} else {
@@ -1143,10 +1143,10 @@ void __glXMappingTeardown(Bool doReset)
__glXNextUnusedHashIndex = 0;
LKDHASH_UNLOCK(__glXPthreadFuncs, __glXDispatchIndexHash);
- LKDHASH_TEARDOWN(__glXPthreadFuncs, __GLXscreenPointerMappingHash,
+ LKDHASH_TEARDOWN(__glXPthreadFuncs, __GLXvendorPointerMappingHash,
contextHashtable, NULL, NULL, False);
- LKDHASH_TEARDOWN(__glXPthreadFuncs, __GLXscreenPointerMappingHash,
+ LKDHASH_TEARDOWN(__glXPthreadFuncs, __GLXvendorPointerMappingHash,
fbconfigHashtable, NULL, NULL, False);
LKDHASH_TEARDOWN(__glXPthreadFuncs, __GLXdisplayInfoHash,
diff --git a/src/GLX/libglxmapping.h b/src/GLX/libglxmapping.h
index 94aed7b..c7f4606 100644
--- a/src/GLX/libglxmapping.h
+++ b/src/GLX/libglxmapping.h
@@ -52,7 +52,7 @@ struct __GLXvendorInfoRec {
__GLXdispatchTableStatic staticDispatch; //< static GLX dispatch table
};
-typedef struct __GLXscreenXIDMappingHashRec __GLXscreenXIDMappingHash;
+typedef struct __GLXvendorXIDMappingHashRec __GLXvendorXIDMappingHash;
/*!
* Structure containing per-display information.
@@ -68,7 +68,7 @@ typedef struct __GLXdisplayInfoRec {
__GLXvendorInfo **vendors;
glvnd_rwlock_t vendorLock;
- DEFINE_LKDHASH(__GLXscreenXIDMappingHash, xidScreenHash);
+ DEFINE_LKDHASH(__GLXvendorXIDMappingHash, xidVendorHash);
/// True if the server supports the GLX extension.
Bool glxSupported;
commit 5c27a7817fa30a6abe11b4d9c9f8a537c4091faf
Author: Kyle Brenneman <kbrenneman@nvidia.com>
Date: Mon Jan 4 15:01:32 2016 -0700
GLX: Don't record the display pointer for contexts and configs.
Remove the Display pointer from __GLXscreenPointerMappingHash. It's no longer
needed for anything in libGLX.so. Dispatch functions can find a vendor library
given only the GLXContext handle itself, so functions like glXGetContextIDEXT
don't need the display either.
diff --git a/src/GLX/libglx.c b/src/GLX/libglx.c
index c91e8a1..a474561 100644
--- a/src/GLX/libglx.c
+++ b/src/GLX/libglx.c
@@ -131,7 +131,7 @@ static __GLXvendorInfo *CommonDispatchContext(Display *dpy, GLXContext context,
if (context != NULL) {
__glXThreadInitialize();
- __glXVendorFromContext(context, NULL, &vendor);
+ __glXVendorFromContext(context, &vendor);
}
if (vendor == NULL) {
__glXSendError(dpy, GLXBadContext, 0, minorCode, False);
@@ -375,7 +375,7 @@ static void glXFreeContextEXT(Display *dpy, GLXContext context)
__glXThreadInitialize();
- __glXVendorFromContext(context, NULL, &vendor);
+ __glXVendorFromContext(context, &vendor);
if (vendor != NULL && vendor->staticDispatch.freeContextEXT != NULL) {
__glXNotifyContextDestroyed(context);
vendor->staticDispatch.freeContextEXT(dpy, context);
@@ -919,7 +919,7 @@ static Bool CommonMakeCurrent(Display *dpy, GLXDrawable draw,
return False;
}
- if (__glXVendorFromContext(context, NULL, &newVendor) != 0) {
+ if (__glXVendorFromContext(context, &newVendor) != 0) {
/*
* We can run into this corner case if a GLX client calls
* glXDestroyContext() on a current context, loses current to this
diff --git a/src/GLX/libglxabi.h b/src/GLX/libglxabi.h
index baca2ae..67eafcf 100644
--- a/src/GLX/libglxabi.h
+++ b/src/GLX/libglxabi.h
@@ -178,15 +178,13 @@ typedef struct __GLXapiExportsRec {
*
* Note that this function does not take a display connection, since
* there are cases (e.g., glXGetContextIDEXT) that take a GLXContext but
- * not a display. Instead, it will return the display that the context was
- * created on.
+ * not a display.
*
* \param context The context to look up.
- * \param[out] retScreen Returns the screen number.
* \param[out] retVendor Returns the vendor.
* \return Zero if a match was found, or non-zero if it was not.
*/
- int (*vendorFromContext)(GLXContext context, Display **retDisplay, __GLXvendorInfo **retVendor);
+ int (*vendorFromContext)(GLXContext context, __GLXvendorInfo **retVendor);
void (*addVendorFBConfigMapping)(Display *dpy, GLXFBConfig config, __GLXvendorInfo *vendor);
void (*removeVendorFBConfigMapping)(Display *dpy, GLXFBConfig config);
diff --git a/src/GLX/libglxmapping.c b/src/GLX/libglxmapping.c
index 6616f3b..e3b99bb 100644
--- a/src/GLX/libglxmapping.c
+++ b/src/GLX/libglxmapping.c
@@ -845,22 +845,6 @@ void __glXFreeDisplay(Display *dpy)
typedef struct {
void *ptr;
- /*
- * Note that the display pointer is needed for GLXContext handles, because
- * at least one function (glXGetContextIDEXT) takes a GLXContext handle
- * without a display, so we have to be able to look up the display.
- *
- * For GLXFBConfig handles, it's not used for anything. Originally, it was
- * used for error-checking, to make sure that the config is used with the
- * correct display. But, some applications actually depend on being able to
- * look up a GLXFBConfig using one display connection and then using it on
- * another connection.
- *
- * To deal with that case, libGLX only cares about being able to map a
- * GLXFBConfig handle to a vendor library. Any additional error-checking
- * has to be in the vendor library itself.
- */
- Display *dpy;
__GLXvendorInfo *vendor;
UT_hash_handle hh;
} __GLXscreenPointerMappingHash;
@@ -870,7 +854,7 @@ static __GLXscreenPointerHashtable contextHashtable = { NULL, GLVND_RWLOCK_INITI
static __GLXscreenPointerHashtable fbconfigHashtable = { NULL, GLVND_RWLOCK_INITIALIZER };
static void AddScreenPointerMapping(__GLXscreenPointerHashtable *table,
- void *ptr, Display *dpy, __GLXvendorInfo *vendor)
+ void *ptr, __GLXvendorInfo *vendor)
{
__GLXscreenPointerMappingHash *pEntry;
@@ -889,11 +873,9 @@ static void AddScreenPointerMapping(__GLXscreenPointerHashtable *table,
if (pEntry == NULL) {
pEntry = malloc(sizeof(*pEntry));
pEntry->ptr = ptr;
- pEntry->dpy = dpy;
pEntry->vendor = vendor;
HASH_ADD_PTR(_LH(*table), ptr, pEntry);
} else {
- pEntry->dpy = dpy;
pEntry->vendor = vendor;
}
@@ -921,12 +903,10 @@ static void RemoveScreenPointerMapping(__GLXscreenPointerHashtable *table, void
}
static int VendorFromPointer(__GLXscreenPointerHashtable *table, void *ptr,
- Display **retDisplay,
__GLXvendorInfo **retVendor)
{
__GLXscreenPointerMappingHash *pEntry;
__GLXvendorInfo *vendor = NULL;
- Display *dpy = NULL;
LKDHASH_RDLOCK(__glXPthreadFuncs, *table);
@@ -934,14 +914,10 @@ static int VendorFromPointer(__GLXscreenPointerHashtable *table, void *ptr,
if (pEntry != NULL) {
vendor = pEntry->vendor;
- dpy = pEntry->dpy;
}
LKDHASH_UNLOCK(__glXPthreadFuncs, *table);
- if (retDisplay != NULL) {
- *retDisplay = dpy;
- }
if (retVendor != NULL) {
*retVendor = vendor;
}
@@ -953,7 +929,7 @@ static int VendorFromPointer(__GLXscreenPointerHashtable *table, void *ptr,
*/
void __glXAddVendorContextMapping(Display *dpy, GLXContext context, __GLXvendorInfo *vendor)
{
- AddScreenPointerMapping(&contextHashtable, context, dpy, vendor);
+ AddScreenPointerMapping(&contextHashtable, context, vendor);
}
@@ -963,15 +939,15 @@ void __glXRemoveVendorContextMapping(Display *dpy, GLXContext context)
}
-int __glXVendorFromContext(GLXContext context, Display **retDisplay, __GLXvendorInfo **retVendor)
+int __glXVendorFromContext(GLXContext context, __GLXvendorInfo **retVendor)
{
- return VendorFromPointer(&contextHashtable, context, retDisplay, retVendor);
+ return VendorFromPointer(&contextHashtable, context, retVendor);
}
void __glXAddVendorFBConfigMapping(Display *dpy, GLXFBConfig config, __GLXvendorInfo *vendor)
{
- AddScreenPointerMapping(&fbconfigHashtable, config, dpy, vendor);
+ AddScreenPointerMapping(&fbconfigHashtable, config, vendor);
}
@@ -983,7 +959,7 @@ void __glXRemoveVendorFBConfigMapping(Display *dpy, GLXFBConfig config)
int __glXVendorFromFBConfig(Display *dpy, GLXFBConfig config, __GLXvendorInfo **retVendor)
{
- return VendorFromPointer(&fbconfigHashtable, config, NULL, retVendor);
+ return VendorFromPointer(&fbconfigHashtable, config, retVendor);
}
// Internally, we use the screen number to look up a vendor, so we don't need
diff --git a/src/GLX/libglxmapping.h b/src/GLX/libglxmapping.h
index 0c7b390..94aed7b 100644
--- a/src/GLX/libglxmapping.h
+++ b/src/GLX/libglxmapping.h
@@ -99,7 +99,7 @@ __GLdispatchTable *__glXGetGLDispatch(Display *dpy, const int screen);
*/
void __glXAddVendorContextMapping(Display *dpy, GLXContext context, __GLXvendorInfo *vendor);
void __glXRemoveVendorContextMapping(Display *dpy, GLXContext context);
-int __glXVendorFromContext(GLXContext context, Display **retDisplay, __GLXvendorInfo **retVendor);
+int __glXVendorFromContext(GLXContext context, __GLXvendorInfo **retVendor);
void __glXAddVendorFBConfigMapping(Display *dpy, GLXFBConfig config, __GLXvendorInfo *vendor);
void __glXRemoveVendorFBConfigMapping(Display *dpy, GLXFBConfig config);
commit bedb59a58058afa113fa26db63f15eb5948d278c
Author: Kyle Brenneman <kbrenneman@nvidia.com>
Date: Mon Jan 4 14:44:22 2016 -0700
GLX: Use separate hashtables for contexts and configs.
libGLX now uses a separate hashtable for mapping GLXContext and GLXFBConfig
handles to vendor libraries.
Updated the ABI documentation to define requirements for GLXContext and
GLXFBConfig values, to ensure that there aren't ever any duplicate handles
between vendor libraries.
diff --git a/src/GLX/libglxabi.h b/src/GLX/libglxabi.h
index a38811f..baca2ae 100644
--- a/src/GLX/libglxabi.h
+++ b/src/GLX/libglxabi.h
@@ -54,6 +54,37 @@ extern "C" {
* - core GL dispatch table: this is a structure maintained by the API library
* which contains both GL core (static) and GL extension (dynamic) functions.
*
+ * Note that while the implementations of most GLX functions in a vendor
+ * library is mostly unchanged from a traditional, single-vendor driver, libGLX
+ * has additional requirements for GLXContext and GLXFBConfig handle values.
+ *
+ * First, all GLXContext and GLXFBConfig handles have to be unique between
+ * vendor libraries. That is, every GLXContext or GLXFBConfig handle must map
+ * to exactly one vendor library, so that libGLX knows which library to dispatch
+ * to.
+ *
+ * To do that, all GLXContext and GLXFBConfig handles *must* be a pointer to an
+ * address that the vendor library somehow controls. The address doesn't need
+ * to be readable or writable, but it must be an address that no other vendor
+ * library would use.
+ *
+ * The address could be a pointer to a structure, or an address in a statically
+ * or dynamically allocated array. It could even be a file mapping, or even an
+ * offset into wherever the vendor library itself is mapped.
+ *
+ * A vendor library may not, however, use anything like an index or an XID for
+ * a GLXContext or GLXFBConfig handle.
+ *
+ * GLXContext handles must also be globally unique across all display
+ * connections in the entire process. That is, a vendor library may not return
+ * the same GLXContext handle for two different contexts, even if they're on
+ * different displays or different servers.
+ *
+ * GLXFBConfigs may be duplicated between multiple displays, as long as they
+ * are still unique between vendors. Some applications even depend on this:
+ * They will look up a GLXFBConfig handle with one connection, and then try to
+ * use that config on another connection.
+ *
* @{
*/
@@ -74,12 +105,19 @@ typedef struct __GLXvendorInfoRec __GLXvendorInfo;
* API library exports *
****************************************************************************/
+/*!
+ * Functions exported by libGLX.so.
+ *
+ * These functions are exported by libGLX, and should be used by the
+ * vendor-implemented dispatch functions to lookup and call into the right
+ * vendor.
+ *
+ * These functions should only be called from the GLX dispatch functions, never
+ * from the actual implementation of any function. libGLX.so may be holding a
+ * non-recursive lock when it calls into the vendor library, so trying to call
+ * back into libGLX could deadlock.
+ */
typedef struct __GLXapiExportsRec {
- /************************************************************************
- * The following routines are used by vendor-implemented GLX dispatch
- * functions to lookup and call into the right vendor.
- ************************************************************************/
-
/*!
* This fetches the appropriate dynamic GLX dispatch table given the display
* and screen number.
diff --git a/src/GLX/libglxmapping.c b/src/GLX/libglxmapping.c
index 49e5b02..6616f3b 100644
--- a/src/GLX/libglxmapping.c
+++ b/src/GLX/libglxmapping.c
@@ -837,22 +837,40 @@ void __glXFreeDisplay(Display *dpy)
/****************************************************************************/
/*
- * __glXScreenPointerMappingHash is a hash table that maps a void*
- * (either GLXContext or GLXFBConfig) to a screen index. Note this
- * stores both GLXContext and GLXFBConfig in this table.
+ * Define two hashtables to store the mappings for GLXFBConfig and GLXContext
+ * handles to vendor libraries.
+ *
+ * The same functions are used to access both tables.
*/
typedef struct {
void *ptr;
+ /*
+ * Note that the display pointer is needed for GLXContext handles, because
+ * at least one function (glXGetContextIDEXT) takes a GLXContext handle
+ * without a display, so we have to be able to look up the display.
+ *
+ * For GLXFBConfig handles, it's not used for anything. Originally, it was
+ * used for error-checking, to make sure that the config is used with the
+ * correct display. But, some applications actually depend on being able to
+ * look up a GLXFBConfig using one display connection and then using it on
+ * another connection.
+ *
+ * To deal with that case, libGLX only cares about being able to map a
+ * GLXFBConfig handle to a vendor library. Any additional error-checking
+ * has to be in the vendor library itself.
+ */
Display *dpy;
__GLXvendorInfo *vendor;
UT_hash_handle hh;
} __GLXscreenPointerMappingHash;
+typedef DEFINE_LKDHASH(__GLXscreenPointerMappingHash, __GLXscreenPointerHashtable);
+static __GLXscreenPointerHashtable contextHashtable = { NULL, GLVND_RWLOCK_INITIALIZER };
+static __GLXscreenPointerHashtable fbconfigHashtable = { NULL, GLVND_RWLOCK_INITIALIZER };
-static DEFINE_INITIALIZED_LKDHASH(__GLXscreenPointerMappingHash, __glXScreenPointerMappingHash);
-
-static void AddScreenPointerMapping(void *ptr, Display *dpy, __GLXvendorInfo *vendor)
+static void AddScreenPointerMapping(__GLXscreenPointerHashtable *table,
+ void *ptr, Display *dpy, __GLXvendorInfo *vendor)
{
__GLXscreenPointerMappingHash *pEntry;
@@ -864,26 +882,25 @@ static void AddScreenPointerMapping(void *ptr, Display *dpy, __GLXvendorInfo *ve
return;
}
- LKDHASH_WRLOCK(__glXPthreadFuncs, __glXScreenPointerMappingHash);
+ LKDHASH_WRLOCK(__glXPthreadFuncs, *table);
- HASH_FIND_PTR(_LH(__glXScreenPointerMappingHash), &ptr, pEntry);
+ HASH_FIND_PTR(_LH(*table), &ptr, pEntry);
if (pEntry == NULL) {
pEntry = malloc(sizeof(*pEntry));
pEntry->ptr = ptr;
pEntry->dpy = dpy;
pEntry->vendor = vendor;
- HASH_ADD_PTR(_LH(__glXScreenPointerMappingHash), ptr, pEntry);
+ HASH_ADD_PTR(_LH(*table), ptr, pEntry);
} else {
pEntry->dpy = dpy;
pEntry->vendor = vendor;
}
- LKDHASH_UNLOCK(__glXPthreadFuncs, __glXScreenPointerMappingHash);
+ LKDHASH_UNLOCK(__glXPthreadFuncs, *table);
}
-
-static void RemoveScreenPointerMapping(void *ptr)
+static void RemoveScreenPointerMapping(__GLXscreenPointerHashtable *table, void *ptr)
Reply to: