libEGL will now forward calls to eglBindAPI to the vendor libraries.
Defined as part of the interface that libEGL only supports OpenGL and GLES.
This should simplify the task of porting a driver to EGL, since the eglBindAPI
behavior is closer to a non-glvnd driver.
In __glXAPITeardown, use pthread_mutex_trylock to take the context hash mutex,
and just skip freeing the context data if the mutex isn't available.
In some cases, such as a multi-threaded program that hits an X11 I/O error,
another thread could be blocked in a glXMakeCurrent call, and so trying to take
the context list mutex would deadlock.
In addition, fix the current context bookkeeping in fork recovery. After a
fork, the contexts should still exist, but none of them will be current
anymore.
In __glDispatchFini, remove the assert that the current context list is empty.
Even though libGLX/libEGL will clear out the current context for the current
thread, another thread may still have a current context.
Implemented the EGL_KHR_debug extension in libEGL.
Updated the error reporting throughout libEGL to call the debug callback.
This requires that all vendor libraries also support EGL_KHR_debug. The reason
is that the debug callback has to be called every time an EGL error is
generated, and vendor libraries are still responsible for keeping track of EGL
errors on their own.
libEGL should be able to cope with a vendor library that doens't support
EGL_KHR_debug, but if that vendor library is used, then the extension won't
work correctly.
The implementation is mostly based off of libGLX.
Unlike GLX, libEGL will load all vendor libraries up front. This is necessary
for dealing with eglGetPlatformDisplay, as well as many client extensions.
Dispatching EGL functions is generally simpler than GLX. All display extension
functions by definition can be dispatched based on an EGLDisplay handle, so
it doesn't need to provide lookup functions for contexts or surfaces, and
vendor libraries don't have to add any EGL objects to tracking.
Only OpenGL and OpenGL ES and a handful of client extensions are supported so
far.
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>
Added a license+copyright comment to winsys_dispatch.[ch].
Renamed __GLVNDwinsysDispatchIndexHash to __GLVNDwinsysDispatchIndexEntry,
since it's not a hashtable anymore.
In __glXLookupVendorByName, only call __glvndWinsysDispatchGetCount once
instead of on every loop iteration.
Removed the locks for the GLX dispatch index list and the generated GLX
dispatch stubs. Instead, the vendor hashtable's lock is used for all three.
There's enough overlap between when the three locks are taken that using
separte locks has very little benefit and increases the risk of deadlocks.
Added functions to create and manage a per-vendor dispatch table for
window-system functions.
These will replace the __GLXdispatchFuncHash hashtable in GLX.
Some minor cleanup of __glXFetchDispatchEntry.
Handle the various failure cases more directly: If we can't find a name, or if
the vendor library doesn't support a function, then return early.
If we can't allocate a cache entry for the function, then return the dispatch
stub anyway. It can try to store the stub again next time.
In cacheProcAddress, check if the function is already in the hashtable before
trying to add it. It's possible that another thread might have already called
glXGetProcAddress for the same function.
In addition, allocate each cache entry with a single malloc instead of a malloc
and a strdup.
The dispatch functions in libGLX are now added to the GLX dispatch list just
like vendor-provided dispatch functions would be.
The function name cache in glXGetProcAddress is no longer required for
correctness, because it can look up a locally-defined dispatch stub in the same
list as the vendor-provided stubs.
In addition to simplifying glXGetProcAddress, this allows vendor libraries to
look up all GLX functions by index. In particular, this would allow a vendor
to look up glXDestroyContext, which would let it recover properly if it fails
to add a new context to the context-to-vendor mapping.
Remove the __GLXdispatchIndexHash table, and use the list in winsys_dispatch.c
to keep track of the function indices, names, and dispatch stubs.
If libGLX generates a GLX dispatch stub, then it will now assign an index to it
when it generates the stub, not when it fills in the stub. That lets it treat
generated stubs the same way regardless of whether they've been filled in or
not.
When assigning an index, it will now call the setDispatchIndex callback for
every vendor library, not just the vendor that provided the dispatch stub.
When loading a vendor library, it will call the new vendor's setDispatchIndex
callback for every existing GLX dispatch function.
Added a new file, winsys_dispatch.c, with functions for keeping track of the
indices, names, and dispatch stubs for window-system functions.
This will replace the __GLXdispatchIndexHash hashtable in GLX.
It's independant of the window system, so it should be usable for EGL as well.
Fix the warnings that autogen.sh spits out.
Added libtool convenience libraries for the source files in src/util instead of
including them directly in other makefiles. This avoids a bunch of
subdir-objects warnings.
Added libtool convenience libraries for each of the glapi builds.
Flattened the vnd-glapi directory. In theory, just setting the subdir-objects
flag should be enough, but that causes failures where "make distcheck" doesn't
build all of the source files.
Removed the header file and the script to generate the __glXDispatchNoopPtr
table.
Also removed the dependency on Perl from configure.ac, since the rest of the
scripts are in Python.
Reviewed-by: aplattner@nvidia.com
Removed the functions __glXGetCurrentDispatch and __glXGetStaticDispatch.
Everything that used either one now looks up the __GLXvendorInfo pointer
instead.
Also removed __glXGetGLDispatch, since it's not used anywhere.
Reviewed-by: aplattner@nvidia.com
In MergeExtensionStrings currentString was read after it was realloc'ed
to make space for the extra extensions.
This patch makes the function read the realloc'ed memory instead. To
allow that to work 'buf' has to be null terminated on after every
extra extension is written.
Moved everything under src/GLdispatch/vnd-glapi/mapi/ to
src/GLdispatch/vnd-glapi.
Removed the subdir-objects flag.
Using subdir-objects causes errors when you do a make followed by a
"make distcheck", because for some reason the distcheck doesn't build all of
the source files.
Add GL_OES_point_size_array to the set of features and extensions that are
exported from libGLESv1_CM.so.
According to the OpenGL ES 1.1 spec, all required extensions are supposed to be
statically exported from the library. GL_OES_point_size_array is the only
required extension that defines any functions.
Move the various vnd-glapi builds into individual .la files in the vnd-glapi
makefile, instead of defining them in the OpenGL, GL, GLESv1, and GLESv2
makefiles.
Fixed a few order and variable name warnings.
Defined convenience libraries for the source files under src/util, to avoid the
subdir-objects warning from them.
If glXDestroyContext is called with NULL for the GLXContext, then it will now
report an error using glvndAppErrorCheckReportError but it won't generate a
GLXBadContext error.
Some existing drivers (NVIDIA, Mesa, and possibly others) will just silently
return in that case, and some applications depend on that behavior.
By the time __glXFini is called, the destructors in the vendor libraries may
have already been called, so it's not safe to call any functions in the vendor
library.
__glXFini will now check for a fork and go through fork recovery, but it won't
call __glDispatchCheckMultithreaded. If there was a current context, then
__glDispatchCheckMultithreaded might call the vendor's thread attach callback.
The libglvnd libraries will now check for a new environment variable,
__GLVND_APP_ERROR_CHECKING. If it's set to a non-zero value, then libglvnd will
check for and report some application errors.
Many non-libglvnd implementations of libGL.so have been fairly tolerant of
certain application bugs. Libglvnd has to be similarly tolerant to support
existing apps that the developers can't or won't fix.
The new __GLVND_APP_ERROR_CHECKING provides a way to check for some of those
errors, so that hopefully there will be fewer broken apps in the future.
In addition to the setting itself, this updates the no-op stubs in
libGLdispatch to report an error when the app tries to call an OpenGL function
without a current context. Later changes will likely add other error checks.
Delete the x11glvnd directory.
Commented out the two tests that depend on it, testx11glvndproto and
testglxnscreens. Eventually, they should be rewritten to use the
GLX_EXT_libglvnd extension instead.
Reworked libGLX.so to use the GLX_EXT_libglvnd extension instead of x11glvnd.
In __glXLookupVendorByScreen, use __glXQueryServerString to look up the vendor
name string, and then split it up with strtok_r.
Move the display pointer from __GLXdisplayInfoHash to __GLXdisplayInfo, so that
we don't have to pass around both the Display and __GLXdisplayInfo pointers to
a function that needs both of them.
libGLX will now use XAddExtension and XESetCloseDisplay to register a callback
when a display is closed.
Removed XGLVRegisterCloseDisplayCallback and
XGLVUnregisterCloseDisplayCallbacks from the x11glvnd client library.
This is in preparation for removing the x11glvnd extension.
Rename __GLdispatchAPIState to __GLdispatchThreadState, to make it clearer that
the structure contains thread-specific data.
Updated some out-of-date comments.
Added the function pointers for entrypoint rewriting as members of
__GLXapiImports, instead of using a separate __GLdispatchPatchCallbacks
pointer.
Moved the __GLdispatchPatchCallbacks struct to GLdispatch.h.
__glx_Main now takes a pointer to the __GLXapiImports struct and fills it in.
The __GLXapiImports struct is now allocated and zeroed by libGLX. This makes it
possible to add an optional element to the end of the struct without breaking
backward compatibility.
libGLX now allocates its own copy of the __GLXapiImports struct for each vendor
library. This is in preparation for providing an allocated and zeroed struct to
__glx_Main to fill in.
Removed the vendorID and vendorName parameters from the __glx_Main function,
since neither one is useful to a vendor.
Instead, __glx_Main now takes the __GLXvendorInfo pointer as a parameter. We
can use that to look up any additional per-vendor information that might be
added in the future.
The code was disabled due to a glibc bug 16272. which as of this point
remains open.
As n alternative solution is already in place and fix for the mentioned
issue is unlikely to land in order distributions, it does not make it a
viable solution that we can use (in the near future).
Drop the code for now, to prevent anyone building a completely broken
library.
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
... as opposed to hardcoding it. While we're here tweak the whole
command to use the standard - AM_V_at and @D, as opposed to @ and dir $@
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
Removed the distinction between TSD and TLS stubs, since that doesn't matter to
a vendor library. There's now a single type for the x86 stubs and a single type
for the x86-64 stubs.
Added a separate type enum for normal ARM and thumb stubs. As with x86, there's
no distinction between TLS and TSD.
Changed the __GLDISPATCH_STUB_PURE_C enum to a more generic
__GLDISPATCH_STUB_UNKNOWN.
Also removed the internal ENTRY_* enums and changed everything to use the
__GLDISPATCH_STUB_* enums instead.
Changed vendorFromContext, vendorFromFBConfig, and vendorFromDrawable to return
the vendor pointer as its return value instead of using a pointer.
Returning by pointer was necessary when the functions would also return a
screen number. But, GLX objects are now associated directly with a vendor,
not with any particular screen or display.
Removed addScreenVisualMapping, removeScreenVisualMapping, and vendorFromVisual
from __GLXapiExports.
The XVisualInfo to vendor mapping is a no-op, since it just uses the screen number
to select a vendor.
It might be useful in the future at some point to provide a mechanism for
selecting between multiple vendors on a single X screen, but such an option
would more likely be used with the GLXFBConfig-based functions, not with the
XVisualInfo-based ones.
The addVendorContextMapping, addVendorFBConfigMapping, and
addVendorDrawableMapping functions in __GLXapiExports now return an int to
indicate success or failure.
Updated the various GLX functions so that they will deal with those failures.
In the case of context and drawable creations functions, it will call back into
the vendor library to destroy the object before returning.
The threadAttach callback is used so that a vendor library can go through any
thread initialization it needs to in order to deal with any later OpenGL calls.
This allows a vendor library to work around broken applications that try to
call OpenGL functions without a current context.
Fix a duplicate typedef of __GLXcontextInfo in libglx.c and libglxcurrent.h.
That causes an error with some compilers.
Reviewed-by: Andy Ritger <aritger@nvidia.com>
Remove the __GLXdispatchTableDynamic struct. Move the hashtable that it
contained to be a member of __GLXvendorInfo instead.
Reviewed-by: Andy Ritger <aritger@nvidia.com>
The __GLXvendorNameHash, __GLXvendorInfo, and vendor name are now allocated in
a single malloc.
Remove some duplicated cleanup code between TeardownVendor and
__glXLookupVendorByName.
Merge TeardownVendor into CleanupVendorNameInto.
In __glXLookupVendorByName, simplify the cleanup path on error. Remove the
local variables that are just copies of the __GLXvendorInfo members.
Remove InitExportsTable and statically initialize the glxExportsTable struct.
Reviewed-by: Andy Ritger <aritger@nvidia.com>
As pointed out with commit d5bc0866a8 "Check for glproto in
configure.ac" we want to rely on the upstream/distribution provided
package. Thus lets remove the in-tree copy.
Also make sure we use the headers (add the missing CFLAGS).
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
Rework the context tracking in libGLX.so so that it can handle a context that's
current to more than one thread at a time.
There's now a single hashtable to keep track of contexts, which replaces both
the (context -> vendor) map and the current context map.
The new __GLXcontextInfo struct keeps track of the number of threads where the
context is current, and whether the context is marked for deletion.
This also provides a workaround of sorts for some broken applications, which
try (and fail) to make a context current on two threads at the same time, and
aren't prepared to deal with the resulting BadAccess error. Moving the
duplicate context check into the vendor library allows it to preserve that
pre-libglvnd behavior for apps that depend on it.
Reviewed-by: Andy Ritger <aritger@nvidia.com>
Moved glvnd_pthread.h and glvnd_pthread.c into src/utils, and removed the
separate makefile for them. The other makefiles now just grab the source file
directly instead.
Reviewed-by: Andy Ritger <aritger@nvidia.com>
The macros in lkdhash.h now just use the __glvndPthreadFuncs table, instead of
taking a GLVNDPthreadFuncs parameter.
Reviewed-by: Andy Ritger <aritger@nvidia.com>
glvnd_pthread.h and glvnd_pthread.c now declare and define a GLVNDPthreadFuncs
struct, instead of having a separate declaration in libGLX and libGLdispatch.
This mostly just simplifies initialization a bit, but it will also make it
easier to have common code that uses pthreads functions.
Reviewed-by: Andy Ritger <aritger@nvidia.com>
The X headers define MODULEVENDORSTRING like so:
#ifndef MODULEVENDORSTRING
#define MODULEVENDORSTRING "X.Org Foundation"
#endif
This allows module vendors such as NVIDIA to override the vendor string at build
time, rather than hard-coding "NVIDIA Corporation" in the sources.
Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
Reviewed-by: Kyle Brenneman <kbrenneman@nvidia.com>
Fixes#48.
This makes the built-in x86_64 TSD stubs use RIP-relative addressing so
that the linker doesn't have to generate relocations of text sections,
which breaks PIC.
Fixes#53
__glDispatchCheckMultithreaded will now check if the thread's current dispatch
table is NULL, and if it is, it will plug in the no-op table.
This is a workaround for some broken applications which try to call OpenGL
functions without a current context. As long as the thread calls a GLX function
first, any OpenGL calls it makes later will call a no-op stub instead of just
crashing.
Added calls to __glXThreadInitialize to some of the functions in
__GLXapiExports, so that GLX extension functions will still call
__glXThreadInitialize.
Removed several header files that were copied from Mesa but aren't used in
libglvnd.
Removed everything under src/arch, also copied from Mesa but unused.
Two header files (libglxabi.h and GLdispatchABI.h) are public -- intended to be
used by vendor libraries, while the other headers are all internal to libglvnd.
Move the public header files to a new directory, include/glvnd.
Add a makefile so that the public headers are installed by make install.
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>
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.
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.
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.
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.
libGLX now only keeps track of the vendor library for each drawable, not the
screen number.
__glXVendorFromDrawable will now always return -1 for the screen. The screen
parameter will be removed in a later change.
When dispatching a function based on a GLXDrawable, generate an X error if the
drawable is invalid.
Added a helper function CommonDispatchDrawable to handle initialization,
looking up a vendor for a drawable, and reporting an error if it can't find
a vendor.
Removed __glXGetDrawableStaticDispatch, and replaced it with
CommonDispatchDrawable.
Removed the unused function __glXScreenFromDrawable.
Change the current context hash to use a recursive mutex instead of an rwlock.
In __glXLookupDisplay, don't take the lock until after InitDisplayInfoEntry
returns, so that it doesn't try to make any X calls while holding the lock.
If an X error occurs while holding a non-recursive lock, then the error handler
may call exit, which would in turn call __glXFini. That can cause a deadlock if
__glXFini tries to take the same lock.
In CommonMakeCurrent, if the new context is NULL and the drawables are not
None, then it should always generate a BadMatch error. But, if the old context
was NULL, then it would return before checking for the BadMatch error.
In MergeVersionStrings, deal with a zero return value from glvnd_asprintf. Zero
is technically a successful return value from glvnd_asprintf, even though none
of the format strings could produce it.
Remove a bit of dead code from AtomicDecrementClampAtZero. The only way for the
if(newVal < 0) branch to be taken is if (oldVal <= 0), which it can't be at
that point.
Added a Makefile to build libGLESv1_CM.so. It's copied and adapted from the one
for libOpenGL.so.
The GLESv1 library currently exports all of the core functions in gl.xml for
GLES version 1.0.
Added a Makefile to build libGLESv2.so. It's copied and adapted from the one
for libOpenGL.so.
The GLESv2 library currently exports all of the core functions in gl.xml for
GLES versions 2.0 through 3.2, inclusive.
In genCommon.py, change getLibOpenGLNamesFromRoots so that it accepts a target
parameter. Defined separate targets for each library, including libGLdispatch.
gen_libOpenGL_exports.py now takes a target parameter just like
gen_gldispatch_mapi.py does.
This is in preparation for adding function lists for the libGLES libraries.
Rewrote the x86 TSD stubs to follow the same pattern and use the same common
functions as the x86-64 stubs.
Aside from being shorter and simpler with less code duplicaiton, this will
allow entrypoint patching to work in the x86 build.
Fixed some errors in the entrypoint patching in the unit tests. The
libGLX_dummy.so library was patching in PC-relative addresses for the MOV
instructions, but those instructions expect absolute addresses.
Add a documentation comment to entry_get_public, and change the name of the
parameter to indicate that it takes an array index instead of a dispatch table
slot.
gen_gldispatch_mapi.py now takes an extra parameter to specify which library
it's building, so that it can generate the correct function list for that
library. For libOpenGL.so, it will only generate the functions that it's going
to export.
Updated the makefiles for libOpenGL.so, libGL.so, and libGLdispatch.so to
generate the correct set of entrypoints for each library.
Moved the code to figure out the libOpenGL.so function names to genCommon.py.
Fix a couple of places that assume that the public stub array (as defined in
entry*.c) is in the same order as the dispatch table.
stub_get_addr will now calculate the index of the stub instead of assuming that
the slot and index are the same.
In stubRestoreFuncsInternal, it will run through the length of the public_stubs
array instead of assuming that the array is of length MAPI_TABLE_NUM_STATIC.
This will allow us to remove all the entrypoints in libOpenGL.so that we're
not going to export.
Added an export list for libGLdispatch.so, so that it doesn't export the OpenGL
entrypoints.
The OpenGL entrypoints should only be exposed through libGL.so or libOpenGL.so,
not through libGLdispatch.so.
Added two additional XML files which contain additional GL and GLX functions
that are exported from existing libGL.so implementations but are missing from
the Khronos XML files.
Adjusted the scripts so that they can take a list of XML files instead of just
one.
Added a new script to generate the GLX entrypoints in libGL. The new script
uses Khronos's glx.xml file for a function list.
Checked in a copy of Khronos's glx.xml, from revision 32184.
Added the gen_libOpenGL_exports.py script, which will generate an export list
for building libOpenGL.so.
With this, libOpenGL.so will only export OpenGL core functions up through
OpenGL 4.5.
Add new scripts to replace the GLAPI code generation scripts, using the
Khronos gl.xml file.
All of the scripts are rewritten from scratch, but intended to produce similar
output files to the original scripts:
gen_gldispatch_mapi.py replaces mapi_abi.py, originally from Mesa's mapi_abi.py.
gl_inittable.py and gl_table.py replace the scripts of the same name in
GLdispatch/vnd-glapi/mapi/glapi/gen. Both are originally derived from
Mesa's gl_gentable.py and gl_table.py.
Checked in a copy of Khronos's gl.xml, from revision 32184.
Added a typedef for GLDEBUGPROCKHR to the scripts that need it, so that the
GLES versions of GL_khr_debug will compile.
libGL.so and libOpenGL.so now export the full set of OpenGL functions,
including any extensions.
Changed __GLXapiExports::vendorFromContext so that it only takes a GLXContext
parameter as input, and returns the display, screen, and vendor for the
context.
This is needed to support a dispatch function for glXGetContextIDEXT, since it
only takes a GLXContext handle, not a display.
In libglxmapping.c, the __GLXscreenPointerMappingHash struct now keeps the
display pointer along with the screen number.
Also added an error check for GLXFBConfigs to make sure that the display passed
from the caller matches the recorded one.
Added dispatch functions to libGLX for glXImportContextEXT and
glXFreeContextEXT, since both of them are difficult to implement as a dispatch
function from a vendor library.
Since glXImportContextEXT doesn't take any parameters that directly specify a
screen, it will query the server manually to figure out a screen number.
libGLX will now report any X errors that it generates directly, instead of
relying on a vendor library to report them.
For simply reporting errors, the notifyError callback in every vendor library
is functionally identical, so there's no reason to require every vendor to
implement it.
As a notification, it falls apart in glXMakeContextCurrent, which could have
two different vendor libraries if the drawables are on different screens. In
that case, libGLX has to arbitrarily pick one vendor to notify.
Add a __glXSendError function to libglx.c (based on the same function from
Mesa) to report X errors.
The __GLXapiImports::notifyError callback no longer has to report the X error.
It's mostly a notificaiton, although it returns a boolean value to tell libGLX
whether to report or ignore the error.
In glXMakeCurrent/glXMakeContextCurrent, it will report an error to whatever
vendor library owns the current context (if any), instead of the vendor
libraries for the two drawables. The rest of the function looks to the context
to select a vendor, and the old context is the only one that's valid in this
case.
libGLX will now call XQueryExtension to check the GLX extension the first time
it sees a display.
Add the GLX opcode and error base to __GLXdisplayInfo.
libGLX only gets a callback at thread termination if it has a current context.
If there isn't a current context, then it will leave the thread's __GLXAPIState
in the hashtable until teardown.
Now, libGLX will only keep a __GLXAPIState when it has a current
context. When glXMakeCurrent is called to release the current context, it will
free the __GLXAPIState.
Removed the hashtable for keeping track of the __GLXAPIStates and replaced it
with a linked list.
The getProcAddress callback that libGLdispatch uses to populate the dispatch
table now takes an extra parameter, which contains arbitrary data used by the
callback.
This allows much better flexibility in a how window system library populates a
dispatch table.
Removed the __GLX14EntryPoints structure from the vendor library ABI. Instead,
libGLX will use the getProcAddress callback to look up each function after
loading the library.
Moved the contents of __GLXvendorCallbacks into __GLXapiImports.
Changed __GLXdispatchTableStatic to be a separate struct from __GLXapiImports.
It now contains all of the GLX 1.4 function pointers, replacing __GLX14EntryPoints.
Rename the functions _glapi_get_dispatch and _glapi_set_dispatch to
_glapi_get_current and _glapi_set_current.
Aside from better consistency with _glapi_Current and _glapi_tls_Current, this
should make it easier to avoid name clashes with Mesa's GLAPI functions.
_glapi_get_proc_address (and stub_add_dynamic) will now assign an offset to a
new dynamic stub when it's first generated, instead of waiting until
_glapi_add_dispatch.
Deferring it until _glapi_add_dispatch is only useful for handling aliases
(where multiple functions are assigned to the same dispatch table slot), but
libGLdispatch does not use aliases.
Removed the newProcList list in GLdispatch.c. It'll now add all functions
directly to extProcList.
Removed _glapi_add_dispatch and stub_fix_dynamic.
Removed __glDispatchGetOffset and __glDispatchSetEntry from libGLdispatch.
Neither one is used anywhere, and the dispatch offsets should be an internal
detail of libGLdispatch.
Removed the mutex from stub_find_dynamic. Anything that calls that function
should already be holding the GLdispatch lock.
Also removed the __GLdispatchGetOffsetHook, since nothing uses it anymore.
In libGLdispatch, initialize the pthreads table in a constructor function so
that we can use the dispatch mutex in __glDispatchInit.
In __glDispatchFini, check whether clientRefcount has dropped to zero before
tearing everything down.
libGL and libOpenGL will now call __glDispatchFini when they're unloaded, since
they also call __glDispatchInit.
Removed some unused files and functions.
Removed _GLAPI_EXPORT on a bunch of functions that don't need to be exported.
Removed some unnecessary macros:
Removed the macro u_current, and replaced all references to it with
_glapi_Current or _glapi_tls_Current.
Removed the mapi_table macro, and replaced it with _glapi_table.
Removed the ENTRY_CURRENT_TABLE and ENTRY_CURRENT_TABLE_GET macros.
Cleaned up the code related to storing the current dispatch table:
Rearranged things so that _glapi_* variables and functions are the public
interface to everything else, and the u_current_* functions are the internal
implementation.
Changed _glapi_Current to use the same definition on all builds.
Removed the existing u_current_get and replaced it with u_current_get_internal,
to match u_current_set.
Made _glapi_get_dispatch into a separate (exported) function, rather than a
macro for u_current_get_internal.
Consolidated most of the code for keeping track of the current dispatch table
into u_current.c. Rearranged the file to use a single #if/#else block to
separate the TLS and TSD versions.
Removed all of the non-pthread code. There's no reason to keep it around, since
the rest of libglvnd won't build without pthreads.
Removed most of the contents of u_thread.h, and replaced it with direct calls
to the pthreads functions.
Change libGLdispatch so that it will use separate writable and executable
mappings when it generates dispatch stubs.
Added a function, u_execmem_get_writable that will hand back a writable pointer
for an executable pointer. That avoids having to rework everything else in
libGLdispatch to keep track of both pointers.
The static x86-64 dispatch stubs are now marked as read+execute instead of
read+write+execute. Before patching them, it will call mprotect to make them
writable.
Change __GLdispatchStubPatchCallbacks::restoreFuncs so that it returns a flag
to indicate success or failure.
Issue #37
Fixed a couple lines in the libOpenGL makefile where it was using the wrong
variable name.
Added an explicit -version-info flag for libGLdispatch and libGLX.
Added the --no-undefined linker flag for libOpenGL, libGL, libGLdispatch, and
libGLX on systems where it's available.
This commit adds static and dynamic TSD stubs generation support for ARMv7.
Testing coverage includes all ARM / Thumb mode combinations between
libglvnd and a vendor implementation.
Add a new callback, __GLXvendorCallbacks::checkSupportsScreen to the vendor
library ABI. The callback is used to check if a vendor library can support a
given X screen.
If the vendor library reports that it doesn't support a screen, then libGLX
will use the indirect rendering library instead.
Issue #39.
In stub_add_dynamic, make a copy of the function name to store in the mapi_stub
struct. The name from the caller is the same pointer that the app passed to
glXGetProcAddress, so the app could modify or free it afterward.
Move the vendorID and dispatch members from __GLdispatchAPIState to
__GLdispatchAPIStatePrivate.
How those variables are tracked and used is an internal detail of
libGLdispatch, so they shouldn't be part of the public interface.
__GLdispatchAPIState now has a pointer to an opaque structure, to be used for
arbitrary private data.
This will allow later versions of libGLdispatch to add data for each API state
without changing the binary interface to libGLX.
The struct is mostly empty, but later changes will add more to it.
In AllocExecPages and OpenTempFile, it will first try creating a temp file by
calling open(2) with the O_TMPFILE flag. If that doesn't work, then it'll fall
back to using mkstemp.
__glDispatchMakeCurrent now fails if the current thread already has an API
state.
This removes the complication of dealing with switching directly from one vendor
to another, and makes it easier for __glDispatchMakeCurrent to avoid any side
effects if it fails.
UpdateCurrentContext will now re-use the existing hashtable entry if it's
switching between two contexts, so there's no longer a possibility of malloc
failing. The only case where it can fail now is if there is a new context but
not an old context.
UpdateCurrentContext will handle removing the old context from the context to
screen mapping as appropriate.
In CommonMakeCurrent, when releasing a context or switching between two
contexts with the same vendor, it will now call UpdateCurrentContext once at
the end, since UpdateCurrentContext can't fail in those cases.
Change the code for glXMakeCurrent/glXMakeCurrentContext to better handle
different changes.
If it switches between two contexts that use the same vendor, it will not call
into libGLdispatch, since it would just be switching to all the same
parameters.
If it switches between two contexts that use different vendors, then it will
fully release the current context before making the new context current.
This makes it easier to ensure that libGLX and the vendor libraries stay in a
consistent state, even when recovering from a failure in the vendor library or
in libGLdispatch.
This also means that __glDispatchMakeCurrent is only called when the current
thread has no current API context, so libGLdispatch doesn't need to deal with
switching between two different API states.
AllocExecPages will now try to create a temp file and map it twice, once
writable and once executable. This will allow it to work on systems that don't
allow the same page to be writable and executable.
Issue #37
Added two new functions, AllocExecPages and FreeExecPages, for allocating
executable memory for generating stub functions.
It uses a single mmap right now, but it's set up to return two pointers, so it
will be able to return separate writable and executable mappings. That will let
it work on systems that don't allow pages to be both writable and executable.
The new functions are in utils_misc.c, since it will be needed in both libGLX
and libGLXdispatch.
Remove the isClientAPI parameter from __GLXvendorCallbacksRec::getProcAddress.
The only thing that libGLX can use to determine the the isClientAPI flag is the
function name, which a vendor library could implement just as easily. In
addition, since it would be possible for a GL entrypoint to start with "glX",
the isClientAPI flag isn't always reliable.
Add a version number for the interface between libGLX and libGLdispatch, which
libGLX checks during initialization.
The interface between libGLX and libGLdispatch can and should be a stable ABI,
so that it's more resiliant to version mismatches if they come from different
packages or installers.
The version number is mainly a sanity check in case some future version of
libGLdispatch does change the interface.
Use the AX_CHECK_ENABLE_DEBUG macro to add an --enable-debug option to the
configure script.
Silence an unused variable warning in libglx.c. A variable in CommonMakeCurrent
is only used in asserts, so setting NDEBUG means it's set but never used.
Remove the dbg_configure.sh script.
The only place where the fallback vendor library should ever be used is with
indirect rendering, so "indirect" is a more appropriate name.
In addition, we'll hopefully have a dedicated vendor library for indirect
rendering at some point, instead of having to use another vendor library.
Reworked the __GLdispatchPatchCallbacks interface, mostly toward fixing issue
37.
__GLdispatchPatchCallbacks::initiatePatch now handles the entire patching
process, instead of splitting it between initiatePatch, getOffsetHook, and
finalizePatch.
Added callbacks to __GLdispatchStubPatchCallbacks that are called before and
after calling into the vendor library to patch the entrypoints.
Changed the documentation to say that the vendor library can only change the
entrypoints during the call to initiatePatch. That'll allow libGLdispatch to
change the memory protection before and after the app is finished modifying
the entrypoints.
The callback that a vendor library calls to fetch an entrypoint now returns
separate writable and executable addresses.
Remvoved the context member of __GLdispatchAPIState, and instead added a new
currentContext member to __GLXAPIState.
libGLdispatch only needs the API state pointer, not the window system's context
handle.
This also removes the ill-defined case where a thread could have a current API
state but not a current context.
The "id" member of __GLdispatchAPIState isn't used anywhere in libGLdispatch,
so it doesn't need to be part of libGLdispatch's interface.
Instead, libGLX now stores the thread ID in __GLXAPIState::tid.
Added a pointer to a callback function __GLdispatchAPIState to notify the
window system library of thread termination.
Removed tsdContextKey from libglx.c. It now uses the API state stored in
libGLdispatch and the callback function in __GLdispatchAPIState instead.
libGLX will now free the __GLXAPIState struct for a thread when the thread
terminates, instead of waiting until __glXAPITeardown.
Fixes issue #35
Add a glvnd_key_t key to GLdispatch.c to hold the current API state.
__glDispatchGetCurrentAPIState and __glDispatchGetCurrentContext are now normal
exported functions instead of wrappers around _glapi_get_current.
Removed _glapi_get_current, _glapi_set_current, _glapi_get_context,
_glapi_set_context, and their associated functions in u_current.c.
Removed the U_CURRENT_* constants and replaced them with the corresponding
GLAPI_CURRENT_* constants.
Removed the GLAPI_CURRENT_* enums except for GLAPI_CURRENT_DISPATCH.
Add a _glapi_init function to perform any initialization for the GLAPI layer.
u_current_init will now initialize the TSD keys, instead of trying to create
them when they're first used.
Moved the check to multiple threads to __glDispatchCheckMultithreaded. The
GLAPI layer now just has a _glapi_set_multithread function to tell it to
switch to multi-threaded mode.
Removed glapi/glthread.h, since nothing in it was used anywhere.
Changed glvnd_thread_t to have a "valid" flag to specify an invalid thread ID.
mt_equal will check the valid flag before calling pthread_equal. It will
consider any invalid glvnd_thread_t values as equal, ignoring the pthread_t
handles.
Added a GLVND_THREAD_NULL constant that you can pass to
GLVNDPthreadFuncs.equal.
Moved the logic in glXMakeCurrent and glXMakeContextCurrent to a common
function, CommonMakeCurrent.
glXMakeCurrent/glXMakeContextCurrent will now return early if the old and
new context and drawables are the same.
UpdateCurrentContext no longer tries to look up the current context from TSD.
The MakeCurrent functions already look up the current context, so they just
pass the old context to UpdateCurrentContext.
Implement the assembly code for the x86-64 TSD stubs.
In u_execmem.c, allocate enough space for 64-byte stubs, which is the size of
the new x86-64 TSD stubs.
The new stubs don't fit in 32 bytes, because they have to hold two movabs
instructions to deal with 64-bit addresses, plus push and pop instructions to
preserve the six registers that are used for passing arguments.
Remove the x86 assembly code from entry_x86-64_tsd.h.
Rearranged it to use the same general structure as entry_x86-64_tls.h, so that
it'll work with vendor library patching.
Added a new file entry_x86-64_tsd.h. It's just a copy of entry_x86_tsd.h for
now, since that's the interface that it has to match.
Updated entry.c to use the new file depending on the GLX_USE_TLS macro, just
like it does for x86.
Added a __GLDISPATCH_STUB_X86_64_TSD enum to GLdispatchABI.h, and a
matching ENTRY_X86_64_TSD enum to entry.h.
Added a "--disable-tls" flag to the configure script to tell it not to use a
TLS version.
libGLX will now generate entrypoints for GLX extension functions if it can't
find a dispatch function from a vendor library.
The generated entrypoints will simply jump to a dispatch function. With the
extra layer of indirection, glXGetProcAddress can return a valid function
pointer for GLX extensions before it loads any vendor libraries.
Issue #34.
If the server doesn't support x11glvnd, then use the fallback vendor name
instead of trying to ask the server for a name.
Fix __glXVendorFromDrawable to work without x11glvnd. Since every screen will
use the same vendor in that case, it just returns the vendor from screen zero.
Fix __glXGetDrawableStaticDispatch. It now uses __glXVendorFromDrawable to look
up the vendor for a drawable.
Added functions for allocating and freeing the __GLXdisplayInfoHash structures.
Added an LKDHASH_TEARDOWN call to free the __glXDisplayInfoHash hashtable.
The pthreadFuncs variable is actually referenced from the files that go into
libGL and libOpenGL, even though none of the functions that reference it are
used. That can lead to unresolved symbol errors.
Some compilers raise an error about a duplicate typedef with the forward
declaration of __GLXvendorInfo in libglxabi.h and the definition in
libglxmapping.h.
All of the #ifdefs for dealing with different ABI versions are based on
ABI_VIDEODRV_VERSION, not ABI_EXTENSION_VERSION, so that's what glvSetup should
check.
Add functions to __GLXapiExports to manage mappings from an XVisualInfo to a
vendor.
This should allow the same sort of arbitrary vendor selection for the GLX 1.2
XVisualInfo-based functions as for the GLXFBConfig-based ones.
Change the functions in __GLXapiExports to map from objects (drawables,
contexts, FBConfigs) to (screen, vendor) pairs.
Internally, libGLX still uses an (object -> screen -> vendor) mapping, but now
that's an implementation detail.
Added a XGLVQueryExtension function, and changed XGLVQueryVersion to generate
an error if the extension isn't supported by the server, so that they match
the behavior of other X extensions.
Fixed the padding in the reply structures so that they're all 32 bytes long.
Fixed the order of the request handler array in the server.
glXGetClientString will now allocate a buffer for the string and will merge
the strings from multiple vendor libraries.
For GLX_VENDOR, it will return each vendor library's string, separated by
commas.
For GLX_VERSION, it will report the highest version number of any vendor
library, up to the GLX version that libglvnd itself supports (currently 1.4).
For GLX_EXTENSIONS, it will return the union of all extensions advertised by
all vendor libraries.
Added a __glDispatchCheckMultithreaded function to tell libGLdispatch to check
for multiple threads.
libGLX will now check for a second thread in __glXThreadInitialize.
When ThreadSafe is true, u_current_get_index no longer returns a stale value
from u_current.
Added #ifdefs for the assembler implementations for the __sync intrinsics.
Check the return value of malloc in glvnd_asprintf.
Change x11glvndclient.c back to using a (const char *) for the extension name.
- Add a config check for ((constructor)) and ((destructor)) funciton
attributes.
- Add missing GL/glxmd.h header.
- For sufficiently old gcc versions, revert to inline asm
implementations of Atomic{Increment,Swap,CompareAndSwap}()
- Add a local implementation of asprintf.
- entry_x86_tsd.h: Add missing cast to (char *) in entry_get_public
- glvnd_pthread.[ch]: Only use pthread_rwlock_t if it's available, and fall
back to pthread_mutex_t otherwise.
- trace.c: Add missing _GNU_SOURCE define
- uthash.h: Fix a -Wcast-qual warning
- x11glvndclient.c: Fix a -Wcast-qual warning by using a writable
array for storing the XGLV_EXTENSION_NAME
Based on a patch by Brian Nguyen.
The problem with allocating a mutex on the stack is that every thread
that enters the function is going to get their own copy of the mutex,
which sort of defeats any mutual exclusion you might have been hoping
for.
Signed-off-by: Adam Jackson <ajax@redhat.com>
Mesa already needs ~700 bytes here. Obviously this still wants to be a
proper union operation, but this gets me non-truncated output in
glxinfo for now.
Signed-off-by: Adam Jackson <ajax@redhat.com>
GLX_ARB_create_context explicitly allows this for GL 3.0+ contexts, the
context is made current but not bound to a default framebuffer.
Signed-off-by: Adam Jackson <ajax@redhat.com>
There is a theoretical problem of wrapping if an application frequently
loads and unloads an API library which registers its entrypoints with
GLdispatch. Proactively prevent this from being an issue by widening
dispatchStubListGeneration, and the corresponding stubGeneration
argument in the __GLdispatchPatchCallbacks API in GLdispatchABI.h, to
64-bit.
This should help make the GLVendor X configuration option slightly
easier to use, and also resolve issues where falling back to the driver
name doesn't quite work because the name is differently-cased (but
otherwise the same).
This callback notifies vendors when they no longer "own" patched
top-level libglvnd entrypoints. This allows vendors to safely
take advantage of optimizations which may modify entrypoint code
outside of the finalizePatch() callback.
Mappings defined in the parent should remain valid in the child process,
so don't clear out mappings after a fork since they may be needed for
GLX calls made in the child.
Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
This commit adds a new vendor callback, notifyError(), for notifying a
vendor library when an X error should be generated. This allows the
vendor to perform any needed error recovery and to generate the error.
In MakeContextCurrentInternal(), check for:
(context && (draw == None || read == None)) ||
(!context && (draw != None || read != None))
and call notifyError() on an appropriate vendor to generate BadMatch
before returning False.
Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Instead of using separate functions to add and remove functions from the
global hash table of current contexts, use a single function which
handles:
- adding the new context and removing the old context from the global
hash table
- initializing the tsdContextKey (if called for the first time) and
updating the tsdContextKey for this thread to contain the new context
This function does _not_ handle removing a screen <-> context mapping if
the old context will be destroyed after it loses current; instead, it
simply returns a flag, needsUnmap, which is expected to be handled by
the caller.
Also, update __glXAPITeardown() to clean up screen <-> context mappings
as needed while entries are being removed from the current context hash.
Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
- Define a function __glXThreadInitialize() which gets called when
entering any GLX entrypoint, or when __glXGetDynDispatch() is called
by a vendor-provided GLX extension entrypoint. This function detects
if a fork occurred since the last entrypoint was called, and performs
fork recovery if needed.
- Implement __glXFini() so that libGLX cleans up allocated resources
when it is unloaded.
These paths make heavy use of the LKDHASH_TEARDOWN() macro that was
implemented in a previous commit.
Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
- Don't clear the current TSD entry when UntrackCurrentContext() is
called. The TSD entry already contains the correct current context when
it is set by TrackCurrentContext() prior to the call to
UntrackCurrentContext().
- In the comment above UntrackCurrentContext(), delete an obsolete TODO.
- If make current fails, re-track the old context before returning.
Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Without this, the current context accounting in GLdispatch can get
confused if a thread is destroyed while a context is still current
to that thread.
Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
__glDispatchFini() is called by a GLdispatch client to clean up
GLdispatch-internal state when the client is done using GLdispatch
functionality.
__glDispatchReset() is called by a GLdispatch client to determine
whether fork recovery is needed, and handle the fork if necessary.
Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Theoretically multiple clients (libGLX and a future libEGL) may call
into __glDispatchInit() to set up dispatching, and we will want to
refcount GLdispatch to determine when dispatch teardown should occur.
So replace the global boolean 'initialized' with a counter
'clientRefcount' which tracks the number of clients using GLdispatch.
Signed-off-by: Brian Nguyen <brnguyen@nvidia.com>
Modify __glDispatchMakeCurrent() to take a pointer to the patch
callbacks for the vendor library whose context is about to be current.
Implement GLdispatch.c:PatchEntrypoints() and helpers. This contains
the logic for determining whether it is safe to patch entrypoints, and
using the provided vendor callbacks to actually do the entrypoint
patching. Call this from __glDispatchMakeCurrent() with the provided
patch callbacks.
Also implement GLdispatch.c:CurrentEntrypointsSafeToUse(), which
determines based on the current vendor ID whether the current top-level
code is safe to use with that vendor. If this check fails, the make
current operation fails.
Allow users to disable entrypoint rewriting functionality by setting the
environment variable __GLVND_DISALLOW_PATCHING=1.
When losing current, also attempt to restore the default libglvnd
entrypoints so other vendors can potentially use them.
This defines several callbacks to be used by vendor libraries for
rewriting top-level entrypoints defined in libglvnd:
- initiatePatch(): libglvnd calls into this function at make current
time to determine whether entrypoint patching is possible with the
given stub type and code size. The vendor library will notify
libglvnd whether offsets are needed based on a generation number.
- getOffsetHook(): libglvnd calls into the vendor library with this hook
for each loaded interface library so the vendor can lookup the stub
locations for rewriting.
- finalizePatch(): libglvnd calls into this function after the vendor
library has updated its stub locations to complete the patch.
This allows vendor libraries to potentially overwrite the static
entrypoints of wrapper libraries (such as libGL and libOpenGL) at make
current time, in addition to the main GLdispatch entrypoints.