diff options
Diffstat (limited to 'xc/extras/Mesa/src/glapi.c')
-rw-r--r-- | xc/extras/Mesa/src/glapi.c | 164 |
1 files changed, 122 insertions, 42 deletions
diff --git a/xc/extras/Mesa/src/glapi.c b/xc/extras/Mesa/src/glapi.c index 0fa74e01e..04380753d 100644 --- a/xc/extras/Mesa/src/glapi.c +++ b/xc/extras/Mesa/src/glapi.c @@ -1,4 +1,4 @@ -/* $Id: glapi.c,v 1.2 2000/01/30 00:27:02 brianp Exp $ */ +/* $Id: glapi.c,v 1.3 2000/02/12 23:09:22 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -42,16 +42,12 @@ -#include <assert.h> -#include <stdlib.h> /* to get NULL */ -#include <string.h> +#include "glheader.h" #include "glapi.h" #include "glapinoop.h" #include "glapioffsets.h" #include "glapitable.h" -#if defined(THREADS) #include "glthread.h" -#endif /* This is used when thread safety is disabled */ @@ -68,19 +64,8 @@ static GLboolean ThreadSafe = GL_FALSE; static _glthread_TSD DispatchTSD; -static void dispatch_thread_init() -{ - _glthread_InitTSD(&DispatchTSD); -} - - static _glthread_TSD ContextTSD; -static void context_thread_init() -{ - _glthread_InitTSD(&ContextTSD); -} - #endif @@ -130,7 +115,7 @@ void _glapi_set_context(void *context) { #if defined(THREADS) - _glthread_SetTSD(&ContextTSD, context, context_thread_init); + _glthread_SetTSD(&ContextTSD, context); if (ThreadSafe) _glapi_Context = NULL; else @@ -181,7 +166,7 @@ _glapi_set_dispatch(struct _glapi_table *dispatch) #endif #if defined(THREADS) - _glthread_SetTSD(&DispatchTSD, (void*) dispatch, dispatch_thread_init); + _glthread_SetTSD(&DispatchTSD, (void*) dispatch); if (ThreadSafe) _glapi_Dispatch = NULL; else @@ -285,13 +270,16 @@ get_static_proc_address(const char *funcName) */ +#define MAX_EXTENSION_FUNCS 1000 + + struct _glapi_ext_entrypoint { const char *Name; /* the extension function's name */ GLuint Offset; /* relative to start of dispatch table */ GLvoid *Address; /* address of dispatch function */ }; -static struct _glapi_ext_entrypoint ExtEntryTable[_GLAPI_EXTRA_SLOTS]; +static struct _glapi_ext_entrypoint ExtEntryTable[MAX_EXTENSION_FUNCS]; static GLuint NumExtEntryPoints = 0; @@ -299,13 +287,51 @@ static GLuint NumExtEntryPoints = 0; /* * Generate a dispatch function (entrypoint) which jumps through * the given slot number (offset) in the current dispatch table. + * We need assembly language in order to accomplish this. */ static void * -generate_entrypoint(GLuint offset) +generate_entrypoint(GLuint functionOffset) { - /* XXX need to generate some assembly code here */ - +#if defined(USE_X86_ASM) + /* + * This x86 code contributed by Josh Vanderhoof. + * + * 0: a1 10 32 54 76 movl __glapi_Dispatch,%eax + * 00 01 02 03 04 + * 5: 85 c0 testl %eax,%eax + * 05 06 + * 7: 74 06 je f <entrypoint+0xf> + * 07 08 + * 9: ff a0 10 32 54 76 jmp *0x76543210(%eax) + * 09 0a 0b 0c 0d 0e + * f: e8 fc ff ff ff call __glapi_get_dispatch + * 0f 10 11 12 13 + * 14: ff a0 10 32 54 76 jmp *0x76543210(%eax) + * 14 15 16 17 18 19 + */ + static const unsigned char temp[] = { + 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x85, 0xc0, + 0x74, 0x06, + 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0xe8, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00 + }; + unsigned char *code = malloc(sizeof(temp)); + unsigned int next_insn; + if (code) { + memcpy(code, temp, sizeof(temp)); + + *(unsigned int *)(code + 0x01) = (unsigned int)&_glapi_Dispatch; + *(unsigned int *)(code + 0x0b) = (unsigned int)functionOffset * 4; + next_insn = (unsigned int)(code + 0x14); + *(unsigned int *)(code + 0x10) = (unsigned int)_glapi_get_dispatch - next_insn; + *(unsigned int *)(code + 0x16) = (unsigned int)functionOffset * 4; + } + return code; +#else return NULL; +#endif } @@ -317,8 +343,6 @@ generate_entrypoint(GLuint offset) GLboolean _glapi_add_entrypoint(const char *funcName, GLuint offset) { - GLint index; - /* Make sure we don't try to add a new entrypoint after someone * has already called _glapi_get_dispatch_table_size()! If that's * happened the caller's information will now be out of date. @@ -326,14 +350,21 @@ _glapi_add_entrypoint(const char *funcName, GLuint offset) assert(!GetSizeCalled); /* first check if the named function is already statically present */ - index = get_static_proc_offset(funcName); + { + GLint index = get_static_proc_offset(funcName); + if (index >= 0) { + return (GLboolean) (index == offset); /* bad offset! */ + } + } - if (index >= 0) { - assert(index == offset); - return GL_TRUE; + { + /* make sure this offset/name pair is legal */ + const char *name = _glapi_get_proc_name(offset); + if (name && strcmp(name, funcName) != 0) + return GL_FALSE; /* bad name! */ } - /* else if (offset < _glapi_get_dispatch_table_size()) { */ - else { + + { /* be sure index and name match known data */ GLuint i; for (i = 0; i < NumExtEntryPoints; i++) { @@ -347,24 +378,73 @@ _glapi_add_entrypoint(const char *funcName, GLuint offset) } } } - assert(NumExtEntryPoints < _GLAPI_EXTRA_SLOTS); - ExtEntryTable[NumExtEntryPoints].Name = strdup(funcName); - ExtEntryTable[NumExtEntryPoints].Offset = offset; - ExtEntryTable[NumExtEntryPoints].Address = generate_entrypoint(offset); - NumExtEntryPoints++; - if (offset > MaxDispatchOffset) - MaxDispatchOffset = offset; + /* make sure we have space */ + if (NumExtEntryPoints >= MAX_EXTENSION_FUNCS) { + return GL_FALSE; + } + else { + void *entrypoint = generate_entrypoint(offset); + if (!entrypoint) + return GL_FALSE; + + ExtEntryTable[NumExtEntryPoints].Name = strdup(funcName); + ExtEntryTable[NumExtEntryPoints].Offset = offset; + ExtEntryTable[NumExtEntryPoints].Address = entrypoint; + NumExtEntryPoints++; + + if (offset > MaxDispatchOffset) + MaxDispatchOffset = offset; - return GL_TRUE; + return GL_TRUE; /* success */ + } } + + /* should never get here, but play it safe */ + return GL_FALSE; +} + + + +#if 0000 /* prototype code for dynamic extension slot allocation */ + +static int NextFreeOffset = 409; /*XXX*/ +#define MAX_DISPATCH_TABLE_SIZE 1000 + /* - else { - return GL_FALSE; + * Dynamically allocate a dispatch slot for an extension entrypoint + * and generate the assembly language dispatch stub. + * Return the dispatch offset for the function or -1 if no room or error. + */ +GLint +_glapi_add_entrypoint2(const char *funcName) +{ + int offset; + + /* first see if extension func is already known */ + offset = _glapi_get_proc_offset(funcName); + if (offset >= 0) + return offset; + + if (NumExtEntryPoints < MAX_EXTENSION_FUNCS + && NextFreeOffset < MAX_DISPATCH_TABLE_SIZE) { + void *entryPoint; + offset = NextFreeOffset; + entryPoint = generate_entrypoint(offset); + if (entryPoint) { + NextFreeOffset++; + ExtEntryTable[NumExtEntryPoints].Name = strdup(funcName); + ExtEntryTable[NumExtEntryPoints].Offset = offset; + ExtEntryTable[NumExtEntryPoints].Address = entryPoint; + NumExtEntryPoints++; + return offset; + } } -*/ + return -1; } +#endif + /* |