mesa: Allow contexts of different APIs to coexist.

This effectively redoes 1741ddb747 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.
This commit is contained in:
Chia-I Wu 2010-10-26 11:31:37 +08:00
parent fdede1efaa
commit 16ee7a55ae
5 changed files with 133 additions and 160 deletions

View file

@ -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.

View file

@ -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;

View file

@ -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_"

View file

@ -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 */

View file

@ -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 */