ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

glapi.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.1
00004  *
00005  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 
00026 /*
00027  * This file manages the OpenGL API dispatch layer.
00028  * The dispatch table (struct _glapi_table) is basically just a list
00029  * of function pointers.
00030  * There are functions to set/get the current dispatch table for the
00031  * current thread and to manage registration/dispatch of dynamically
00032  * added extension functions.
00033  *
00034  * It's intended that this file and the other glapi*.[ch] files are
00035  * flexible enough to be reused in several places:  XFree86, DRI-
00036  * based libGL.so, and perhaps the SGI SI.
00037  *
00038  * NOTE: There are no dependencies on Mesa in this code.
00039  *
00040  * Versions (API changes):
00041  *   2000/02/23  - original version for Mesa 3.3 and XFree86 4.0
00042  *   2001/01/16  - added dispatch override feature for Mesa 3.5
00043  *   2002/06/28  - added _glapi_set_warning_func(), Mesa 4.1.
00044  *   2002/10/01  - _glapi_get_proc_address() will now generate new entrypoints
00045  *                 itself (using offset ~0).  _glapi_add_entrypoint() can be
00046  *                 called afterward and it'll fill in the correct dispatch
00047  *                 offset.  This allows DRI libGL to avoid probing for DRI
00048  *                 drivers!  No changes to the public glapi interface.
00049  */
00050 
00051 
00052 
00053 #ifdef HAVE_DIX_CONFIG_H
00054 
00055 #include <dix-config.h>
00056 #define PUBLIC
00057 
00058 #else
00059 
00060 #include "main/glheader.h"
00061 
00062 #endif
00063 
00064 #include <stdlib.h>
00065 #include <string.h>
00066 #ifdef DEBUG
00067 #include <assert.h>
00068 #endif
00069 
00070 #include "glapi.h"
00071 #include "glapioffsets.h"
00072 #include "glapitable.h"
00073 
00074 
00075 /***** BEGIN NO-OP DISPATCH *****/
00076 
00077 static GLboolean WarnFlag = GL_FALSE;
00078 static _glapi_warning_func warning_func;
00079 
00080 /*
00081  * Enable/disable printing of warning messages.
00082  */
00083 PUBLIC void
00084 _glapi_noop_enable_warnings(GLboolean enable)
00085 {
00086    WarnFlag = enable;
00087 }
00088 
00089 /*
00090  * Register a callback function for reporting errors.
00091  */
00092 PUBLIC void
00093 _glapi_set_warning_func( _glapi_warning_func func )
00094 {
00095    warning_func = func;
00096 }
00097 
00098 static GLboolean
00099 warn(void)
00100 {
00101    if ((WarnFlag || getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG"))
00102        && warning_func) {
00103       return GL_TRUE;
00104    }
00105    else {
00106       return GL_FALSE;
00107    }
00108 }
00109 
00110 
00111 #define KEYWORD1 static
00112 #define KEYWORD1_ALT static
00113 #define KEYWORD2 GLAPIENTRY
00114 #define NAME(func)  NoOp##func
00115 
00116 #define F NULL
00117 
00118 #define DISPATCH(func, args, msg)                         \
00119    if (warn()) {                                  \
00120       warning_func(NULL, "GL User Error: called without context: %s", #func); \
00121    }
00122 
00123 #define RETURN_DISPATCH(func, args, msg)                      \
00124    if (warn()) {                                  \
00125       warning_func(NULL, "GL User Error: called without context: %s", #func); \
00126    }                                          \
00127    return 0
00128 
00129 #define DISPATCH_TABLE_NAME __glapi_noop_table
00130 #define UNUSED_TABLE_NAME __unused_noop_functions
00131 
00132 #define TABLE_ENTRY(name) (_glapi_proc) NoOp##name
00133 
00134 static GLint NoOpUnused(void)
00135 {
00136    if (warn()) {
00137       warning_func(NULL, "GL User Error: calling extension function without a current context\n");
00138    }
00139    return 0;
00140 }
00141 
00142 #include "glapitemp.h"
00143 
00144 /***** END NO-OP DISPATCH *****/
00145 
00146 
00147 
00179 #if defined(GLX_USE_TLS)
00180 
00181 PUBLIC __thread struct _glapi_table * _glapi_tls_Dispatch
00182     __attribute__((tls_model("initial-exec")))
00183     = (struct _glapi_table *) __glapi_noop_table;
00184 
00185 PUBLIC __thread void * _glapi_tls_Context
00186     __attribute__((tls_model("initial-exec")));
00187 
00188 PUBLIC const struct _glapi_table *_glapi_Dispatch = NULL;
00189 PUBLIC const void *_glapi_Context = NULL;
00190 
00191 #else
00192 
00193 #if defined(THREADS)
00194 
00195 static GLboolean ThreadSafe = GL_FALSE;  
00196 _glthread_TSD _gl_DispatchTSD;           
00197 static _glthread_TSD ContextTSD;         
00199 #if defined(WIN32_THREADS)
00200 void FreeTSD(_glthread_TSD *p);
00201 void FreeAllTSD(void)
00202 {
00203    FreeTSD(&_gl_DispatchTSD);
00204    FreeTSD(&ContextTSD);
00205 }
00206 #endif /* defined(WIN32_THREADS) */
00207 
00208 #endif /* defined(THREADS) */
00209 
00210 PUBLIC struct _glapi_table *_glapi_Dispatch = 
00211   (struct _glapi_table *) __glapi_noop_table;
00212 PUBLIC void *_glapi_Context = NULL;
00213 
00214 #endif /* defined(GLX_USE_TLS) */
00215 
00224 void
00225 _glapi_check_multithread(void)
00226 {
00227 #if defined(THREADS) && !defined(GLX_USE_TLS)
00228    if (!ThreadSafe) {
00229       static unsigned long knownID;
00230       static GLboolean firstCall = GL_TRUE;
00231       if (firstCall) {
00232          knownID = _glthread_GetID();
00233          firstCall = GL_FALSE;
00234       }
00235       else if (knownID != _glthread_GetID()) {
00236          ThreadSafe = GL_TRUE;
00237          _glapi_set_dispatch(NULL);
00238          _glapi_set_context(NULL);
00239       }
00240    }
00241    else if (!_glapi_get_dispatch()) {
00242       /* make sure that this thread's dispatch pointer isn't null */
00243       _glapi_set_dispatch(NULL);
00244    }
00245 #endif
00246 }
00247 
00248 
00249 
00255 PUBLIC void
00256 _glapi_set_context(void *context)
00257 {
00258    (void) __unused_noop_functions; /* silence a warning */
00259 #if defined(GLX_USE_TLS)
00260    _glapi_tls_Context = context;
00261 #elif defined(THREADS)
00262    _glthread_SetTSD(&ContextTSD, context);
00263    _glapi_Context = (ThreadSafe) ? NULL : context;
00264 #else
00265    _glapi_Context = context;
00266 #endif
00267 }
00268 
00269 
00270 
00276 PUBLIC void *
00277 _glapi_get_context(void)
00278 {
00279 #if defined(GLX_USE_TLS)
00280    return _glapi_tls_Context;
00281 #elif defined(THREADS)
00282    if (ThreadSafe) {
00283       return _glthread_GetTSD(&ContextTSD);
00284    }
00285    else {
00286       return _glapi_Context;
00287    }
00288 #else
00289    return _glapi_Context;
00290 #endif
00291 }
00292 
00293 #ifdef USE_X86_ASM
00294 
00295 #if defined( GLX_USE_TLS )
00296 extern       GLubyte gl_dispatch_functions_start[];
00297 extern       GLubyte gl_dispatch_functions_end[];
00298 #else
00299 extern const GLubyte gl_dispatch_functions_start[];
00300 #endif
00301 
00302 #endif /* USE_X86_ASM */
00303 
00304 
00305 #if defined(USE_X64_64_ASM) && defined(GLX_USE_TLS)
00306 # define DISPATCH_FUNCTION_SIZE  16
00307 #elif defined(USE_X86_ASM)
00308 # if defined(THREADS) && !defined(GLX_USE_TLS)
00309 #  define DISPATCH_FUNCTION_SIZE  32
00310 # else
00311 #  define DISPATCH_FUNCTION_SIZE  16
00312 # endif
00313 #endif
00314 
00315 #if !defined(DISPATCH_FUNCTION_SIZE) && !defined(XFree86Server) && !defined(XGLServer)
00316 # define NEED_FUNCTION_POINTER
00317 #endif
00318 
00319 #if defined(PTHREADS) || defined(GLX_USE_TLS)
00320 
00323 static void
00324 init_glapi_relocs( void )
00325 {
00326 #if defined(USE_X86_ASM) && defined(GLX_USE_TLS) && !defined(GLX_X86_READONLY_TEXT)
00327     extern unsigned long _x86_get_dispatch(void);
00328     char run_time_patch[] = {
00329        0x65, 0xa1, 0, 0, 0, 0 /* movl %gs:0,%eax */
00330     };
00331     GLuint *offset = (GLuint *) &run_time_patch[2]; /* 32-bits for x86/32 */
00332     const GLubyte * const get_disp = (const GLubyte *) run_time_patch;
00333     GLubyte * curr_func = (GLubyte *) gl_dispatch_functions_start;
00334 
00335     *offset = _x86_get_dispatch();
00336     while ( curr_func != (GLubyte *) gl_dispatch_functions_end ) {
00337     (void) memcpy( curr_func, get_disp, sizeof(run_time_patch));
00338     curr_func += DISPATCH_FUNCTION_SIZE;
00339     }
00340 #endif
00341 }
00342 #endif /* defined(PTHREADS) || defined(GLX_USE_TLS) */
00343 
00344 
00350 PUBLIC void
00351 _glapi_set_dispatch(struct _glapi_table *dispatch)
00352 {
00353 #if defined(PTHREADS) || defined(GLX_USE_TLS)
00354    static pthread_once_t once_control = PTHREAD_ONCE_INIT;
00355    pthread_once( & once_control, init_glapi_relocs );
00356 #endif
00357 
00358    if (!dispatch) {
00359       /* use the no-op functions */
00360       dispatch = (struct _glapi_table *) __glapi_noop_table;
00361    }
00362 #ifdef DEBUG
00363    else {
00364       _glapi_check_table(dispatch);
00365    }
00366 #endif
00367 
00368 #if defined(GLX_USE_TLS)
00369    _glapi_tls_Dispatch = dispatch;
00370 #elif defined(THREADS)
00371    _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch);
00372    _glapi_Dispatch = (ThreadSafe) ? NULL : dispatch;
00373 #else /*THREADS*/
00374    _glapi_Dispatch = dispatch;
00375 #endif /*THREADS*/
00376 }
00377 
00378 
00379 
00383 PUBLIC struct _glapi_table *
00384 _glapi_get_dispatch(void)
00385 {
00386    struct _glapi_table * api;
00387 #if defined(GLX_USE_TLS)
00388    api = _glapi_tls_Dispatch;
00389 #elif defined(THREADS)
00390    api = (ThreadSafe)
00391      ? (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD)
00392      : _glapi_Dispatch;
00393 #else
00394    api = _glapi_Dispatch;
00395 #endif
00396    return api;
00397 }
00398 
00399 
00400 
00401 
00402 /*
00403  * The dispatch table size (number of entries) is the size of the
00404  * _glapi_table struct plus the number of dynamic entries we can add.
00405  * The extra slots can be filled in by DRI drivers that register new extension
00406  * functions.
00407  */
00408 #define DISPATCH_TABLE_SIZE (sizeof(struct _glapi_table) / sizeof(void *) + MAX_EXTENSION_FUNCS)
00409 
00410 
00415 PUBLIC GLuint
00416 _glapi_get_dispatch_table_size(void)
00417 {
00418    return DISPATCH_TABLE_SIZE;
00419 }
00420 
00421 
00426 void
00427 _glapi_check_table(const struct _glapi_table *table)
00428 {
00429 #ifdef EXTRA_DEBUG
00430    const GLuint entries = _glapi_get_dispatch_table_size();
00431    const void **tab = (const void **) table;
00432    GLuint i;
00433    for (i = 1; i < entries; i++) {
00434       assert(tab[i]);
00435    }
00436 
00437    /* Do some spot checks to be sure that the dispatch table
00438     * slots are assigned correctly.
00439     */
00440    {
00441       GLuint BeginOffset = _glapi_get_proc_offset("glBegin");
00442       char *BeginFunc = (char*) &table->Begin;
00443       GLuint offset = (BeginFunc - (char *) table) / sizeof(void *);
00444       assert(BeginOffset == _gloffset_Begin);
00445       assert(BeginOffset == offset);
00446    }
00447    {
00448       GLuint viewportOffset = _glapi_get_proc_offset("glViewport");
00449       char *viewportFunc = (char*) &table->Viewport;
00450       GLuint offset = (viewportFunc - (char *) table) / sizeof(void *);
00451       assert(viewportOffset == _gloffset_Viewport);
00452       assert(viewportOffset == offset);
00453    }
00454    {
00455       GLuint VertexPointerOffset = _glapi_get_proc_offset("glVertexPointer");
00456       char *VertexPointerFunc = (char*) &table->VertexPointer;
00457       GLuint offset = (VertexPointerFunc - (char *) table) / sizeof(void *);
00458       assert(VertexPointerOffset == _gloffset_VertexPointer);
00459       assert(VertexPointerOffset == offset);
00460    }
00461    {
00462       GLuint ResetMinMaxOffset = _glapi_get_proc_offset("glResetMinmax");
00463       char *ResetMinMaxFunc = (char*) &table->ResetMinmax;
00464       GLuint offset = (ResetMinMaxFunc - (char *) table) / sizeof(void *);
00465       assert(ResetMinMaxOffset == _gloffset_ResetMinmax);
00466       assert(ResetMinMaxOffset == offset);
00467    }
00468    {
00469       GLuint blendColorOffset = _glapi_get_proc_offset("glBlendColor");
00470       char *blendColorFunc = (char*) &table->BlendColor;
00471       GLuint offset = (blendColorFunc - (char *) table) / sizeof(void *);
00472       assert(blendColorOffset == _gloffset_BlendColor);
00473       assert(blendColorOffset == offset);
00474    }
00475    {
00476       GLuint secondaryColor3fOffset = _glapi_get_proc_offset("glSecondaryColor3fEXT");
00477       char *secondaryColor3fFunc = (char*) &table->SecondaryColor3fEXT;
00478       GLuint offset = (secondaryColor3fFunc - (char *) table) / sizeof(void *);
00479       assert(secondaryColor3fOffset == _gloffset_SecondaryColor3fEXT);
00480       assert(secondaryColor3fOffset == offset);
00481    }
00482    {
00483       GLuint pointParameterivOffset = _glapi_get_proc_offset("glPointParameterivNV");
00484       char *pointParameterivFunc = (char*) &table->PointParameterivNV;
00485       GLuint offset = (pointParameterivFunc - (char *) table) / sizeof(void *);
00486       assert(pointParameterivOffset == _gloffset_PointParameterivNV);
00487       assert(pointParameterivOffset == offset);
00488    }
00489    {
00490       GLuint setFenceOffset = _glapi_get_proc_offset("glSetFenceNV");
00491       char *setFenceFunc = (char*) &table->SetFenceNV;
00492       GLuint offset = (setFenceFunc - (char *) table) / sizeof(void *);
00493       assert(setFenceOffset == _gloffset_SetFenceNV);
00494       assert(setFenceOffset == offset);
00495    }
00496 #else
00497    (void) table;
00498 #endif
00499 }

Generated on Sat May 26 2012 04:18:45 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.