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

libglvnd: Changes to 'debian-unstable'



 README.md                                           |  162 +--
 configure.ac                                        |   12 
 debian/control                                      |    4 
 debian/rules                                        |    2 
 include/compiler.h                                  |    2 
 src/GL/Makefile.am                                  |   10 
 src/GLESv1/Makefile.am                              |   25 
 src/GLESv2/Makefile.am                              |   25 
 src/GLX/Makefile.am                                 |   26 
 src/GLX/gen_stubs.pl                                |  275 ------
 src/GLX/glx_funcs.spec                              |  353 -------
 src/GLX/libglx.c                                    |  321 +++----
 src/GLX/libglxcurrent.h                             |   15 
 src/GLX/libglxmapping.c                             |  362 +++-----
 src/GLX/libglxmapping.h                             |   23 
 src/GLX/libglxnoop.h                                |   41 
 src/GLdispatch/GLdispatch.c                         |   28 
 src/GLdispatch/Makefile.am                          |   12 
 src/GLdispatch/vnd-glapi/Makefile.am                |   95 +-
 src/GLdispatch/vnd-glapi/entry.h                    |   98 ++
 src/GLdispatch/vnd-glapi/entry_armv7_tsd.c          |  237 +++++
 src/GLdispatch/vnd-glapi/entry_common.c             |   76 +
 src/GLdispatch/vnd-glapi/entry_common.h             |   48 +
 src/GLdispatch/vnd-glapi/entry_files.mk             |   26 
 src/GLdispatch/vnd-glapi/entry_pure_c.c             |   98 ++
 src/GLdispatch/vnd-glapi/entry_x86_64_common.c      |   79 +
 src/GLdispatch/vnd-glapi/entry_x86_64_tls.c         |  111 ++
 src/GLdispatch/vnd-glapi/entry_x86_64_tsd.c         |  137 +++
 src/GLdispatch/vnd-glapi/entry_x86_tls.c            |  141 +++
 src/GLdispatch/vnd-glapi/entry_x86_tsd.c            |  111 ++
 src/GLdispatch/vnd-glapi/glapi.h                    |  260 +++++
 src/GLdispatch/vnd-glapi/mapi/entry.h               |   98 --
 src/GLdispatch/vnd-glapi/mapi/entry_armv7_tsd.c     |  237 -----
 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        |   98 --
 src/GLdispatch/vnd-glapi/mapi/entry_x86_64_common.c |   79 -
 src/GLdispatch/vnd-glapi/mapi/entry_x86_64_tls.c    |  111 --
 src/GLdispatch/vnd-glapi/mapi/entry_x86_64_tsd.c    |  137 ---
 src/GLdispatch/vnd-glapi/mapi/entry_x86_tls.c       |  141 ---
 src/GLdispatch/vnd-glapi/mapi/entry_x86_tsd.c       |  111 --
 src/GLdispatch/vnd-glapi/mapi/glapi/glapi.h         |  260 -----
 src/GLdispatch/vnd-glapi/mapi/mapi_abi.py           |  890 --------------------
 src/GLdispatch/vnd-glapi/mapi/mapi_glapi.c          |  133 --
 src/GLdispatch/vnd-glapi/mapi/mapi_tmp.h            |   34 
 src/GLdispatch/vnd-glapi/mapi/stub.c                |  374 --------
 src/GLdispatch/vnd-glapi/mapi/stub.h                |   71 -
 src/GLdispatch/vnd-glapi/mapi/table.c               |   50 -
 src/GLdispatch/vnd-glapi/mapi/table.h               |   72 -
 src/GLdispatch/vnd-glapi/mapi/u_compiler.h          |   33 
 src/GLdispatch/vnd-glapi/mapi/u_current.h           |   28 
 src/GLdispatch/vnd-glapi/mapi/u_current_tls.c       |   65 -
 src/GLdispatch/vnd-glapi/mapi/u_current_tsd.c       |   92 --
 src/GLdispatch/vnd-glapi/mapi/u_execmem.c           |  183 ----
 src/GLdispatch/vnd-glapi/mapi/u_execmem.h           |   29 
 src/GLdispatch/vnd-glapi/mapi/u_macros.h            |   12 
 src/GLdispatch/vnd-glapi/mapi_glapi.c               |  133 ++
 src/GLdispatch/vnd-glapi/mapi_tmp.h                 |   34 
 src/GLdispatch/vnd-glapi/stub.c                     |  374 ++++++++
 src/GLdispatch/vnd-glapi/stub.h                     |   71 +
 src/GLdispatch/vnd-glapi/table.c                    |   50 +
 src/GLdispatch/vnd-glapi/table.h                    |   72 +
 src/GLdispatch/vnd-glapi/u_compiler.h               |   33 
 src/GLdispatch/vnd-glapi/u_current.h                |   28 
 src/GLdispatch/vnd-glapi/u_current_tls.c            |   65 +
 src/GLdispatch/vnd-glapi/u_current_tsd.c            |   92 ++
 src/GLdispatch/vnd-glapi/u_execmem.c                |  183 ++++
 src/GLdispatch/vnd-glapi/u_execmem.h                |   29 
 src/GLdispatch/vnd-glapi/u_macros.h                 |   12 
 src/OpenGL/Makefile.am                              |   33 
 src/OpenGL/entrypoint_common.mk                     |   82 -
 src/OpenGL/libopengl.c                              |    1 
 src/generate/genCommon.py                           |   14 
 src/util/Makefile.am                                |   29 
 src/util/trace.c                                    |   83 +
 src/util/trace.h                                    |   90 ++
 src/util/trace/Makefile.am                          |   37 
 src/util/trace/trace.c                              |   85 -
 src/util/trace/trace.h                              |   90 --
 src/util/winsys_dispatch.c                          |  201 ++++
 src/util/winsys_dispatch.h                          |  130 ++
 tests/GLX_dummy/GLX_dummy.c                         |  390 +++++---
 tests/GLX_dummy/Makefile.am                         |   13 
 tests/Makefile.am                                   |   27 
 tests/test_utils.c                                  |  109 ++
 tests/test_utils.h                                  |    7 
 tests/testglxmakecurrent.c                          |   86 +
 tests/testpatchentrypoints.c                        |    2 
 tests/testpatchentrypoints.sh                       |    3 
 89 files changed, 4108 insertions(+), 5257 deletions(-)

