mapi: Add support for bridge mode.
authorChia-I Wu <olv@lunarg.com>
Thu, 16 Dec 2010 16:24:27 +0000 (00:24 +0800)
committerChia-I Wu <olv@lunarg.com>
Thu, 20 Jan 2011 09:15:50 +0000 (17:15 +0800)
In bridge mode, mapi no longer implements glapi.h.  It becomes a user of
glapi.h.  Imagine an app that uses both libGL.so and libGLESv2.so.
There will be two copies of glapi in the app's memory.  It is possible
that _glapi_get_dispatch does not return what _glapi_set_dispatch set,
if they access different copies of the global variables.  The solution
to this situation to build either one of the libraries as a bridge to
the other.  Or build both libraries as bridges to another shared
glapi library.

src/mapi/mapi/entry.c
src/mapi/mapi/entry_x86-64_tls.h
src/mapi/mapi/entry_x86_tls.h
src/mapi/mapi/entry_x86_tsd.h
src/mapi/mapi/mapi_abi.py
src/mapi/mapi/mapi_tmp.h
src/mapi/mapi/sources.mak
src/mapi/mapi/u_current.h

index faeda8351995d97c77f799b289e7a3186576578a..f378ccfda95f5c15d19de1e7ba72c07f58a9db41 100644 (file)
 /* define macros for use by assembly dispatchers */
 #define ENTRY_CURRENT_TABLE U_STRINGIFY(u_current_table)
 
+/* in bridge mode, mapi is a user of glapi */
+#ifdef MAPI_MODE_BRIDGE
+#define ENTRY_CURRENT_TABLE_GET "_glapi_get_dispatch"
+#else
+#define ENTRY_CURRENT_TABLE_GET "u_current_get_internal"
+#endif
+
 #if defined(USE_X86_ASM) && defined(__GNUC__)
 #   ifdef GLX_USE_TLS
 #      include "entry_x86_tls.h"
 
 #include <stdlib.h>
 
+static INLINE const struct mapi_table *
+entry_current_get(void)
+{
+#ifdef MAPI_MODE_BRIDGE
+   return GET_DISPATCH();
+#else
+   return u_current_get();
+#endif
+}
+
 /* C version of the public entries */
 #define MAPI_TMP_DEFINES
 #define MAPI_TMP_PUBLIC_DECLARES
 #define MAPI_TMP_PUBLIC_ENTRIES
 #include "mapi_tmp.h"
 
