summaryrefslogtreecommitdiffstats
path: root/src/mesa/glapi/glapi.c
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2005-08-10 23:54:15 +0000
committerIan Romanick <[email protected]>2005-08-10 23:54:15 +0000
commit967b006f518849e57fef68ab71359485b1535b3a (patch)
treec18fc79ce8a3610b3ab8151c1ef02827186c9afb /src/mesa/glapi/glapi.c
parent1b8d0f149e0afac859c4c1e1e47772bb19da0187 (diff)
Remove _glapi_check_multithread from the interface exported by the loader to
the driver. The loader now takes care of this for the driver. Remove _glapi_DispatchTSD and give _glapi_Dispatch its semantic (i.e., having a NULL value means that the application is multithreaded and _glapi_get_dispatch must be called). Gut all of the dispatch override code. This removes _glapi_RealDispatch, _glapi_tls_RealDispatch, _glapi_begin_dispatch_override, _glapi_end_dispatch_override, and _glapi_get_override_dispatch. Remove _glapi_get_proc_address, _glapi_get_proc_name, _glapi_get_version, and _glapi_check_table from the loader / driver interface. Reviewed by: Brian Paul
Diffstat (limited to 'src/mesa/glapi/glapi.c')
-rw-r--r--src/mesa/glapi/glapi.c319
1 files changed, 57 insertions, 262 deletions
diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c
index 47a1f164582..c11760cf126 100644
--- a/src/mesa/glapi/glapi.c
+++ b/src/mesa/glapi/glapi.c
@@ -133,122 +133,65 @@ static GLint NoOpUnused(void)
-/***** BEGIN THREAD-SAFE DISPATCH *****/
-
-#if defined(THREADS)
-
+/**
+ * \name Current dispatch and current context control variables
+ *
+ * Depending on whether or not multithreading is support, and the type of
+ * support available, several variables are used to store the current context
+ * pointer and the current dispatch table pointer. In the non-threaded case,
+ * the variables \c _glapi_Dispatch and \c _glapi_Context are used for this
+ * purpose.
+ *
+ * In the "normal" threaded case, the variables \c _glapi_Dispatch and
+ * \c _glapi_Context will be \c NULL if an application is detected as being
+ * multithreaded. Single-threaded applications will use \c _glapi_Dispatch
+ * and \c _glapi_Context just like the case without any threading support.
+ * When \c _glapi_Dispatch and \c _glapi_Context are \c NULL, the thread state
+ * data \c _gl_DispatchTSD and \c ContextTSD are used. Drivers and the
+ * static dispatch functions access these variables via \c _glapi_get_dispatch
+ * and \c _glapi_get_context.
+ *
+ * There is a race condition in setting \c _glapi_Dispatch to \c NULL. It is
+ * possible for the original thread to be setting it at the same instant a new
+ * thread, perhaps running on a different processor, is clearing it. Because
+ * of that, \c ThreadSafe, which can only ever be changed to \c GL_TRUE, is
+ * used to determine whether or not the application is multithreaded.
+ *
+ * In the TLS case, the variables \c _glapi_Dispatch and \c _glapi_Context are
+ * hardcoded to \c NULL. Instead the TLS variables \c _glapi_tls_Dispatch and
+ * \c _glapi_tls_Context are used. Having \c _glapi_Dispatch and
+ * \c _glapi_Context be hardcoded to \c NULL maintains binary compatability
+ * between TLS enabled loaders and non-TLS DRI drivers.
+ */
+/*@{*/
#if defined(GLX_USE_TLS)
-__thread struct _glapi_table * _glapi_tls_Dispatch
- __attribute__((tls_model("initial-exec")))
- = (struct _glapi_table *) __glapi_noop_table;
-
-static __thread struct _glapi_table * _glapi_tls_RealDispatch
+PUBLIC __thread struct _glapi_table * _glapi_tls_Dispatch
__attribute__((tls_model("initial-exec")))
= (struct _glapi_table *) __glapi_noop_table;
-__thread void * _glapi_tls_Context
+PUBLIC __thread void * _glapi_tls_Context
__attribute__((tls_model("initial-exec")));
-/**
- * Legacy per-thread dispatch pointer. This is only needed to support
- * non-TLS DRI drivers.
- */
-
-_glthread_TSD _gl_DispatchTSD;
+PUBLIC const struct _glapi_table *_glapi_Dispatch = NULL;
+PUBLIC const void *_glapi_Context = NULL;
#else
-/**
- * \name Multi-threaded control support variables
- *
- * If thread-safety is supported, there are two potential mechanisms that can
- * be used. The old-style mechanism would set \c _glapi_Dispatch to a special
- * thread-safe dispatch table. These dispatch routines would call
- * \c _glapi_get_dispatch to get the actual dispatch pointer. In this
- * setup \c _glapi_Dispatch could never be \c NULL. This dual layered
- * dispatch setup performed great for single-threaded apps, but didn't
- * perform well for multithreaded apps.
- *
- * In the new mechansim, there are two variables. The first is
- * \c _glapi_DispatchTSD. In the single-threaded case, this variable points
- * to the dispatch table. In the multi-threaded case, this variable is
- * \c NULL, and thread-specific variable \c _gl_DispatchTSD points to the
- * actual dispatch table. \c _glapi_DispatchTSD is used to signal to the
- * static dispatch functions to call \c _glapi_get_dispatch to get the real
- * dispatch table.
- *
- * There is a race condition in setting \c _glapi_DispatchTSD to \c NULL.
- * It is possible for the original thread to be setting it at the same instant
- * a new thread, perhaps running on a different processor, is clearing it.
- * Because of that, \c ThreadSafe, which can only ever be changed to
- * \c GL_TRUE, is used to determine whether or not the application is
- * multithreaded.
- */
-/*@{*/
+#if defined(THREADS)
+
static GLboolean ThreadSafe = GL_FALSE; /**< In thread-safe mode? */
_glthread_TSD _gl_DispatchTSD; /**< Per-thread dispatch pointer */
-static _glthread_TSD RealDispatchTSD; /**< only when using override */
static _glthread_TSD ContextTSD; /**< Per-thread context pointer */
-/*@}*/
-
-#endif /* defined(GLX_USE_TLS) */
-
-#define DISPATCH_TABLE_NAME __glapi_threadsafe_table
-#define UNUSED_TABLE_NAME __unused_threadsafe_functions
-
-#define TABLE_ENTRY(name) (_glapi_proc) gl##name
-
-static GLint glUnused(void)
-{
- return 0;
-}
-#include "glapitemp.h"
-
-#endif
-
-/***** END THREAD-SAFE DISPATCH *****/
-
-
-#if defined(GLX_USE_TLS)
-
-/**
- * \name Old dispatch pointers
- *
- * Very old DRI based drivers assume that \c _glapi_Dispatch will never be
- * \c NULL. Becuase of that, special "thread-safe" dispatch functions are
- * needed here. Slightly more recent drivers detect the multi-threaded case
- * by \c _glapi_DispatchTSD being \c NULL.
- *
- * \deprecated
- *
- * \warning
- * \c _glapi_RealDispatch does not exist in TLS builds. I don't think it was
- * ever used outside libGL.so, so this should be safe.
- */
-/*@{*/
-PUBLIC const struct _glapi_table *_glapi_Dispatch = (struct _glapi_table *) __glapi_threadsafe_table;
-PUBLIC const struct _glapi_table *_glapi_DispatchTSD = NULL;
-PUBLIC const void *_glapi_Context = NULL;
-/*@}*/
+#endif /* defined(THREADS) */
-#else
-
-PUBLIC struct _glapi_table *_glapi_Dispatch = (struct _glapi_table *) __glapi_noop_table;
-#if defined( THREADS )
-PUBLIC struct _glapi_table *_glapi_DispatchTSD = (struct _glapi_table *) __glapi_noop_table;
-#endif
-PUBLIC struct _glapi_table *_glapi_RealDispatch = (struct _glapi_table *) __glapi_noop_table;
-
-/* Used when thread safety disabled */
+PUBLIC struct _glapi_table *_glapi_Dispatch =
+ (struct _glapi_table *) __glapi_noop_table;
PUBLIC void *_glapi_Context = NULL;
#endif /* defined(GLX_USE_TLS) */
-
-
-static GLboolean DispatchOverride = GL_FALSE;
-
+/*@}*/
/**
@@ -272,7 +215,7 @@ str_dup(const char *str)
* We should call this periodically from a function such as glXMakeCurrent
* in order to test if multiple threads are being used.
*/
-PUBLIC void
+void
_glapi_check_multithread(void)
{
#if defined(THREADS) && !defined(GLX_USE_TLS)
@@ -309,7 +252,6 @@ _glapi_set_context(void *context)
#if defined(GLX_USE_TLS)
_glapi_tls_Context = context;
#elif defined(THREADS)
- (void) __unused_threadsafe_functions; /* silence a warning */
_glthread_SetTSD(&ContextTSD, context);
_glapi_Context = (ThreadSafe) ? NULL : context;
#else
@@ -367,40 +309,12 @@ _glapi_set_dispatch(struct _glapi_table *dispatch)
#endif
#if defined(GLX_USE_TLS)
- if (DispatchOverride) {
- _glapi_tls_RealDispatch = dispatch;
- }
- else {
- _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch);
- _glapi_tls_Dispatch = dispatch;
- }
+ _glapi_tls_Dispatch = dispatch;
#elif defined(THREADS)
- if (DispatchOverride) {
- _glthread_SetTSD(&RealDispatchTSD, (void *) dispatch);
- if (ThreadSafe)
- _glapi_RealDispatch = (struct _glapi_table*) __glapi_threadsafe_table;
- else
- _glapi_RealDispatch = dispatch;
- }
- else {
- /* normal operation */
- _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch);
- if (ThreadSafe) {
- _glapi_Dispatch = (struct _glapi_table *) __glapi_threadsafe_table;
- _glapi_DispatchTSD = NULL;
- }
- else {
- _glapi_Dispatch = dispatch;
- _glapi_DispatchTSD = dispatch;
- }
- }
+ _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch);
+ _glapi_Dispatch = (ThreadSafe) ? NULL : dispatch;
#else /*THREADS*/
- if (DispatchOverride) {
- _glapi_RealDispatch = dispatch;
- }
- else {
- _glapi_Dispatch = dispatch;
- }
+ _glapi_Dispatch = dispatch;
#endif /*THREADS*/
}
@@ -412,128 +326,20 @@ _glapi_set_dispatch(struct _glapi_table *dispatch)
PUBLIC struct _glapi_table *
_glapi_get_dispatch(void)
{
-#if defined(GLX_USE_TLS)
- struct _glapi_table * api = (DispatchOverride)
- ? _glapi_tls_RealDispatch : _glapi_tls_Dispatch;
-
- assert( api != NULL );
- return api;
-#elif defined(THREADS)
- if (ThreadSafe) {
- if (DispatchOverride) {
- return (struct _glapi_table *) _glthread_GetTSD(&RealDispatchTSD);
- }
- else {
- return (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD);
- }
- }
- else {
- if (DispatchOverride) {
- assert(_glapi_RealDispatch);
- return _glapi_RealDispatch;
- }
- else {
- assert(_glapi_DispatchTSD);
- return _glapi_DispatchTSD;
- }
- }
-#else
- return _glapi_Dispatch;
-#endif
-}
-
-
-/*
- * Notes on dispatch overrride:
- *
- * Dispatch override allows an external agent to hook into the GL dispatch
- * mechanism before execution goes into the core rendering library. For
- * example, a trace mechanism would insert itself as an overrider, print
- * logging info for each GL function, then dispatch to the real GL function.
- *
- * libGLS (GL Stream library) is another agent that might use override.
- *
- * We don't allow more than one layer of overriding at this time.
- * In the future we may allow nested/layered override. In that case
- * _glapi_begin_dispatch_override() will return an override layer,
- * _glapi_end_dispatch_override(layer) will remove an override layer
- * and _glapi_get_override_dispatch(layer) will return the dispatch
- * table for a given override layer. layer = 0 will be the "real"
- * dispatch table.
- */
-
-/*
- * Return: dispatch override layer number.
- */
-PUBLIC int
-_glapi_begin_dispatch_override(struct _glapi_table *override)
-{
- struct _glapi_table *real = _glapi_get_dispatch();
-
- assert(!DispatchOverride); /* can't nest at this time */
- DispatchOverride = GL_TRUE;
-
- _glapi_set_dispatch(real);
+ struct _glapi_table * api;
#if defined(GLX_USE_TLS)
- _glthread_SetTSD(&_gl_DispatchTSD, (void *) override);
- _glapi_tls_Dispatch = override;
+ api = _glapi_tls_Dispatch;
#elif defined(THREADS)
- _glthread_SetTSD(&_gl_DispatchTSD, (void *) override);
- if ( ThreadSafe ) {
- _glapi_Dispatch = (struct _glapi_table *) __glapi_threadsafe_table;
- _glapi_DispatchTSD = NULL;
- }
- else {
- _glapi_Dispatch = override;
- _glapi_DispatchTSD = override;
- }
+ api = (ThreadSafe)
+ ? (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD)
+ : _glapi_Dispatch;
#else
- _glapi_Dispatch = override;
+ api = _glapi_Dispatch;
#endif
- return 1;
-}
-
-PUBLIC void
-_glapi_end_dispatch_override(int layer)
-{
- struct _glapi_table *real = _glapi_get_dispatch();
- (void) layer;
- DispatchOverride = GL_FALSE;
- _glapi_set_dispatch(real);
- /* the rest of this isn't needed, just play it safe */
-#if defined(GLX_USE_TLS)
- _glapi_tls_RealDispatch = NULL;
-#else
-# if defined(THREADS)
- _glthread_SetTSD(&RealDispatchTSD, NULL);
-# endif
- _glapi_RealDispatch = NULL;
-#endif
-}
-
-
-PUBLIC struct _glapi_table *
-_glapi_get_override_dispatch(int layer)
-{
- if (layer == 0) {
- return _glapi_get_dispatch();
- }
- else {
- if (DispatchOverride) {
-#if defined(GLX_USE_TLS)
- return (struct _glapi_table *) _glapi_tls_Dispatch;
-#elif defined(THREADS)
- return (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD);
-#else
- return _glapi_Dispatch;
-#endif
- }
- else {
- return NULL;
- }
- }
+ assert( api != NULL );
+ return api;
}
@@ -1063,7 +869,7 @@ _glapi_get_proc_offset(const char *funcName)
* in the name of static functions, try generating a new API entrypoint on
* the fly with assembly language.
*/
-PUBLIC _glapi_proc
+_glapi_proc
_glapi_get_proc_address(const char *funcName)
{
struct _glapi_function * entry;
@@ -1101,7 +907,7 @@ _glapi_get_proc_address(const char *funcName)
* Return the name of the function at the given dispatch offset.
* This is only intended for debugging.
*/
-PUBLIC const char *
+const char *
_glapi_get_proc_name(GLuint offset)
{
GLuint i;
@@ -1137,21 +943,10 @@ _glapi_get_dispatch_table_size(void)
/**
- * Get API dispatcher version string.
- */
-PUBLIC const char *
-_glapi_get_version(void)
-{
- return "20021001"; /* YYYYMMDD */
-}
-
-
-
-/**
* Make sure there are no NULL pointers in the given dispatch table.
* Intended for debugging purposes.
*/
-PUBLIC void
+void
_glapi_check_table(const struct _glapi_table *table)
{
#ifdef DEBUG