From 16ee7a55ae269612263468195f2af998cb9ef695 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 26 Oct 2010 11:31:37 +0800 Subject: [PATCH] mesa: Allow contexts of different APIs to coexist. This effectively redoes 1741ddb747ca0be284315adb4b6fe67ddf292d03 in a way that allows contexts of different APIs to coexist. First, the changes to the remap table are reverted. The remap table (driDispatchRemapTable) is always initialized in the same way regardless of the context API. es_generator.py is updated to use a local remap table, whose sole purpose is to help initialize its dispatch table. The local remap table and the global one are always different, as they use different glapidispatch.h. But the dispatch tables initialized by both remap tables are always compatible with glapi (libGL.so). Finally, the semantics of one_time_init are changed to per-api one-time initialization. --- src/mesa/main/api_exec.c | 40 ------------- src/mesa/main/context.c | 56 +++++++++--------- src/mesa/main/es_generator.py | 105 ++++++++++++++++++++-------------- src/mesa/main/remap.c | 46 +++++++++++++-- src/mesa/main/remap.h | 44 -------------- 5 files changed, 132 insertions(+), 159 deletions(-) diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c index 5f8ce3927c2..25ece5c95e9 100644 --- a/src/mesa/main/api_exec.c +++ b/src/mesa/main/api_exec.c @@ -105,46 +105,6 @@ #if FEATURE_GL -#ifdef _GLAPI_USE_REMAP_TABLE - -#define need_MESA_remap_table -#include "main/remap.h" -#include "main/remap_helper.h" - -/* This is shared across all APIs but We define this here since - * desktop GL has the biggest remap table. */ -int driDispatchRemapTable[driDispatchRemapTable_size]; - -/** - * Map the functions which are already static. - * - * When a extension function are incorporated into the ABI, the - * extension suffix is usually stripped. Mapping such functions - * makes sure the alternative names are available. - * - * Note that functions mapped by _mesa_init_remap_table() are - * excluded. - */ -void -_mesa_map_static_functions(void) -{ - /* Remap static functions which have alternative names and are in the ABI. - * This is to be on the safe side. glapi should have defined those names. - */ - _mesa_map_function_array(MESA_alt_functions); -} - -void -_mesa_init_remap_table(void) -{ - _mesa_do_init_remap_table(_mesa_function_pool, - driDispatchRemapTable_size, - MESA_remap_table_functions); -} - -#endif /* _GLAPI_USE_REMAP_TABLE */ - - /** * Initialize a dispatch table with pointers to Mesa's immediate-mode * commands. diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 81e862275d4..4e9bf0f9903 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -131,6 +131,7 @@ #if _HAVE_FULL_GL #include "math/m_matrix.h" #endif +#include "main/dispatch.h" /* for _gloffset_COUNT */ #ifdef USE_SPARC_ASM #include "sparc/sparc.h" @@ -379,10 +380,12 @@ _glthread_DECLARE_STATIC_MUTEX(OneTimeLock); static void one_time_init( struct gl_context *ctx ) { - static GLboolean alreadyCalled = GL_FALSE; - (void) ctx; + static GLbitfield api_init_mask = 0x0; + _glthread_LOCK_MUTEX(OneTimeLock); - if (!alreadyCalled) { + + /* truly one-time init */ + if (!api_init_mask) { GLuint i; /* do some implementation tests */ @@ -395,27 +398,9 @@ one_time_init( struct gl_context *ctx ) _mesa_get_cpu_features(); - switch (ctx->API) { -#if FEATURE_GL - case API_OPENGL: - _mesa_init_remap_table(); - break; -#endif -#if FEATURE_ES1 - case API_OPENGLES: - _mesa_init_remap_table_es1(); - break; -#endif -#if FEATURE_ES2 - case API_OPENGLES2: - _mesa_init_remap_table_es2(); - break; -#endif - default: - break; - } - _mesa_init_sqrt_table(); + + /* context dependence is never a one-time thing... */ _mesa_init_get_hash(ctx); for (i = 0; i < 256; i++) { @@ -426,9 +411,22 @@ one_time_init( struct gl_context *ctx ) _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n", MESA_VERSION_STRING, __DATE__, __TIME__); #endif + } - alreadyCalled = GL_TRUE; + /* per-API one-time init */ + if (!(api_init_mask & (1 << ctx->API))) { + /* + * This is fine as ES does not use the remap table, but it may not be + * future-proof. We cannot always initialize the remap table because + * when an app is linked to libGLES*, there are not enough dynamic + * entries. + */ + if (ctx->API == API_OPENGL) + _mesa_init_remap_table(); } + + api_init_mask |= 1 << ctx->API; + _glthread_UNLOCK_MUTEX(OneTimeLock); /* Hopefully atexit() is widely available. If not, we may need some @@ -811,9 +809,13 @@ _mesa_alloc_dispatch_table(int size) * Mesa we do this to accomodate different versions of libGL and various * DRI drivers. */ - GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), size); - struct _glapi_table *table = - (struct _glapi_table *) malloc(numEntries * sizeof(_glapi_proc)); + GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT); + struct _glapi_table *table; + + /* should never happen, but just in case */ + numEntries = MAX2(numEntries, size); + + table = (struct _glapi_table *) malloc(numEntries * sizeof(_glapi_proc)); if (table) { _glapi_proc *entry = (_glapi_proc *) table; GLint i; diff --git a/src/mesa/main/es_generator.py b/src/mesa/main/es_generator.py index bd25acd07c9..aa8dab7a743 100644 --- a/src/mesa/main/es_generator.py +++ b/src/mesa/main/es_generator.py @@ -191,6 +191,8 @@ print """ #include "%s" #include "%s" #include "main/mfeatures.h" +#include "main/compiler.h" +#include "main/api_exec.h" #if FEATURE_%s """ % (versionHeader, versionExtHeader, shortname.upper()) @@ -206,48 +208,7 @@ typedef double GLclampd; /* Mesa error handling requires these */ extern void *_mesa_get_current_context(void); extern void _mesa_error(void *ctx, GLenum error, const char *fmtString, ... ); - -#include "main/compiler.h" -#include "main/api_exec.h" -#include "main/remap.h" - -/* cannot include main/dispatch.h here */ -#if FEATURE_remap_table -#define _GLAPI_USE_REMAP_TABLE -#endif -/* glapi uses GLAPIENTRY while GLES headers define GL_APIENTRY */ -#ifndef GLAPIENTRY -#define GLAPIENTRY GL_APIENTRY -#endif -#include "%sapi/main/glapidispatch.h" - -#if FEATURE_remap_table - -#if !FEATURE_GL -int driDispatchRemapTable[driDispatchRemapTable_size]; -#endif - -#define need_MESA_remap_table - -#include "%sapi/main/remap_helper.h" - -void -_mesa_init_remap_table_%s(void) -{ - _mesa_do_init_remap_table(_mesa_function_pool, - driDispatchRemapTable_size, - MESA_remap_table_functions); -} - -void -_mesa_map_static_functions_%s(void) -{ -} - -#endif - -typedef void (*_glapi_proc)(void); /* generic function pointer */ -""" % (shortname, shortname, shortname, shortname); +""" # Finally we get to the all-important functions print """/************************************************************* @@ -711,15 +672,73 @@ for funcName in keys: # end for each function print """ +#include "glapi/glapi.h" + +#if FEATURE_remap_table + +/* cannot include main/dispatch.h here */ +#define _GLAPI_USE_REMAP_TABLE +#include "%sapi/main/glapidispatch.h" + +#define need_MESA_remap_table +#include "%sapi/main/remap_helper.h" + +/* force SET_* macros to use the local remap table */ +#define driDispatchRemapTable remap_table +static int remap_table[driDispatchRemapTable_size]; + +static void +init_remap_table(void) +{ + _glthread_DECLARE_STATIC_MUTEX(mutex); + static GLboolean initialized = GL_FALSE; + const struct gl_function_pool_remap *remap = MESA_remap_table_functions; + int i; + + _glthread_LOCK_MUTEX(mutex); + if (initialized) { + _glthread_UNLOCK_MUTEX(mutex); + return; + } + + for (i = 0; i < driDispatchRemapTable_size; i++) { + GLint offset; + const char *spec; + + /* sanity check */ + ASSERT(i == remap[i].remap_index); + spec = _mesa_function_pool + remap[i].pool_index; + + offset = _mesa_map_function_spec(spec); + remap_table[i] = offset; + } + initialized = GL_TRUE; + _glthread_UNLOCK_MUTEX(mutex); +} + +#else /* FEATURE_remap_table */ + +/* cannot include main/dispatch.h here */ +#include "%sapi/main/glapidispatch.h" + +static INLINE void +init_remap_table(void) +{ +} + +#endif /* FEATURE_remap_table */ + struct _glapi_table * _mesa_create_exec_table_%s(void) { struct _glapi_table *exec; + exec = _mesa_alloc_dispatch_table(_gloffset_COUNT); if (exec == NULL) return NULL; -""" % shortname + init_remap_table(); +""" % (shortname, shortname, shortname, shortname) for func in keys: prefix = "_es_" if func not in allSpecials else "_check_" diff --git a/src/mesa/main/remap.c b/src/mesa/main/remap.c index 2341f8488d1..c89fba45302 100644 --- a/src/mesa/main/remap.c +++ b/src/mesa/main/remap.c @@ -44,10 +44,15 @@ #include "imports.h" #include "glapi/glapi.h" -#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) #define MAX_ENTRY_POINTS 16 -static const char *_mesa_function_pool; +#define need_MESA_remap_table +#include "main/remap_helper.h" + + +/* this is global for quick access */ +int driDispatchRemapTable[driDispatchRemapTable_size]; + /** * Return the spec string associated with the given function index. @@ -60,7 +65,10 @@ static const char *_mesa_function_pool; const char * _mesa_get_function_spec(GLint func_index) { - return _mesa_function_pool + func_index; + if (func_index < Elements(_mesa_function_pool)) + return _mesa_function_pool + func_index; + else + return NULL; } @@ -151,12 +159,32 @@ _mesa_map_function_array(const struct gl_function_remap *func_array) } +/** + * Map the functions which are already static. + * + * When a extension function are incorporated into the ABI, the + * extension suffix is usually stripped. Mapping such functions + * makes sure the alternative names are available. + * + * Note that functions mapped by _mesa_init_remap_table() are + * excluded. + */ +void +_mesa_map_static_functions(void) +{ + /* Remap static functions which have alternative names and are in the ABI. + * This is to be on the safe side. glapi should have defined those names. + */ + _mesa_map_function_array(MESA_alt_functions); +} + + /** * Initialize the remap table. This is called in one_time_init(). * The remap table needs to be initialized before calling the * CALL/GET/SET macros defined in main/dispatch.h. */ -void +static void _mesa_do_init_remap_table(const char *pool, int size, const struct gl_function_pool_remap *remap) @@ -167,7 +195,6 @@ _mesa_do_init_remap_table(const char *pool, if (initialized) return; initialized = GL_TRUE; - _mesa_function_pool = pool; /* initialize the remap table */ for (i = 0; i < size; i++) { @@ -187,4 +214,13 @@ _mesa_do_init_remap_table(const char *pool, } +void +_mesa_init_remap_table(void) +{ + _mesa_do_init_remap_table(_mesa_function_pool, + driDispatchRemapTable_size, + MESA_remap_table_functions); +} + + #endif /* FEATURE_remap_table */ diff --git a/src/mesa/main/remap.h b/src/mesa/main/remap.h index a2a55f615d5..5fee3005290 100644 --- a/src/mesa/main/remap.h +++ b/src/mesa/main/remap.h @@ -59,26 +59,9 @@ _mesa_map_function_array(const struct gl_function_remap *func_array); extern void _mesa_map_static_functions(void); -extern void -_mesa_map_static_functions_es1(void); - -extern void -_mesa_map_static_functions_es2(void); - -extern void -_mesa_do_init_remap_table(const char *pool, - int size, - const struct gl_function_pool_remap *remap); - extern void _mesa_init_remap_table(void); -extern void -_mesa_init_remap_table_es1(void); - -extern void -_mesa_init_remap_table_es2(void); - #else /* FEATURE_remap_table */ static INLINE const char * @@ -104,38 +87,11 @@ _mesa_map_static_functions(void) } -static INLINE void -_mesa_map_static_functions_es1(void) -{ -} - -static INLINE void -_mesa_map_static_functions_es2(void) -{ -} - -static INLINE void -_mesa_do_init_remap_table(const char *pool, - int size, - const struct gl_function_pool_remap *remap) -{ -} - static INLINE void _mesa_init_remap_table(void) { } -static INLINE void -_mesa_init_remap_table_es1(void) -{ -} - -static INLINE void -_mesa_init_remap_table_es2(void) -{ -} - #endif /* FEATURE_remap_table */ -- 2.30.2