[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: