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 <aplatt...@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 <aplatt...@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 <kbrenne...@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 <kbrenne...@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 <kbrenne...@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 <kbrenne...@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)