diff options
Diffstat (limited to 'GLdispatch.mdwn')
-rw-r--r-- | GLdispatch.mdwn | 62 |
1 files changed, 25 insertions, 37 deletions
diff --git a/GLdispatch.mdwn b/GLdispatch.mdwn index 77e146f..90cb6e1 100644 --- a/GLdispatch.mdwn +++ b/GLdispatch.mdwn @@ -28,37 +28,30 @@ In terms of API dispatch, Mesa currently supports four different threading model In single threaded mode as single, global variable is used to store the dispatch table pointer. This results in the simplest possible dispatch stubs as well. - -[[!format txt """ -void glVertex3fv( const GLfloat * v ) -{ - (*_glapi_Dispatch->Vertex3fv)( v ); -} -"""]] + void glVertex3fv( const GLfloat * v ) + { + (*_glapi_Dispatch->Vertex3fv)( v ); + } ## Non-TLS threading models Mesa implements a generic wrapper function, called `_glapi_get_dispatch`, that is used to get the per-thread dispatch pointer. The naive implementation of a dispatch stub is shown below. + void glVertex3fv( const GLfloat * v ) + { + const struct _glapi_table * d = _glapi_get_dispatch(); + (*d->Vertex3fv)( v ); + } -[[!format txt """ -void glVertex3fv( const GLfloat * v ) -{ - const struct _glapi_table * d = _glapi_get_dispatch(); - (*d->Vertex3fv)( v ); -} -"""]] This implementation is very simple, but it results in poor performance in the single-threaded case. Single-threaded applications are by far more common that multi-threaded, so it make sense to do some optimization for that case. The old variable `_glapi_Dispatch` continues to exist, but its semantic is slightly modified. When the implementation of `glXMakeCurrent` detects that a new thread is setting a current context, `_glapi_Dispatch` is set to `NULL` and the true dispatch table pointer is stored in some piece of thread local storage. This allows the dispatch function to use the state of `_glapi_Dispatch` to determine whether or not the application is single- or multi-threaded. + void glVertex3fv( const GLfloat * v ) + { + const struct _glapi_table * d = (_glapi_Dispatch != NULL) + ? _glapi_Dispatch : _glapi_get_dispatch(); + (*d->Vertex3fv)( v ); + } -[[!format txt """ -void glVertex3fv( const GLfloat * v ) -{ - const struct _glapi_table * d = (_glapi_Dispatch != NULL) - ? _glapi_Dispatch : _glapi_get_dispatch(); - (*d->Vertex3fv)( v ); -} -"""]] The result is vastly improved single-threaded performance with a small penalty to multi-threaded performance. @@ -66,15 +59,12 @@ The result is vastly improved single-threaded performance with a small penalty t Pthreads is by far the most common threading model used by Mesa. Some of the overhead of `_glapi_get_dispatch` can be avoided by directly calling `pthread_getspecific` from the dispatch stub. This helps the multi-threaded case slightly but has no impact on the single-threaded case. - -[[!format txt """ -void glVertex3fv( const GLfloat * v ) -{ - const struct _glapi_table * d = (_glapi_Dispatch != NULL) - ? _glapi_Dispatch : pthread_getspecific( & _gl_DispatchTSD ); - (*d->Vertex3fv)( v ); -} -"""]] + void glVertex3fv( const GLfloat * v ) + { + const struct _glapi_table * d = (_glapi_Dispatch != NULL) + ? _glapi_Dispatch : pthread_getspecific( & _gl_DispatchTSD ); + (*d->Vertex3fv)( v ); + } ## TLS @@ -83,12 +73,10 @@ Thread-local storage on Linux provides compiler supported, per-thread variables. The name of the dispatch table pointer is changed in the TLS case to prevent conflicts between a TLS libGL and a non-TLS DRI driver. -[[!format txt """ -void glVertex3fv( const GLfloat * v ) -{ - (*_glapi_tls_Dispatch->Vertex3fv)( v ); -} -"""]] + void glVertex3fv( const GLfloat * v ) + { + (*_glapi_tls_Dispatch->Vertex3fv)( v ); + } # Implementation of static dispatch functions in Mesa |