+#ifndef MAPI_MODE_BRIDGE
+
 void
 entry_patch_public(void)
 {
@@ -74,4 +93,6 @@ entry_patch(mapi_func entry, int slot)
 {
 }
 
+#endif /* MAPI_MODE_BRIDGE */
+
 #endif /* asm */
index 21ba434ae8ae9831444b5fc7056aea44418ef37d..d3b606c8ac5b82a62a21a4a82c0713a0ffd12521 100644 (file)
@@ -26,8 +26,6 @@
  *    Chia-I Wu <olv@lunarg.com>
  */
 
-#include <string.h>
-#include "u_execmem.h"
 #include "u_macros.h"
 
 #ifdef __linux__
@@ -43,13 +41,8 @@ __asm__(".section .note.ABI-tag, \"a\"\n\t"
         "3: .p2align 2\n\t");    /* pad out section */
 #endif /* __linux__ */
 
-__asm__(".text");
-
-__asm__("x86_64_current_tls:\n\t"
-       "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t"
-       "ret");
-
-__asm__(".balign 32\n"
+__asm__(".text\n"
+        ".balign 32\n"
         "x86_64_entry_start:");
 
 #define STUB_ASM_ENTRY(func)                             \
@@ -66,9 +59,18 @@ __asm__(".balign 32\n"
 #define MAPI_TMP_STUB_ASM_GCC
 #include "mapi_tmp.h"
 
+#ifndef MAPI_MODE_BRIDGE
+
+__asm__("x86_64_current_tls:\n\t"
+       "movq " ENTRY_CURRENT_TABLE "@GOTTPOFF(%rip), %rax\n\t"
+       "ret");
+
 extern unsigned long
 x86_64_current_tls();
 
+#include <string.h>
+#include "u_execmem.h"
+
 void
 entry_patch_public(void)
 {
@@ -118,3 +120,5 @@ entry_generate(int slot)
 
    return entry;
 }
+
+#endif /* MAPI_MODE_BRIDGE */
index 43f34895646a6154e433657d82b54e892bc3dd74..5169069a132500e92bfbb5ed4b386329e996ae6d 100644 (file)
@@ -27,7 +27,6 @@
  */
 
 #include <string.h>
-#include "u_execmem.h"
 #include "u_macros.h"
 
 #ifdef __linux__
@@ -80,6 +79,10 @@ __asm__(".balign 16\n"
 __asm__(".text");
 #endif /* GLX_X86_READONLY_TEXT */
 
+#ifndef MAPI_MODE_BRIDGE
+
+#include "u_execmem.h"
+
 extern unsigned long
 x86_current_tls();
 
@@ -139,3 +142,5 @@ entry_generate(int slot)
 
    return entry;
 }
+
+#endif /* MAPI_MODE_BRIDGE */
index 38742e77dc439c8369f94a12b463b6d6fd3e44ae..1491478d4707730e4ce52a8a174f6b2d21e8620e 100644 (file)
@@ -26,8 +26,6 @@
  *    Chia-I Wu <olv@lunarg.com>
  */
 
-#include <string.h>
-#include "u_execmem.h"
 #include "u_macros.h"
 
 #define X86_ENTRY_SIZE 32
@@ -48,15 +46,20 @@ __asm__(".text\n"
    "je 1f\n\t"                      \
    "jmp *(4 * " slot ")(%eax)\n"    \
    "1:\n\t"                         \
-   "call u_current_get_internal\n\t"\
+   "call " ENTRY_CURRENT_TABLE_GET "\n\t" \
    "jmp *(4 * " slot ")(%eax)"
 
 #define MAPI_TMP_STUB_ASM_GCC
 #include "mapi_tmp.h"
 
+#ifndef MAPI_MODE_BRIDGE
+
 __asm__(".balign 32\n"
         "x86_entry_end:");
 
+#include <string.h>
+#include "u_execmem.h"
+
 void
 entry_patch_public(void)
 {
@@ -96,3 +99,5 @@ entry_generate(int slot)
 
    return entry;
 }
+
+#endif /* MAPI_MODE_BRIDGE */
index 47be8c5b4af09b6441915a355fa6ce1d310796f6..cb9fc0ef84185efd819c2c725aa728288b2b9267 100644 (file)
@@ -295,6 +295,7 @@ class ABIPrinter(object):
         self.indent = ' ' * 3
         self.noop_warn = 'noop_warn'
         self.noop_generic = 'noop_generic'
+        self.current_get = 'entry_current_get'
 
         self.api_defines = []
         self.api_headers = ['"KHR/khrplatform.h"']
@@ -307,7 +308,8 @@ class ABIPrinter(object):
         self.lib_need_table_size = True
         self.lib_need_noop_array = True
         self.lib_need_stubs = True
-        self.lib_need_entries = True
+        self.lib_need_all_entries = True
+        self.lib_need_non_hidden_entries = False
 
     def c_notice(self):
         return '/* This file is automatically generated by mapi_abi.py.  Do not modify. */'
@@ -337,11 +339,7 @@ class ABIPrinter(object):
 
     def c_mapi_table(self):
         """Return defines of the dispatch table size."""
-        num_static_entries = 0
-        for ent in self.entries:
-            if not ent.alias:
-                num_static_entries += 1
-
+        num_static_entries = self.entries[-1].slot + 1
         return ('#define MAPI_TABLE_NUM_STATIC %d\n' + \
                 '#define MAPI_TABLE_NUM_DYNAMIC %d') % (
                         num_static_entries, ABI_NUM_DYNAMIC_ENTRIES)
@@ -418,10 +416,13 @@ class ABIPrinter(object):
 
         return "\n".join(decls)
 
-    def c_public_dispatches(self, prefix):
+    def c_public_dispatches(self, prefix, no_hidden):
         """Return the public dispatch functions."""
         dispatches = []
         for ent in self.entries:
+            if ent.hidden and no_hidden:
+                continue
+
             if not self.need_entry_point(ent):
                 continue
 
@@ -434,7 +435,8 @@ class ABIPrinter(object):
             if ent.ret:
                 ret = 'return '
             stmt1 = self.indent
-            stmt1 += 'const struct mapi_table *_tbl = u_current_get();'
+            stmt1 += 'const struct mapi_table *_tbl = %s();' % (
+                    self.current_get)
             stmt2 = self.indent
             stmt2 += 'mapi_func _func = ((const mapi_func *) _tbl)[%d];' % (
                     ent.slot)
@@ -524,11 +526,13 @@ class ABIPrinter(object):
         pre = self.indent + '(mapi_func) '
         return pre + (',\n' + pre).join(entries)
 
-    def c_asm_gcc(self, prefix):
+    def c_asm_gcc(self, prefix, no_hidden):
         asm = []
 
-        asm.append('__asm__(')
         for ent in self.entries:
+            if ent.hidden and no_hidden:
+                continue
+
             if not self.need_entry_point(ent):
                 continue
 
@@ -540,7 +544,7 @@ class ABIPrinter(object):
             if ent.hidden:
                 asm.append('".hidden "%s"\\n"' % (name))
 
-            if ent.alias:
+            if ent.alias and not (ent.alias.hidden and no_hidden):
                 asm.append('".globl "%s"\\n"' % (name))
                 asm.append('".set "%s", "%s"\\n"' % (name,
                     self._c_function(ent.alias, prefix, True, True)))
@@ -551,7 +555,6 @@ class ABIPrinter(object):
             if ent.handcode:
                 asm.append('#endif')
             asm.append('')
-        asm.append(');')
 
         return "\n".join(asm)
 
@@ -611,10 +614,10 @@ class ABIPrinter(object):
             print '#undef MAPI_TMP_PUBLIC_STUBS'
             print '#endif /* MAPI_TMP_PUBLIC_STUBS */'
 
-        if self.lib_need_entries:
+        if self.lib_need_all_entries:
             print
             print '#ifdef MAPI_TMP_PUBLIC_ENTRIES'
-            print self.c_public_dispatches(self.prefix_lib)
+            print self.c_public_dispatches(self.prefix_lib, False)
             print
             print 'static const mapi_func public_entries[] = {'
             print self.c_public_initializer(self.prefix_lib)
@@ -624,10 +627,35 @@ class ABIPrinter(object):
 
             print
             print '#ifdef MAPI_TMP_STUB_ASM_GCC'
-            print self.c_asm_gcc(self.prefix_lib)
+            print '__asm__('
+            print self.c_asm_gcc(self.prefix_lib, False)
+            print ');'
             print '#undef MAPI_TMP_STUB_ASM_GCC'
             print '#endif /* MAPI_TMP_STUB_ASM_GCC */'
 
+        if self.lib_need_non_hidden_entries:
+            all_hidden = True
+            for ent in self.entries:
+                if not ent.hidden:
+                    all_hidden = False
+                    break
+            if not all_hidden:
+                print
+                print '#ifdef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN'
+                print self.c_public_dispatches(self.prefix_lib, True)
+                print
+                print '/* does not need public_entries */'
+                print '#undef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN'
+                print '#endif /* MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN */'
+
+                print
+                print '#ifdef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN'
+                print '__asm__('
+                print self.c_asm_gcc(self.prefix_lib, True)
+                print ');'
+                print '#undef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN'
+                print '#endif /* MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN */'
+
     def output_for_app(self):
         print self.c_notice()
         print
@@ -657,6 +685,12 @@ class GLAPIPrinter(ABIPrinter):
         self.api_entry = 'APIENTRY'
         self.api_attrs = ''
 
+        self.lib_need_table_size = False
+        self.lib_need_noop_array = False
+        self.lib_need_stubs = False
+        self.lib_need_all_entries = False
+        self.lib_need_non_hidden_entries = True
+
         self.prefix_lib = 'GLAPI_PREFIX'
         self.prefix_app = '_mesa_'
         self.prefix_noop = 'noop'
@@ -1161,6 +1195,30 @@ typedef int GLclampx;
 
         return header
 
+class SharedGLAPIPrinter(GLAPIPrinter):
+    """Shared GLAPI API Printer"""
+
+    def __init__(self, entries):
+        super(SharedGLAPIPrinter, self).__init__(entries, [])
+
+        self.lib_need_table_size = True
+        self.lib_need_noop_array = True
+        self.lib_need_stubs = True
+        self.lib_need_all_entries = True
+        self.lib_need_non_hidden_entries = False
+
+        self.prefix_lib = 'shared'
+        self.prefix_warn = 'gl'
+
+    def _get_c_header(self):
+        header = """#ifndef _GLAPI_TMP_H_
+#define _GLAPI_TMP_H_
+typedef int GLfixed;
+typedef int GLclampx;
+#endif /* _GLAPI_TMP_H_ */"""
+
+        return header
+
 class VGAPIPrinter(ABIPrinter):
     """OpenVG API Printer"""
 
@@ -1179,7 +1237,7 @@ class VGAPIPrinter(ABIPrinter):
         self.prefix_warn = 'vg'
 
 def parse_args():
-    printers = ['glapi', 'es1api', 'es2api', 'vgapi']
+    printers = ['vgapi', 'glapi', 'es1api', 'es2api', 'shared-glapi']
     modes = ['lib', 'app']
 
     parser = OptionParser(usage='usage: %prog [options] <filename>')
@@ -1201,7 +1259,8 @@ def main():
         'vgapi': VGAPIPrinter,
         'glapi': GLAPIPrinter,
         'es1api': ES1APIPrinter,
-        'es2api': ES2APIPrinter
+        'es2api': ES2APIPrinter,
+        'shared-glapi': SharedGLAPIPrinter,
     }
 
     filename, options = parse_args()
index a1b067fb73ce41fa9d5cedde60a6de59160b3938..f326b4a4e14fd4baa696b519ce38a8a12938cabd 100644 (file)
 #error "MAPI_ABI_HEADER must be defined"
 #endif
 
+/* does not need hidden entries in bridge mode */
+#ifdef MAPI_MODE_BRIDGE
+
+#ifdef MAPI_TMP_PUBLIC_ENTRIES
+#undef MAPI_TMP_PUBLIC_ENTRIES
+#define MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN
+#endif
+
+#ifdef MAPI_TMP_STUB_ASM_GCC
+#undef MAPI_TMP_STUB_ASM_GCC
+#define MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN
+#endif
+
+#endif /* MAPI_MODE_BRIDGE */
+
 #include MAPI_ABI_HEADER
index 86d98cd143f2a52ca3d46597ea19b1424e865e4f..c50234b5789fb0cb5a442a6e2e63540599f0ebfa 100644 (file)
@@ -10,6 +10,9 @@
 #
 #  - In glapi mode, mapi implements the interface defined by glapi.h.  To use
 #    this mode, compile MAPI_GLAPI_SOURCES with MAPI_MODE_GLAPI defined.
+#
+#  - In bridge mode, mapi provides entry points calling into glapi.  To use
+#    this mode, compile MAPI_BRIDGE_SOURCES with MAPI_MODE_BRIDGE defined.
 
 MAPI_UTIL_SOURCES = \
        u_current.c \
@@ -29,3 +32,6 @@ MAPI_GLAPI_SOURCES = \
        stub.c \
        table.c \
        $(MAPI_UTIL_SOURCES)
+
+MAPI_BRIDGE_SOURCES = \
+       entry.c
index bdd2df112517d7449a77cbb63ee5ec1d0761da0c..f9cffd8c3d0c1bcd67bf2969186fdfc01fefdd80 100644 (file)
@@ -1,7 +1,8 @@
 #ifndef _U_CURRENT_H_
 #define _U_CURRENT_H_
 
-#if defined(MAPI_MODE_UTIL) || defined(MAPI_MODE_GLAPI)
+#if defined(MAPI_MODE_UTIL) || defined(MAPI_MODE_GLAPI) || \
+    defined(MAPI_MODE_BRIDGE)
 
 #include "glapi/glapi.h"
 
@@ -21,7 +22,7 @@
 
 #define u_current_table_tsd _gl_DispatchTSD
 
-#else /* MAPI_MODE_UTIL || MAPI_MODE_GLAPI */
+#else /* MAPI_MODE_UTIL || MAPI_MODE_GLAPI || MAPI_MODE_BRIDGE */
 
 #include "u_compiler.h"
 
@@ -42,7 +43,7 @@ extern void *u_current_user;
 
 #endif /* GLX_USE_TLS */
 
-#endif /* MAPI_MODE_UTIL || MAPI_MODE_GLAPI */
+#endif /* MAPI_MODE_UTIL || MAPI_MODE_GLAPI || MAPI_MODE_BRIDGE */
 
 void
 u_current_init(void);