Fix the aliasing support to actually build.

Jordan asked me to show my code, so I pushed the snapshot I had,
forgetting that the build was broken at that point in commit
--amending.
macos/v1.5.9
Eric Anholt 11 years ago
parent 4c9b7e63b1
commit faad44cc0a
  1. 62
      src/gen_dispatch.py

@ -35,15 +35,29 @@ class GLFunction(object):
self.ret_type = ret_type self.ret_type = ret_type
self.providers = [] self.providers = []
self.args = [] self.args = []
# This is the string of C code for passing through the
# arguments to the function.
self.args_list = '' self.args_list = ''
# This is the string of C code for declaring the arguments
# list.
self.args_decl = 'void' self.args_decl = 'void'
# For an alias group, alias_func is the function they are all # If present, this is the string name of the function that
# marked as the alias of. # this is an alias of. This initially comes from the
# registry, and may get updated if it turns out our alias is
# itself an alias (for example glFramebufferTextureEXT ->
# glFramebufferTextureARB -> glFramebufferTexture)
self.alias_name = None
# After alias resolution, this is the function that this is an
# alias of.
self.alias_func = None self.alias_func = None
# For an alias group, the shared alias_func has this list of
# functions (of different names) that are marked as aliases of # For the root of an alias tree, this lists the functions that
# it, so that it can write a resolver for all of them. # are marked as aliases of it, so that it can write a resolver
# for all of them.
self.alias_exts = [] self.alias_exts = []
def add_arg(self, type, name): def add_arg(self, type, name):
@ -138,8 +152,11 @@ class Generator(object):
alias = command.find('alias') alias = command.find('alias')
if alias is not None: if alias is not None:
alias_func = self.functions[alias.get('name')] # XXX print('{0} -> {1}'.format(func.name, alias.get('name')))
alias_func.add_alias(func) # Note that some alias references appear before the
# target command is defined (glAttachObjectARB() ->
# glAttachShader(), for example).
func.alias_name = alias.get('name')
self.functions[name] = func self.functions[name] = func
@ -154,6 +171,17 @@ class Generator(object):
for name in weird_functions: for name in weird_functions:
del self.functions[name] del self.functions[name]
def resolve_aliases(self):
for func in self.functions.values():
# Find the root of the alias tree, and add ourselves to it.
if func.alias_name:
alias_func = func
while alias_func.alias_name:
alias_func = self.functions[alias_func.alias_name]
func.alias_name = alias_func.name
func.alias_func = alias_func
alias_func.alias_exts.append(func)
def process_require_statements(self, feature, condition, loader, human_name): def process_require_statements(self, feature, condition, loader, human_name):
for command in feature.findall('require/command'): for command in feature.findall('require/command'):
name = command.get('name') name = command.get('name')
@ -373,20 +401,20 @@ class Generator(object):
self.outln('') self.outln('')
def write_dispatch_table_stub(self, func): def write_dispatch_table_stub(self, func):
dispatch_table_entry = 'dispatch_table->p{0}'.format(func.name)
# Use the same resolver for all the aliases of a particular # Use the same resolver for all the aliases of a particular
# function. # function.
alias_func = func alias_name = func.name
if func.alias_func: if func.alias_name:
alias_func = func alias_name = func.alias_name
dispatch_table_entry = 'dispatch_table->p{0}'.format(alias_name)
self.outln('PUBLIC {0}'.format(func.ret_type)) self.outln('PUBLIC {0}'.format(func.ret_type))
self.outln('epoxy_{0}({1})'.format(func.name, func.args_decl)) self.outln('epoxy_{0}({1})'.format(func.name, func.args_decl))
self.outln('{') self.outln('{')
self.outln(' if (!{0})'.format(dispatch_table_entry)) self.outln(' if (!{0})'.format(dispatch_table_entry))
self.outln(' {0} = epoxy_{1}_resolver();'.format(dispatch_table_entry, self.outln(' {0} = epoxy_{1}_resolver();'.format(dispatch_table_entry,
alias_func.name)) alias_name))
self.outln('') self.outln('')
if func.ret_type == 'void': if func.ret_type == 'void':
self.outln(' {0}({1});'.format(dispatch_table_entry, func.args_list)) self.outln(' {0}({1});'.format(dispatch_table_entry, func.args_list))
@ -415,7 +443,9 @@ class Generator(object):
self.outln('struct dispatch_table {') self.outln('struct dispatch_table {')
for func in self.functions.values(): for func in self.functions.values():
self.outln(' {0} p{1};'.format(func.ptr_type, func.name)) # Aliases don't get their own slot, since they use a shared resolver.
if not func.alias_name:
self.outln(' {0} p{1};'.format(func.ptr_type, func.name))
self.outln('};') self.outln('};')
self.outln('') self.outln('')
@ -428,6 +458,7 @@ class Generator(object):
if not func.alias_func: if not func.alias_func:
self.write_function_ptr_resolver(func) self.write_function_ptr_resolver(func)
for func in self.functions.values():
self.write_dispatch_table_stub(func) self.write_dispatch_table_stub(func)
argparser = argparse.ArgumentParser(description='Generate GL dispatch wrappers.') argparser = argparse.ArgumentParser(description='Generate GL dispatch wrappers.')
@ -443,13 +474,14 @@ for file in args.files:
generator = Generator() generator = Generator()
generator.parse(file) generator.parse(file)
generator.drop_weird_glx_functions() generator.drop_weird_glx_functions()
generator.resolve_aliases()
generator.fixup_bootstrap_function('glGetString') generator.fixup_bootstrap_function('glGetString')
generator.fixup_bootstrap_function('glGetIntegerv') generator.fixup_bootstrap_function('glGetIntegerv')
# While this is technically exposed as a GLX extension, it's # While this is technically exposed as a GLX extension, it's
# required to be present as a public symbol by the Linux OpenGL # required to be present as a public symbol by the Linux OpenGL
# ABI. # ABI.
generator.fixup_bootstrap_function('glXGetProcAddressARB') generator.fixup_bootstrap_function('glXGetProcAddress')
generator.write_header(incdir + name + '_generated.h') generator.write_header(incdir + name + '_generated.h')
generator.write_proto_define_header(incdir + name + '_generated_vtable_defines.h', '') generator.write_proto_define_header(incdir + name + '_generated_vtable_defines.h', '')

Loading…
Cancel
Save