Mesa (master): mesa: Allow contexts of different APIs to coexist.

Chia-I Wu olv at kemper.freedesktop.org
Tue Nov 2 06:57:27 UTC 2010


Module: Mesa
Branch: master
Commit: 16ee7a55ae269612263468195f2af998cb9ef695
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=16ee7a55ae269612263468195f2af998cb9ef695

Author: Chia-I Wu <olv at lunarg.com>
Date:   Tue Oct 26 11:31:37 2010 +0800

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 5f8ce39..25ece5c 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 81e8622..4e9bf0f 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 bd25acd..aa8dab7 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 2341f84..c89fba4 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;
 }
 
 
@@ -152,11 +160,31 @@ _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 a2a55f6..5fee300 100644
--- a/src/mesa/main/remap.h
+++ b/src/mesa/main/remap.h
@@ -60,25 +60,8 @@ 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 *
@@ -105,37 +88,10 @@ _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 */
 
 




More information about the mesa-commit mailing list