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.
This commit is contained in:
@@ -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 <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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
+76
-17
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user