New commits:
commit 8577ead28c0d949f607e88b752beb67e4cfb5bf9
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Mon Jun 20 12:37:46 2016 +0300

    bump policy to 3.9.7

diff --git a/debian/control b/debian/control
index 3938070..b076678 100644
--- a/debian/control
+++ b/debian/control
@@ -10,7 +10,7 @@ Build-Depends:
  python-dev,
  python-libxml2,
  x11proto-gl-dev,
-Standards-Version: 3.9.4
+Standards-Version: 3.9.7
 Section: libs
 Homepage: https://github.com/NVIDIA/libglvnd
 Vcs-Git: git://git.debian.org/pkg-xorg/lib/libglvnd.git

commit 6a78c3cc0d9a8aaf0eedff6dc45689ebd6db8a55
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Mon Jun 20 12:37:33 2016 +0300

    add x11proto-gl-dev to builddeps

diff --git a/debian/control b/debian/control
index 3f04d6b..3938070 100644
--- a/debian/control
+++ b/debian/control
@@ -9,6 +9,7 @@ Build-Depends:
  libxext-dev,
  python-dev,
  python-libxml2,
+ x11proto-gl-dev,
 Standards-Version: 3.9.4
 Section: libs
 Homepage: https://github.com/NVIDIA/libglvnd

commit 4e2db508b8f5e1d3329d1f8828ff6321504d2b31
Author: Timo Aaltonen <tjaalton@debian.org>
Date:   Mon Jun 20 12:31:23 2016 +0300

    drop xserver-xorg-dev from build-deps, not needed anymore

diff --git a/debian/control b/debian/control
index cd6d9ea..3f04d6b 100644
--- a/debian/control
+++ b/debian/control
@@ -7,7 +7,6 @@ Build-Depends:
  pkg-config,
  libx11-dev,
  libxext-dev,
- xserver-xorg-dev,
  python-dev,
  python-libxml2,
 Standards-Version: 3.9.4
diff --git a/debian/rules b/debian/rules
index e50c073..49fe284 100755
--- a/debian/rules
+++ b/debian/rules
@@ -11,4 +11,4 @@ override_dh_install:
 override_dh_auto_test:
 
 %:
-	dh $@ --parallel --with autoreconf,xsf --builddirectory=build/
+	dh $@ --parallel --with autoreconf --builddirectory=build/

commit 093f0485da8f4e9d39949b8a4ee20fd318b318ad
Author: Kyle Brenneman <kbrenneman@nvidia.com>
Date:   Thu Jun 9 13:12:29 2016 -0600

    Update the README file.
    
    Update the README file to reflect various changes to libglvnd.

diff --git a/README.md b/README.md
index 27d4d52..4a25144 100644
--- a/README.md
+++ b/README.md
@@ -15,10 +15,10 @@ future this library may support EGL and OpenGL ES as well.
 Building the library
 ----------------------
 
-libglvnd build-depends on xorg-server, libx11, glproto and libxext.
+libglvnd build-depends on libx11, glproto and libxext.
 On Debian and derivatives, run:
 
-    sudo apt-get install xserver-xorg-dev libxext-dev libx11-dev x11proto-gl-dev
+    sudo apt-get install libxext-dev libx11-dev x11proto-gl-dev
 
 Run `./autogen.sh`, then run `./configure` and `make`.
 
@@ -29,41 +29,40 @@ Code overview
 The code in the src/ directory is organized as follows:
 
 - GLX/ contains code for libGLX, the GLX window-system API library.
