mesa: Allow contexts of different APIs to coexist.
authorChia-I Wu <olv@lunarg.com>
Tue, 26 Oct 2010 03:31:37 +0000 (11:31 +0800)
committerChia-I Wu <olv@lunarg.com>
Tue, 2 Nov 2010 06:43:35 +0000 (14:43 +0800)
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
src/mesa/main/context.c
src/mesa/main/es_generator.py
src/mesa/main/remap.c
src/mesa/main/remap.h

index 5f8ce3927c2c87ed533f22f7eaf0d96bdd19951b..25ece5c95e9fce97cde14590fcfd70a4ed0e8adb 100644 (file)
 #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.
index 81e862275d4008c16cb59cab0aff9d3142e23d7e..4e9bf0f990312f322b84d022ae702fbf4d610793 100644 (file)
 #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;
index bd25acd07c99757d986aab4c053e6c4400520269..aa8dab7a74325e7f9098296e0b0b9777cae37815 100644 (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_"
index 2341f8488d117f030e7043604b13f0ef570989e2..c89fba453023ecad854b78d226f6f089272d97e1 100644 (file)
 #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 */
index a2a55f615d594355e80d9768c12b2a3a40c06856..5fee300529058bda52d7a63bdae086393316124c 100644 (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 */