From 97185bf2654f7e72d8bfcc216f905492655d4c77 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 17 Dec 2010 00:24:27 +0800 Subject: [PATCH] mapi: Add support for bridge mode. 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 | 21 +++++++++ src/mapi/mapi/entry_x86-64_tls.h | 22 ++++++---- src/mapi/mapi/entry_x86_tls.h | 7 ++- src/mapi/mapi/entry_x86_tsd.h | 11 +++-- src/mapi/mapi/mapi_abi.py | 93 ++++++++++++++++++++++++++++++++-------- src/mapi/mapi/mapi_tmp.h | 15 +++++++ src/mapi/mapi/sources.mak | 6 +++ src/mapi/mapi/u_current.h | 7 +-- 8 files changed, 149 insertions(+), 33 deletions(-) diff --git a/src/mapi/mapi/entry.c b/src/mapi/mapi/entry.c index faeda83..f378ccf 100644 --- a/src/mapi/mapi/entry.c +++ b/src/mapi/mapi/entry.c @@ -33,6 +33,13 @@ /* 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" @@ -45,12 +52,24 @@ #include +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 */ diff --git a/src/mapi/mapi/entry_x86-64_tls.h b/src/mapi/mapi/entry_x86-64_tls.h index 21ba434..d3b606c 100644 --- a/src/mapi/mapi/entry_x86-64_tls.h +++ b/src/mapi/mapi/entry_x86-64_tls.h @@ -26,8 +26,6 @@ * Chia-I Wu */ -#include -#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 +#include "u_execmem.h" + void entry_patch_public(void) { @@ -118,3 +120,5 @@ entry_generate(int slot) return entry; } + +#endif /* MAPI_MODE_BRIDGE */ diff --git a/src/mapi/mapi/entry_x86_tls.h b/src/mapi/mapi/entry_x86_tls.h index 43f3489..5169069 100644 --- a/src/mapi/mapi/entry_x86_tls.h +++ b/src/mapi/mapi/entry_x86_tls.h @@ -27,7 +27,6 @@ */ #include -#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 */ diff --git a/src/mapi/mapi/entry_x86_tsd.h b/src/mapi/mapi/entry_x86_tsd.h index 38742e7..1491478 100644 --- a/src/mapi/mapi/entry_x86_tsd.h +++ b/src/mapi/mapi/entry_x86_tsd.h @@ -26,8 +26,6 @@ * Chia-I Wu */ -#include -#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 +#include "u_execmem.h" + void entry_patch_public(void) { @@ -96,3 +99,5 @@ entry_generate(int slot) return entry; } + +#endif /* MAPI_MODE_BRIDGE */ diff --git a/src/mapi/mapi/mapi_abi.py b/src/mapi/mapi/mapi_abi.py index 47be8c5..cb9fc0e 100644 --- a/src/mapi/mapi/mapi_abi.py +++ b/src/mapi/mapi/mapi_abi.py @@ -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] ') @@ -1201,7 +1259,8 @@ def main(): 'vgapi': VGAPIPrinter, 'glapi': GLAPIPrinter, 'es1api': ES1APIPrinter, - 'es2api': ES2APIPrinter + 'es2api': ES2APIPrinter, + 'shared-glapi': SharedGLAPIPrinter, } filename, options = parse_args() diff --git a/src/mapi/mapi/mapi_tmp.h b/src/mapi/mapi/mapi_tmp.h index a1b067f..f326b4a 100644 --- a/src/mapi/mapi/mapi_tmp.h +++ b/src/mapi/mapi/mapi_tmp.h @@ -30,4 +30,19 @@ #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 diff --git a/src/mapi/mapi/sources.mak b/src/mapi/mapi/sources.mak index 86d98cd..c50234b 100644 --- a/src/mapi/mapi/sources.mak +++ b/src/mapi/mapi/sources.mak @@ -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 diff --git a/src/mapi/mapi/u_current.h b/src/mapi/mapi/u_current.h index bdd2df1..f9cffd8 100644 --- a/src/mapi/mapi/u_current.h +++ b/src/mapi/mapi/u_current.h @@ -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); -- 2.7.4