-- GLdispatch/ contains code for libGLdispatch, which is really just a thin
-  wrapper around Mesa's glapi that tries to hide most of the complexity of
-  managing dispatch tables. Its interface is defined in GLdispatch.h. This
-  implements the guts of the core GL API libraries.
-- EGL/ and GLESv{1,2}/ are placeholders for now. GLESv{1,2}/ implement
-  static GL entrypoints which use the context defined in libGLdispatch, while
-  EGL/ will contain libEGL, which may be implemented similarly to libGLX.
-- GL/ and OpenGL/ respectively contain code to generate libGL and libOpenGL,
-  which are both merely wrapper libraries for libGLX and libGLdispatch.
-  Ideally, these could be implemented via ELF symbol filtering, but in practice
-  they need to be implemented manually.  See the Issues section for details on
-  why this is the case.
-- util/ contains generic utility code, and arch/ contains architecture-specific
-  defines.
+- GLdispatch/ contains code for libGLdispatch, which is responsible for
+  dispatching OpenGL functions to the correct vendor library. Its interface is
+  defined in GLdispatch.h. This implements the guts of the core GL API
+  libraries. Most of the dispatch code is based on Mesa's glapi.
+- EGL/ is a placeholder for now. It will contain libEGL, which may be
+  implemented similarly to libGLX.
+- OpenGL/, GLESv1/, and GLESv2/ contain code to generate libOpenGL.so,
+  libGLESv1\_CM.so, and libGLESv2.so, respectively. All three are merely
+  wrapper libraries for libGLdispatch. Ideally, these could be implemented via
+  ELF symbol filtering, but in practice they need to be implemented manually.
+  See the Issues section for details on why this is the case.
+- GL/ contains code for libGL. This is a wrapper around libGLdispatch and
+  libGLX.
+- util/ contains generic utility code.
+
+In addition, libglvnd uses a GLX extension,
+[GLX\_EXT\_libglvnd](https://www.opengl.org/registry/specs/EXT/glx_libglvnd.txt),
+to determine which vendor library to use for a screen or XID.
 
 There are a few good starting points for familiarizing oneself with the code:
 
 - Look at the vendor-library to GLX ABI defined in `libglxabi.h`.
 - Follow the flow of `glXGetProcAddress() -> __glDispatchGetProcAddress() ->
-  __glapi_get_proc_address()` to see how the dispatch table is updated as new GL
+  _glapi_get_proc_address()` to see how the dispatch table is updated as new GL
   stubs are generated, and how GLX looks for vendor-library-implemented
   dispatchers for GLX extension functions.
 - Follow the flow of `glXMakeContextCurrent() -> __glDispatchMakeCurrent() ->
   _glapi_set_current()` to see how the current dispatch table and state is
   updated by the API library.
 - Look at `libglxmapping.c:__glXLookupVendorBy{Name,Screen}()` to see how
-  vendor library names are queried. At the same time, look at
-  x11glvnd{client,server}.c to see how the "x11glvnd" extension which
-  retrieves the appropriate mappings is implemented.
+  vendor library names are queried.
 
 The tests/ directory contains several unit tests which verify that dispatching
 to different vendors actually works. Run `make check` to run these unit tests.
-Note some of the unit tests require a special X server configuration and
-are skipped by default.  To include these tests (and X server
-initialization/teardown), run `make check DO_X11_TESTS=1`.
 
 Architecture
 ------------
@@ -78,16 +77,16 @@ See the diagram below:
           │     │                                  │
           │     └─────┬───────────────────┬────────┘
           │           │                   │
-          │     ┌─────▾─────┐             │                    ┌──────────────┐
-          │     │           │             │                    │              │
-          │     │ libOpenGL │             │                    │              │
-          │     │           │             │                    │  X server    │
-          │     └─────┬─────┘             │                    │              │
-          │        DT_FILTER              │                    │              │
-          │     ┌─────▾──────────┐ ┌──────▾────────┐           │ ┌──────────┐ │
-          │     │                │ │               │           └─│x11glvnd  │─┘
-          │     │ [mapi/glapi]   ◂─▸               │             │extension │
-          │     │ libGLdispatch  │ │   libGLX      ├─────────────▸──────────┘
+          │     ┌─────▾─────┐             │                    ┌──────────────────────┐
+          │     │           │             │                    │                      │
+          │     │ libOpenGL │             │                    │                      │
+          │     │           │             │                    │  X server            │
+          │     └─────┬─────┘             │                    │                      │
+          │        DT_FILTER              │                    │                      │
+          │     ┌─────▾──────────┐ ┌──────▾────────┐           │ ┌──────────────────┐ │
+          │     │                │ │               │           └─│GLX_EXT_libglvnd  │─┘
+          │     │ [mapi/glapi]   ◂─▸               │             │extension         │
+          │     │ libGLdispatch  │ │   libGLX      ├─────────────▸──────────────────┘
           │     │                │ │               ◂──────────┬─────────────────┐
           │     └───────▴────────┘ └──────▴────────┘          │                 │
           │         DT_FILTER         DT_FILTER             ┌─▾─────────┐   ┌───▾────────┐
@@ -108,9 +107,9 @@ In this diagram,
 libGLX manages loading GLX vendor libraries and dispatching GLX core and
 extension functions to the right vendor.
 
-x11glvnd is a simple X extension which allows libGLX to determine the number of
-the screen belonging to an arbitrary drawable XID, and also the GL vendor to use
-for a given screen.
+GLX\_EXT\_libglvnd is a simple GLX extension which allows libGLX to determine
+the number of the screen belonging to an arbitrary drawable XID, and also the
+GL vendor to use for a given screen.
 
 libGLdispatch implements core GL dispatching and TLS. It acts as a thin wrapper
 around glapi which provides some higher-level functionality for managing
@@ -120,17 +119,19 @@ linked into libGLX, since current dispatch tables will eventually be shared
 between GLX and EGL, similarly to how glapi operates when Mesa is compiled with
 the --shared-glapi option.
 
-libOpenGL is a wrapper library to libGLdispatch which exposes OpenGL 4.x core and
-compatibility entry points. Eventually, there will be a libGLESv{1,2} which will
-also be wrapper libraries to libGLdispatch that expose GLES entry points.
+libOpenGL is a wrapper library to libGLdispatch which exposes OpenGL 4.5 core and
+compatibility entry points.
 
-libGL is a wrapper library on libGLdispatch and libGLX which is provided for
+libGLESv{1,2} are wrapper libraries to libGLdispatch which expose OpenGL ES
+entrypoints.
+
+libGL is a wrapper library to libGLdispatch and libGLX which is provided for
 backwards-compatibility with applications which link against the old ABI.
 
-NOTE: Logically, libGL should be a wrapper library to libOpenGL rather than
-libGLdispatch, as libGLdispatch is an implementation detail of libglvnd.
-However, we have this current arrangement for performance reasons since ELF
-symbol filtering is disabled by default (see Issues).
+Note that since all OpenGL functions are dispatched through the same table in
+libGLdispatch, it doesn't matter which library is used to find the entrypoint.
+The same OpenGL function in libGL, libOpenGL, libGLES, and the function pointer
+returned by glXGetProcAddress are all interchangeable.
 
 ### GLX dispatching ###
 
@@ -150,7 +151,7 @@ map GLX API calls to the right vendor, we use the following strategy:
   * Use the Display connection to query the X server for the GLX
     vendor of that X screen.
 
-  * Load the correspending `libGLX_VENDOR.so`.
+  * Load the corresponding `libGLX_VENDOR.so`.
 
   * Read the vendor's GLX dispatch table from the `libGLX_VENDOR.so`.
 
@@ -158,33 +159,24 @@ map GLX API calls to the right vendor, we use the following strategy:
     use in subsequent dispatching.
 
 * Some GLX entry points imply an X screen by a GLX object they
-  specify.  Such GLX objects are:
+  specify. Such GLX objects are:
 
-    GLXContext  (an opaque pointer)
-    GLXFBConfig (an opaque pointer)
-    GLXPixmap   (an XID)
-    GLXDrawable (an XID)
-    GLXWindow   (an XID)
-    GLXPbuffer  (an XID)
+  * GLXContext  (an opaque pointer)
+  * GLXFBConfig (an opaque pointer)
+  * GLXPixmap   (an XID)
+  * GLXDrawable (an XID)
+  * GLXWindow   (an XID)
+  * GLXPbuffer  (an XID)
 
   To map from object to screen, record the corresponding screen when
-  the object is created.  This means the current process needs to see
-  a GLX call to create the object.  In the case of the opaque
+  the object is created. This means the current process needs to see
+  a GLX call to create the object. In the case of the opaque
   pointers, this is reasonable, since the pointer is only meaningful
-  within the current process.  But XIDs could be created by another
-  process.  See the Issues section below.
-
-* To minimize code complexity from error checking, define a noop GLX
-  dispatch table.  This is returned by `__glXGet{,Current}Dispatch()` in
-  case no other dispatch table can be found.
+  within the current process.
 
-* Similarly, `__glXScreenFrom{Context,FBConfig,Drawable}()` may fail to
-  find a screen matching the specified GLX object.  In this case, the
-  returned screen number is -1, but the caller should just pass the
-  screen number through to `__glXGetDispatch()` or
-  `__glX{Add,Remove}Screen{Context,FBConfig,Drawable}Mapping()`.  Those
-  functions are expected to deal gracefully with the invalid screen
-  number.
+  XIDs, however, can be created by another process, so libGLX may not know in
+  advance which screen they belong to. To deal with that, libGLX queries the
+  server using the GLX extension GLX\_EXT\_libglvnd.
 
 Issues
 ------
@@ -208,10 +200,10 @@ Issues
   mapping? How would this be implemented? Should we add new API calls to "GLX
   Next"?
 
-  * Note that the (drawable -> screen -> vendor) mapping is an internal detail
-	of libGLX. The ABI provided to the vendor library exposes a mapping from
-	drawables to (screen, vendor) pairs. The interface does not make any
-	assumptions about how screens and vendors correspond to each other.
+  * Note that the (drawable -> screen -> vendor) mapping mainly exists in the
+    GLX_EXT_libglvnd extension. libGLX itself keeps a simple
+    (drawable -> vendor) mapping, and exposes that mapping to the vendor
+    libraries.
 
 * Along the same lines, would it be useful to include a
   "glXGetProcAddressFromVendor()" or "glXGetProcAddressFromScreen()" entrypoint
@@ -238,33 +230,19 @@ Issues
 
 * How should forking be handled?
 
-* Should we map XIDs directly to vendors, rather than to screens?
-
-* The current libGLX implementation stores the mapping between screen and all
-  objects of the same type in one hash table.  I.e., all pointer types
-  (GLXContext and GLXFBConfig) in one table, and all XID types (GLXDrawable,
-  GLXPixmap, GLXWindow, and GLXPbuffer) in another table.  Should there instead
-  be more finer-grained hash tables?  There probably couldn't be finer-grained
-  tables for XIDs, because GLXDrawable is used interchangeably with the other
-  XID-based types.
-
-* The issue above applies to XIDs in the x11glvnd extension as well: we
-  currently don't make any distinction between window, GLX pixmap, GLX window, or
-  GLX pbuffer XIDs.
+* The current libGLX implementation stores all GLXContext and GLXFBConfig
+  handles in global hashtables, which means that GLXContext and GLXFBConfig
+  handles must be unique between vendors. That is, two vendor libraries must
+  not come up with the same handle value for a GLXContext or GLXFBConfig. To
+  that end, GLXContext and GLXFBConfig handles must be pointers to memory
+  addresses that the vendor library somehow controls. The values are otherwise
+  opaque.
 
 * Querying an XID <=> screen mapping without somehow "locking" the XID is
   inherently racy, since a different process may destroy the drawable, and X
   may recycle the XID, after the mapping is saved client-side. Is there a mechanism
   we could use to notify the API library when a mapping is no longer valid?
 
-* Currently the library does not attempt to clean up allocations and
-  unload vendor libraries if the application unloads it. This will need to be
-  implemented eventually for the library to be usable in a production
-  environment. What will the sequencing of this look like? Should we also hook
-  into XCloseDisplay()?
-
-* Should x11glvnd be an extension on top of GLX 1.4, or a "GLX Next" feature?
-
 References
 ----------
 

commit 1b30d153338196804348b44d6c7c6d98932a7b14
Author: Kyle Brenneman <kbrenneman@nvidia.com>
Date:   Tue May 24 15:52:42 2016 -0600

    GLdispatch: Don't unpatch entrypoints in __glDispatchLoseCurrent.
    
    In __glDispatchLoseCurrent, don't try to restore the default entrypoints.
    Instead, __glDispatchMakeCurrent will check if it's using a different vendor
    library, and if so, it will unpatch and repatch the entrypoints then. If it's
    using the same vendor library (which will usually be the case), then it can
    leave them patched and skip the patch overhead.
    
    Some applications will call glXMakeCurrent to release and bind the same context
    every frame, sometimes multiples times. Each patch and unpatch sequnce can chew
    up 1-2 milliseconds. That's enough to significantly reduce the framerate of
    some applications.
    
    Reviewed-by: James Jones <jajones@nvidia.com>

diff --git a/src/GLdispatch/GLdispatch.c b/src/GLdispatch/GLdispatch.c
index be2f61a..e5aa8c2 100644
--- a/src/GLdispatch/GLdispatch.c
+++ b/src/GLdispatch/GLdispatch.c
@@ -573,6 +573,17 @@ static int PatchEntrypoints(
         if (stubCurrentPatchCb->releasePatch != NULL) {
             stubCurrentPatchCb->releasePatch();
         }
+
+        // Restore the stubs to the default implementation.
+        glvnd_list_for_each_entry(stub, &dispatchStubList, entry) {
+            if (stub->isPatched) {
+                stub->callbacks.restoreFuncs();
+                stub->isPatched = GL_FALSE;
+            }
+        }
+
+        stubCurrentPatchCb = NULL;
+        stubOwnerVendorID = 0;
     }
 
     if (patchCb) {
@@ -609,17 +620,6 @@ static int PatchEntrypoints(
             stubCurrentPatchCb = NULL;
             stubOwnerVendorID = 0;
         }
-    } else {
-        // Restore the stubs to the default implementation
-        glvnd_list_for_each_entry(stub, &dispatchStubList, entry) {
-            if (stub->isPatched) {
-                stub->callbacks.restoreFuncs();
-                stub->isPatched = GL_FALSE;
-            }
-        }
-
-        stubCurrentPatchCb = NULL;
-        stubOwnerVendorID = 0;
     }
 
     return 1;
@@ -695,8 +695,10 @@ static void LoseCurrentInternal(__GLdispatchThreadState *curThreadState,
         GLboolean threadDestroyed)
 {
     LockDispatch();
-    // Try to restore the libglvnd default stubs, if possible.
-    PatchEntrypoints(NULL, 0);
+    // Note that we don't try to restore the default stubs here. Chances are,
+    // the next MakeCurrent will be from the same vendor, and if we leave them
+    // patched, then we won't have to go through the overhead of patching them
+    // again.
 
     if (curThreadState) {
         numCurrentContexts--;

commit d0ced9a2e33c5415768be455c9cae08129844c0a
Author: Kyle Brenneman <kbrenneman@nvidia.com>
Date:   Fri May 27 11:47:59 2016 -0600

    GLX: Fix a couple of errors.
    
    Moved the unlock in __glXLookupVendorByName to after the calls to update the
    GLX entrypoints.
    
    Fixed a typo in GLXEntrypointUpdateCallback.

diff --git a/src/GLX/libglxmapping.c b/src/GLX/libglxmapping.c
index 90957ac..165270f 100644
--- a/src/GLX/libglxmapping.c
+++ b/src/GLX/libglxmapping.c
@@ -238,7 +238,7 @@ __GLXextFuncPtr __glXGetGLXDispatchAddress(const GLubyte *procName)
 
 static GLVNDentrypointStub GLXEntrypointUpdateCallback(const char *procName, void *param)
 {
-    __GLXvendorInfo *vendor = (__GLXvendorInfo *) vendor;
+    __GLXvendorInfo *vendor = (__GLXvendorInfo *) param;
     __GLXextFuncPtr addr = NULL;
 
     addr = vendor->glxvc->getDispatchAddress((const GLubyte *) procName);
@@ -489,7 +489,6 @@ __GLXvendorInfo *__glXLookupVendorByName(const char *vendorName)
 
             HASH_ADD_KEYPTR(hh, _LH(__glXVendorNameHash), vendor->name,
                             strlen(vendor->name), pEntry);
-            LKDHASH_UNLOCK(__glXVendorNameHash);
 
             // Look up the dispatch functions for any GLX extensions that we
             // generated entrypoints for.
@@ -501,10 +500,8 @@ __GLXvendorInfo *__glXLookupVendorByName(const char *vendorName)
                 const char *procName = __glvndWinsysDispatchGetName(i);
                 vendor->glxvc->setDispatchIndex((const GLubyte *) procName, i);
             }
-        } else {
-            /* Some other thread added a vendor */
-            LKDHASH_UNLOCK(__glXVendorNameHash);
         }
+        LKDHASH_UNLOCK(__glXVendorNameHash);
     }
 
     return &pEntry->vendor;

commit bb67f11d4012492c9eec5a3e4723be66c01a2167
Author: Kyle Brenneman <kbrenneman@nvidia.com>
Date:   Tue Apr 5 15:55:50 2016 -0600

    tests: Merge the dummy and patchentry libraries.
    
    Remove the libGLX_patchentry dummy vendor library. The libGLX_dummy.so library
    will provide the entrypoint patching callbacks based on an environment
    variable.

diff --git a/tests/GLX_dummy/GLX_dummy.c b/tests/GLX_dummy/GLX_dummy.c
index 9e234bf..4cae6bb 100644
--- a/tests/GLX_dummy/GLX_dummy.c
+++ b/tests/GLX_dummy/GLX_dummy.c
@@ -627,7 +627,6 @@ static void         dummySetDispatchIndex      (const GLubyte *procName, int ind
     }
 }
 
-#if defined(PATCH_ENTRYPOINTS)
 PUBLIC int __glXSawVertex3fv;
 
 static void patch_x86_64(char *writeEntry,
@@ -788,7 +787,15 @@ static GLboolean dummyInitiatePatch(int type,
     return GL_TRUE;
 }
 
-#endif // defined(PATCH_ENTRYPOINTS)
+static Bool GetEnvFlag(const char *name)
+{
+    const char *env = getenv(name);
+    if (env != NULL && atoi(env) != 0) {
+        return True;
+    } else {
+        return False;
+    }
+}
 
 PUBLIC Bool __glx_Main(uint32_t version,
                                   const __GLXapiExports *exports,
@@ -807,10 +814,11 @@ PUBLIC Bool __glx_Main(uint32_t version,
             imports->getProcAddress = dummyGetProcAddress;
             imports->getDispatchAddress = dummyGetDispatchAddress;
             imports->setDispatchIndex = dummySetDispatchIndex;
-#if defined(PATCH_ENTRYPOINTS)
-            imports->isPatchSupported = dummyCheckPatchSupported;
-            imports->initiatePatch = dummyInitiatePatch;
-#endif
+
+            if (GetEnvFlag("GLVND_TEST_PATCH_ENTRYPOINTS")) {
+                imports->isPatchSupported = dummyCheckPatchSupported;
+                imports->initiatePatch = dummyInitiatePatch;
+            }
 
             return True;
         }
diff --git a/tests/GLX_dummy/Makefile.am b/tests/GLX_dummy/Makefile.am
index 54e0976..4fb1506 100644
--- a/tests/GLX_dummy/Makefile.am
+++ b/tests/GLX_dummy/Makefile.am
@@ -1,5 +1,5 @@
 noinst_HEADERS = GLX_dummy.h
-check_LTLIBRARIES = libGLX_dummy.la libGLX_patchentry.la
+check_LTLIBRARIES = libGLX_dummy.la
 
 check-local: libGLX_dummy_copy
 
@@ -32,8 +32,3 @@ libGLX_dummy_la_LIBADD = $(top_builddir)/src/util/libtrace.la
 libGLX_dummy_la_LIBADD += $(top_builddir)/src/util/libutils_misc.la
 libGLX_dummy_la_LDFLAGS = $(COMMON_LDFLAGS)
 
-libGLX_patchentry_la_CFLAGS = $(COMMON_CFLAGS) -DPATCH_ENTRYPOINTS
-libGLX_patchentry_la_SOURCES = $(COMMON_SOURCES)
-libGLX_patchentry_la_LIBADD = $(top_builddir)/src/util/libtrace.la
-libGLX_patchentry_la_LIBADD += $(top_builddir)/src/util/libutils_misc.la
-libGLX_patchentry_la_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/tests/testpatchentrypoints.c b/tests/testpatchentrypoints.c
index 59ba045..a573129 100644
--- a/tests/testpatchentrypoints.c
+++ b/tests/testpatchentrypoints.c
@@ -41,7 +41,7 @@ int main(int argc, char **argv)
         goto fail;
     }
 
-    vendorHandle = dlopen("libGLX_patchentry.so", RTLD_LAZY);
+    vendorHandle = dlopen("libGLX_dummy.so", RTLD_LAZY);
     if (!vendorHandle) {
         printError("No valid vendor library handle\n");
         goto fail;
diff --git a/tests/testpatchentrypoints.sh b/tests/testpatchentrypoints.sh
index fcd2b81..cfd7cfb 100755
--- a/tests/testpatchentrypoints.sh
+++ b/tests/testpatchentrypoints.sh
@@ -1,6 +1,7 @@
 #!/bin/bash
 
-export __GLX_VENDOR_LIBRARY_NAME=patchentry
+export __GLX_VENDOR_LIBRARY_NAME=dummy
+export GLVND_TEST_PATCH_ENTRYPOINTS=1
 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TOP_BUILDDIR/tests/GLX_dummy/.libs
 
 # Run the patch entrypoint test.

commit 198b0b0897979c8f9f187821fcca90edaf8e2301
Author: Kyle Brenneman <kbrenneman@nvidia.com>
Date:   Tue Mar 29 15:12:40 2016 -0600

    tests: Expand the MakeCurrent tests to the GLXFBConfig-based functions.
    
    The testglxmakecurrent tests will now test both the GLXFBConfig and
    XVisualInfo-based GLX functions.
    
    The tests will also now cover using glXCreateContextAttribsARB to create a
    rendering context.

diff --git a/tests/test_utils.c b/tests/test_utils.c
index ec81fff..d4a9d90 100644
--- a/tests/test_utils.c
+++ b/tests/test_utils.c
@@ -33,7 +33,7 @@
 #include <string.h>
 #include <assert.h>
 
-GLboolean testUtilsCreateWindow(Display *dpy,
+static GLboolean CommonCreateWindow(Display *dpy, 
                                 struct window_info *wi,
                                 int screen)
 {
@@ -41,20 +41,49 @@ GLboolean testUtilsCreateWindow(Display *dpy,
     XSetWindowAttributes wattr;
     int wattr_mask;
 
+    root = RootWindow(dpy, screen);
+
+    wi->cmap = XCreateColormap(dpy, root, wi->visinfo->visual, AllocNone);
+
+    if (!wi->cmap) {
+        printError("Failed to create colormap!\n");
+        return GL_FALSE;
+    }
+
+    wattr_mask = CWBackPixmap | CWBorderPixel | CWColormap;
+    wattr.background_pixmap = None;
+    wattr.border_pixel = 0;
+    wattr.bit_gravity = StaticGravity;
+    wattr.colormap = wi->cmap;
+
+    wi->win = XCreateWindow(dpy, root, 0, 0, 512, 512, 0,
+                            wi->visinfo->depth, InputOutput,
+                            wi->visinfo->visual, wattr_mask, &wattr);
+
+    if (!wi->win) {
+        printError("Failed to create window!\n");
+        return GL_FALSE;
+    }
+
+    return GL_TRUE;
+}
+
+GLboolean testUtilsCreateWindow(Display *dpy,
+                                struct window_info *wi,
+                                int screen)
+{
     int visattr[] = {
-        GLX_CONFIG_CAVEAT, GLX_NONE,
-        GLX_RENDER_TYPE, GLX_RGBA_BIT,
+        GLX_RGBA,
         GLX_RED_SIZE, 1,
         GLX_GREEN_SIZE, 1,
         GLX_BLUE_SIZE, 1,
-        GLX_DOUBLEBUFFER, 1,
+        GLX_DOUBLEBUFFER,
         None,
     };
 
     memset(wi, 0, sizeof(*wi));
 
     wi->dpy = dpy;
-    root = RootWindow(dpy, screen);
 
     wi->visinfo = glXChooseVisual(dpy, screen, visattr);
     if (!wi->visinfo) {
@@ -62,29 +91,58 @@ GLboolean testUtilsCreateWindow(Display *dpy,
         return GL_FALSE;
     }
 
-    wi->cmap = XCreateColormap(dpy, root, wi->visinfo->visual, AllocNone);
-
-    if (!wi->cmap) {
-        printError("Failed to create colormap!\n");
+    if (!CommonCreateWindow(dpy, wi, screen)) {
         return GL_FALSE;
     }
 
-    wattr_mask = CWBackPixmap | CWBorderPixel | CWColormap;
-    wattr.background_pixmap = None;
-    wattr.border_pixel = 0;
-    wattr.bit_gravity = StaticGravity;
-    wattr.colormap = wi->cmap;
+    wi->draw = wi->win;
+    return GL_TRUE;
+}
 
-    wi->win = XCreateWindow(dpy, root, 0, 0, 512, 512, 0,
-                            wi->visinfo->depth, InputOutput,
-                            wi->visinfo->visual, wattr_mask, &wattr);
+GLboolean testUtilsCreateWindowConfig(Display *dpy,
+                                struct window_info *wi,
+                                int screen)
+{
+    int configAttr[] = {
+        GLX_CONFIG_CAVEAT, GLX_NONE,
+        GLX_RENDER_TYPE, GLX_RGBA_BIT,
+        GLX_RED_SIZE, 1,
+        GLX_GREEN_SIZE, 1,
+        GLX_BLUE_SIZE, 1,
+        GLX_DOUBLEBUFFER, 1,
+        None,
+    };
 
-    if (!wi->win) {
-        printError("Failed to create window!\n");
+    GLXFBConfig *configs = NULL;
+    int numConfigs = 0;
+
+    memset(wi, 0, sizeof(*wi));
+
+    wi->dpy = dpy;
+
+    configs = glXChooseFBConfig(dpy, screen, configAttr, &numConfigs);
+    if (numConfigs <= 0 || configs == NULL) {
+        printError("Failed to find a suitable GLXFBConfig!\n");
         return GL_FALSE;
     }
+    wi->config = configs[0];
+    XFree(configs);
 
+    wi->visinfo = glXGetVisualFromFBConfig(dpy, wi->config);
+    if (!wi->visinfo) {
+        printError("Failed to find a suitable visual!\n");
+        return GL_FALSE;
+    }
+
+    if (!CommonCreateWindow(dpy, wi, screen)) {
+        return GL_FALSE;
+    }
 
+    wi->draw = glXCreateWindow(dpy, wi->config, wi->win, NULL);
+    if (wi->draw == None) {
+        printError("Failed to create GLXWindow\n");
+        return GL_FALSE;
+    }
     return GL_TRUE;
 }
 
@@ -92,12 +150,23 @@ void testUtilsDestroyWindow(Display *dpy,
                             struct window_info *wi)
 {
     assert(dpy == wi->dpy);
+    if (wi->config != NULL) {
+        if (wi->draw != None) {
+            glXDestroyWindow(dpy, wi->draw);
+            wi->draw = None;
+        }
+    }
     if (wi->win) {
         XDestroyWindow(dpy, wi->win);
+        wi->win = None;
     }
     if (wi->cmap) {
         XFreeColormap(dpy, wi->cmap);
+        wi->cmap = None;
+    }
+    if (wi->visinfo != NULL) {
+        XFree(wi->visinfo);
+        wi->visinfo = NULL;
     }
-    XFree(wi->visinfo);
 }
 
diff --git a/tests/test_utils.h b/tests/test_utils.h
index 73c33ff..6a88d17 100644
--- a/tests/test_utils.h
+++ b/tests/test_utils.h
@@ -40,13 +40,20 @@
 struct window_info {
     Display *dpy;
     Window win;
+    GLXDrawable draw;
     XVisualInfo *visinfo;
+    GLXFBConfig config;
     Colormap cmap;
 };
 
 GLboolean testUtilsCreateWindow(Display *dpy,
                                 struct window_info *wi,
                                 int screen);
+
+GLboolean testUtilsCreateWindowConfig(Display *dpy,
+                                struct window_info *wi,
+                                int screen);
+
 void testUtilsDestroyWindow(Display *dpy,
                             struct window_info *wi);
 
diff --git a/tests/testglxmakecurrent.c b/tests/testglxmakecurrent.c
index b3b886f..d3ea070 100644
--- a/tests/testglxmakecurrent.c
+++ b/tests/testglxmakecurrent.c
@@ -46,10 +46,19 @@
 // For glMakeCurrentTestResults()
 #include "GLX_dummy/GLX_dummy.h"
 
+enum
+{
+    TEST_VISUAL,
+    TEST_CONFIG,
+    TEST_CONTEXT_ATTRIBS,
+    TEST_MAX
+};
+
 typedef struct TestOptionsRec {
     int iterations;
     int threads;
     GLboolean late;
+    int testType;
 } TestOptions;
 
 static void print_help(void)
@@ -151,6 +160,7 @@ void *MakeCurrentThread(void *arg)
     intptr_t ret = GL_FALSE;
     const TestOptions *t = (const TestOptions *)arg;
     Display *dpy;
+    GLboolean success;
 
     memset(&wi, 0, sizeof(wi));
 
@@ -172,14 +182,35 @@ void *MakeCurrentThread(void *arg)
         }
     }
 
-    if (!testUtilsCreateWindow(dpy, &wi, 0)) {
+    if (t->testType == TEST_VISUAL) {
+        success = testUtilsCreateWindow(dpy, &wi, 0);
+    } else {
+        success = testUtilsCreateWindowConfig(dpy, &wi, 0);
+    }
+    if (!success) {
         printError("Failed to create window!\n");
         goto fail;
     }
 
     // TODO: Might be a good idea to try sharing contexts/windows between
     // threads
-    ctx = glXCreateContext(dpy, wi.visinfo, NULL, GL_TRUE);
+    if (t->testType == TEST_VISUAL) {
+        ctx = glXCreateContext(dpy, wi.visinfo, NULL, True);
+    } else if (t->testType == TEST_CONFIG) {
+        ctx = glXCreateNewContext(dpy, wi.config, GLX_RGBA_TYPE, NULL, True);
+    } else if (t->testType == TEST_CONTEXT_ATTRIBS) {
+        PFNGLXCREATECONTEXTATTRIBSARBPROC ptr_glXCreateContextAttribsARB;
+        ptr_glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
+            glXGetProcAddress((const GLubyte *) "glXCreateContextAttribsARB");
+        if (ptr_glXCreateContextAttribsARB == NULL) {
+            printError("Can't find function glXCreateContextAttribsARB!\n");
+            goto fail;
+        }
+        ctx = ptr_glXCreateContextAttribsARB(dpy, wi.config, NULL, True, NULL);
+    } else {
+        printf("Invalid test type %d\n", t->testType);
+        abort();
+    }
     if (!ctx) {
         printError("Failed to create a context!\n");
         goto fail;
@@ -187,7 +218,7 @@ void *MakeCurrentThread(void *arg)
 
     for (i = 0; i < t->iterations; i++) {
 
-        if (!glXMakeContextCurrent(dpy, wi.win, wi.win, ctx)) {
+        if (!glXMakeContextCurrent(dpy, wi.draw, wi.draw, ctx)) {
             printError("Failed to make current!\n");
             goto fail;
         }
@@ -287,16 +318,11 @@ int main(int argc, char **argv)
     TestOptions t;
     int i;
     void *ret;
+    int all_ret = 0;
 
     init_options(argc, argv, &t);
 
-    if (t.threads == 1) {
-        ret = MakeCurrentThread((void *)&t);
-        return ret ? 0 : 1;
-    } else {
-        glvnd_thread_t *threads = malloc(t.threads * sizeof(glvnd_thread_t));
-        int all_ret = 0;
-
+    if (t.threads > 1) {
         XInitThreads();
 
         glvndSetupPthreads();
@@ -304,24 +330,36 @@ int main(int argc, char **argv)
         if (__glvndPthreadFuncs.is_singlethreaded) {
             exit(1);
         }
+    }
 
-        for (i = 0; i < t.threads; i++) {
-            if (__glvndPthreadFuncs.create(&threads[i], NULL, MakeCurrentThread, (void *)&t)
-                != 0) {
-                printError("Error in pthread_create(): %s\n", strerror(errno));
-                exit(1);
-            }
-        }
-
-        for (i = 0; i < t.threads; i++) {
-            if (__glvndPthreadFuncs.join(threads[i], &ret) != 0) {
-                printError("Error in pthread_join(): %s\n", strerror(errno));
-                exit(1);
-            }
+    for (t.testType = 0; t.testType < TEST_MAX; t.testType++) {
+        fprintf(stderr, "Testing with method %d\n", (int) t.testType);
+        if (t.threads == 1) {
+            ret = MakeCurrentThread((void *)&t);
             if (!ret) {
                 all_ret = 1;
             }
+        } else {
+            glvnd_thread_t *threads = malloc(t.threads * sizeof(glvnd_thread_t));
+
+            for (i = 0; i < t.threads; i++) {
+                if (__glvndPthreadFuncs.create(&threads[i], NULL, MakeCurrentThread, (void *)&t)
+                    != 0) {
+                    printError("Error in pthread_create(): %s\n", strerror(errno));
+                    exit(1);
+                }
+            }
+
+            for (i = 0; i < t.threads; i++) {
+                if (__glvndPthreadFuncs.join(threads[i], &ret) != 0) {
+                    printError("Error in pthread_join(): %s\n", strerror(errno));
+                    exit(1);
+                }
+                if (!ret) {
+                    all_ret = 1;
+                }
+            }
         }
-        return all_ret;
     }
+    return all_ret;
 }



Reply to: