📄 glapi.c
字号:
***/#if !defined( USE_X86_ASM ) && !defined( XFree86Server ) && !defined ( XGLServer )#define NEED_FUNCTION_POINTER#endif/* The code in this file is auto-generated with Python */#include "glprocs.h"/** * Search the table of static entrypoint functions for the named function * and return the corresponding glprocs_table_t entry. */static const glprocs_table_t *find_entry( const char * n ){ GLuint i; for (i = 0; static_functions[i].Name_offset >= 0; i++) { const char *testName = gl_string_table + static_functions[i].Name_offset; if (strcmp(testName, n) == 0) { return &static_functions[i]; } } return NULL;}/** * Return dispatch table offset of the named static (built-in) function. * Return -1 if function not found. */static GLintget_static_proc_offset(const char *funcName){ const glprocs_table_t * const f = find_entry( funcName ); if (f) { return f->Offset; } return -1;}#if !defined(XFree86Server) && !defined(XGLServer)#ifdef USE_X86_ASM#if defined( GLX_USE_TLS )extern GLubyte gl_dispatch_functions_start[];extern GLubyte gl_dispatch_functions_end[];#elseextern const GLubyte gl_dispatch_functions_start[];#endif# if defined(THREADS) && !defined(GLX_USE_TLS)# define X86_DISPATCH_FUNCTION_SIZE 32# else# define X86_DISPATCH_FUNCTION_SIZE 16# endif#endif /* USE_X86_ASM *//** * Return dispatch function address for the named static (built-in) function. * Return NULL if function not found. */static const _glapi_procget_static_proc_address(const char *funcName){ const glprocs_table_t * const f = find_entry( funcName ); if (f) {#ifdef USE_X86_ASM return (_glapi_proc) (gl_dispatch_functions_start + (X86_DISPATCH_FUNCTION_SIZE * f->Offset));#else return f->Address;#endif } else { return NULL; }}#endif /* !defined(XFree86Server) && !defined(XGLServer) *//** * Return the name of the function at the given offset in the dispatch * table. For debugging only. */static const char *get_static_proc_name( GLuint offset ){ GLuint i; for (i = 0; static_functions[i].Name_offset >= 0; i++) { if (static_functions[i].Offset == offset) { return gl_string_table + static_functions[i].Name_offset; } } return NULL;}/********************************************************************** * Extension function management. *//* * Number of extension functions which we can dynamically add at runtime. */#define MAX_EXTENSION_FUNCS 300/* * The dispatch table size (number of entries) is the size of the * _glapi_table struct plus the number of dynamic entries we can add. * The extra slots can be filled in by DRI drivers that register new extension * functions. */#define DISPATCH_TABLE_SIZE (sizeof(struct _glapi_table) / sizeof(void *) + MAX_EXTENSION_FUNCS)/** * Track information about a function added to the GL API. */struct _glapi_function { /** * Name of the function. */ const char * name; /** * Text string that describes the types of the parameters passed to the * named function. Parameter types are converted to characters using the * following rules: * - 'i' for \c GLint, \c GLuint, and \c GLenum * - 'p' for any pointer type * - 'f' for \c GLfloat and \c GLclampf * - 'd' for \c GLdouble and \c GLclampd */ const char * parameter_signature; /** * Offset in the dispatch table where the pointer to the real function is * located. If the driver has not requested that the named function be * added to the dispatch table, this will have the value ~0. */ unsigned dispatch_offset; /** * Pointer to the dispatch stub for the named function. * * \todo * The semantic of this field should be changed slightly. Currently, it * is always expected to be non-\c NULL. However, it would be better to * only allocate the entry-point stub when the application requests the * function via \c glXGetProcAddress. This would save memory for all the * functions that the driver exports but that the application never wants * to call. */ _glapi_proc dispatch_stub;};static struct _glapi_function ExtEntryTable[MAX_EXTENSION_FUNCS];static GLuint NumExtEntryPoints = 0;#ifdef USE_SPARC_ASMextern void __glapi_sparc_icache_flush(unsigned int *);#endif/** * 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 _glapi_procgenerate_entrypoint(GLuint functionOffset){#if defined(USE_X86_ASM) /* 32 is chosen as something of a magic offset. For x86, the dispatch * at offset 32 is the first one where the offset in the * "jmp OFFSET*4(%eax)" can't be encoded in a single byte. */ const GLubyte * const template_func = gl_dispatch_functions_start + (X86_DISPATCH_FUNCTION_SIZE * 32); GLubyte * const code = (GLubyte *) malloc( X86_DISPATCH_FUNCTION_SIZE ); if ( code != NULL ) { (void) memcpy( code, template_func, X86_DISPATCH_FUNCTION_SIZE ); fill_in_entrypoint_offset( (_glapi_proc) code, functionOffset ); } return (_glapi_proc) code;#elif defined(USE_SPARC_ASM)#ifdef __arch64__ static const unsigned int insn_template[] = { 0x05000000, /* sethi %uhi(_glapi_Dispatch), %g2 */ 0x03000000, /* sethi %hi(_glapi_Dispatch), %g1 */ 0x8410a000, /* or %g2, %ulo(_glapi_Dispatch), %g2 */ 0x82106000, /* or %g1, %lo(_glapi_Dispatch), %g1 */ 0x8528b020, /* sllx %g2, 32, %g2 */ 0xc2584002, /* ldx [%g1 + %g2], %g1 */ 0x05000000, /* sethi %hi(8 * glapioffset), %g2 */ 0x8410a000, /* or %g2, %lo(8 * glapioffset), %g2 */ 0xc6584002, /* ldx [%g1 + %g2], %g3 */ 0x81c0c000, /* jmpl %g3, %g0 */ 0x01000000 /* nop */ };#else static const unsigned int insn_template[] = { 0x03000000, /* sethi %hi(_glapi_Dispatch), %g1 */ 0xc2006000, /* ld [%g1 + %lo(_glapi_Dispatch)], %g1 */ 0xc6006000, /* ld [%g1 + %lo(4*glapioffset)], %g3 */ 0x81c0c000, /* jmpl %g3, %g0 */ 0x01000000 /* nop */ };#endif /* __arch64__ */ unsigned int *code = (unsigned int *) malloc(sizeof(insn_template)); unsigned long glapi_addr = (unsigned long) &_glapi_Dispatch; if (code) { memcpy(code, insn_template, sizeof(insn_template));#ifdef __arch64__ code[0] |= (glapi_addr >> (32 + 10)); code[1] |= ((glapi_addr & 0xffffffff) >> 10); __glapi_sparc_icache_flush(&code[0]); code[2] |= ((glapi_addr >> 32) & ((1 << 10) - 1)); code[3] |= (glapi_addr & ((1 << 10) - 1)); __glapi_sparc_icache_flush(&code[2]); code[6] |= ((functionOffset * 8) >> 10); code[7] |= ((functionOffset * 8) & ((1 << 10) - 1)); __glapi_sparc_icache_flush(&code[6]);#else code[0] |= (glapi_addr >> 10); code[1] |= (glapi_addr & ((1 << 10) - 1)); __glapi_sparc_icache_flush(&code[0]); code[2] |= (functionOffset * 4); __glapi_sparc_icache_flush(&code[2]);#endif /* __arch64__ */ } return (_glapi_proc) code;#else (void) functionOffset; return NULL;#endif /* USE_*_ASM */}/** * This function inserts a new dispatch offset into the assembly language * stub that was generated with the preceeding function. */static voidfill_in_entrypoint_offset(_glapi_proc entrypoint, GLuint offset){#if defined(USE_X86_ASM) GLubyte * const code = (GLubyte *) entrypoint;#if X86_DISPATCH_FUNCTION_SIZE == 32 *((unsigned int *)(code + 11)) = 4 * offset; *((unsigned int *)(code + 22)) = 4 * offset;#elif X86_DISPATCH_FUNCTION_SIZE == 16 && defined( GLX_USE_TLS ) *((unsigned int *)(code + 8)) = 4 * offset;#elif X86_DISPATCH_FUNCTION_SIZE == 16 *((unsigned int *)(code + 7)) = 4 * offset;#else# error Invalid X86_DISPATCH_FUNCTION_SIZE!#endif#elif defined(USE_SPARC_ASM) /* XXX this hasn't been tested! */ unsigned int *code = (unsigned int *) entrypoint;#ifdef __arch64__ code[6] = 0x05000000; /* sethi %hi(8 * glapioffset), %g2 */ code[7] = 0x8410a000; /* or %g2, %lo(8 * glapioffset), %g2 */ code[6] |= ((offset * 8) >> 10); code[7] |= ((offset * 8) & ((1 << 10) - 1)); __glapi_sparc_icache_flush(&code[6]);#else /* __arch64__ */ code[2] = 0xc6006000; /* ld [%g1 + %lo(4*glapioffset)], %g3 */ code[2] |= (offset * 4); __glapi_sparc_icache_flush(&code[2]);#endif /* __arch64__ */#else /* an unimplemented architecture */ (void) entrypoint; (void) offset;#endif /* USE_*_ASM */}/** * Generate new entrypoint * * Use a temporary dispatch offset of ~0 (i.e. -1). Later, when the driver * calls \c _glapi_add_dispatch we'll put in the proper offset. If that * never happens, and the user calls this function, he'll segfault. That's * what you get when you try calling a GL function that doesn't really exist. * * \param funcName Name of the function to create an entry-point for. * * \sa _glapi_add_entrypoint */static struct _glapi_function *add_function_name( const char * funcName ){ struct _glapi_function * entry = NULL; if (NumExtEntryPoints < MAX_EXTENSION_FUNCS) { _glapi_proc entrypoint = generate_entrypoint(~0); if (entrypoint != NULL) { entry = & ExtEntryTable[NumExtEntryPoints]; ExtEntryTable[NumExtEntryPoints].name = str_dup(funcName); ExtEntryTable[NumExtEntryPoints].parameter_signature = NULL; ExtEntryTable[NumExtEntryPoints].dispatch_offset = ~0; ExtEntryTable[NumExtEntryPoints].dispatch_stub = entrypoint; NumExtEntryPoints++; } } return entry;}/** * Fill-in the dispatch stub for the named function. * * This function is intended to be called by a hardware driver. When called, * a dispatch stub may be created created for the function. A pointer to this * dispatch function will be returned by glXGetProcAddress. * * \param function_names Array of pointers to function names that should * share a common dispatch offset.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -