1848b8605Smrg 2848b8605Smrg# (C) Copyright IBM Corporation 2004, 2005 3848b8605Smrg# All Rights Reserved. 4848b8605Smrg# 5848b8605Smrg# Permission is hereby granted, free of charge, to any person obtaining a 6848b8605Smrg# copy of this software and associated documentation files (the "Software"), 7848b8605Smrg# to deal in the Software without restriction, including without limitation 8848b8605Smrg# on the rights to use, copy, modify, merge, publish, distribute, sub 9848b8605Smrg# license, and/or sell copies of the Software, and to permit persons to whom 10848b8605Smrg# the Software is furnished to do so, subject to the following conditions: 11848b8605Smrg# 12848b8605Smrg# The above copyright notice and this permission notice (including the next 13848b8605Smrg# paragraph) shall be included in all copies or substantial portions of the 14848b8605Smrg# Software. 15848b8605Smrg# 16848b8605Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17848b8605Smrg# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20848b8605Smrg# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21848b8605Smrg# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22848b8605Smrg# IN THE SOFTWARE. 23848b8605Smrg# 24848b8605Smrg# Authors: 25848b8605Smrg# Ian Romanick <idr@us.ibm.com> 26848b8605Smrg 27b8e80941Smrgfrom __future__ import print_function 28b8e80941Smrg 29b8e80941Smrgimport argparse 30b8e80941Smrg 31848b8605Smrgimport gl_XML, glX_XML 32848b8605Smrgimport license 33848b8605Smrg 34848b8605Smrgclass PrintGlOffsets(gl_XML.gl_print_base): 35848b8605Smrg def __init__(self, es=False): 36848b8605Smrg gl_XML.gl_print_base.__init__(self) 37848b8605Smrg 38848b8605Smrg self.name = "gl_apitemp.py (from Mesa)" 39848b8605Smrg self.license = license.bsd_license_template % ( \ 40848b8605Smrg"""Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 41848b8605Smrg(C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM") 42848b8605Smrg 43848b8605Smrg self.es = es 44848b8605Smrg 45848b8605Smrg self.undef_list.append( "KEYWORD1" ) 46848b8605Smrg self.undef_list.append( "KEYWORD1_ALT" ) 47848b8605Smrg self.undef_list.append( "KEYWORD2" ) 48848b8605Smrg self.undef_list.append( "NAME" ) 49848b8605Smrg self.undef_list.append( "DISPATCH" ) 50848b8605Smrg self.undef_list.append( "RETURN_DISPATCH" ) 51848b8605Smrg self.undef_list.append( "DISPATCH_TABLE_NAME" ) 52848b8605Smrg self.undef_list.append( "UNUSED_TABLE_NAME" ) 53848b8605Smrg self.undef_list.append( "TABLE_ENTRY" ) 54848b8605Smrg 55848b8605Smrg 56848b8605Smrg def printFunction(self, f, name): 57848b8605Smrg p_string = "" 58848b8605Smrg o_string = "" 59848b8605Smrg t_string = "" 60848b8605Smrg comma = "" 61848b8605Smrg 62848b8605Smrg if f.is_static_entry_point(name): 63848b8605Smrg keyword = "KEYWORD1" 64848b8605Smrg else: 65848b8605Smrg keyword = "KEYWORD1_ALT" 66848b8605Smrg 67848b8605Smrg n = f.static_name(name) 68848b8605Smrg 69848b8605Smrg silence = '' 70848b8605Smrg space = '' 71848b8605Smrg for p in f.parameterIterator(name): 72848b8605Smrg if p.is_padding: 73848b8605Smrg continue 74848b8605Smrg 75848b8605Smrg if p.is_pointer(): 76848b8605Smrg cast = "(const void *) " 77848b8605Smrg else: 78848b8605Smrg cast = "" 79848b8605Smrg 80848b8605Smrg t_string = t_string + comma + p.format_string() 81848b8605Smrg p_string = p_string + comma + p.name 82848b8605Smrg o_string = o_string + comma + cast + p.name 83848b8605Smrg comma = ", " 84848b8605Smrg 85848b8605Smrg silence += "%s(void) %s;" % (space, p.name); 86848b8605Smrg space = ' ' 87848b8605Smrg 88848b8605Smrg 89848b8605Smrg if f.return_type != 'void': 90848b8605Smrg dispatch = "RETURN_DISPATCH" 91848b8605Smrg else: 92848b8605Smrg dispatch = "DISPATCH" 93848b8605Smrg 94848b8605Smrg need_proto = False 95848b8605Smrg if not f.is_static_entry_point(name): 96848b8605Smrg need_proto = True 97848b8605Smrg elif self.es: 98848b8605Smrg cat, num = api.get_category_for_name(name) 99848b8605Smrg if (cat.startswith("es") or cat.startswith("GL_OES")): 100848b8605Smrg need_proto = True 101848b8605Smrg if need_proto: 102b8e80941Smrg print('%s %s KEYWORD2 NAME(%s)(%s);' % (keyword, f.return_type, n, f.get_parameter_string(name))) 103b8e80941Smrg print('') 104848b8605Smrg 105b8e80941Smrg print('%s %s KEYWORD2 NAME(%s)(%s)' % (keyword, f.return_type, n, f.get_parameter_string(name))) 106b8e80941Smrg print('{') 107848b8605Smrg if silence: 108b8e80941Smrg print(' %s' % (silence)) 109848b8605Smrg if p_string == "": 110b8e80941Smrg print(' %s(%s, (), (F, "gl%s();\\n"));' \ 111b8e80941Smrg % (dispatch, f.name, name)) 112848b8605Smrg else: 113b8e80941Smrg print(' %s(%s, (%s), (F, "gl%s(%s);\\n", %s));' \ 114b8e80941Smrg % (dispatch, f.name, p_string, name, t_string, o_string)) 115b8e80941Smrg print('}') 116b8e80941Smrg print('') 117848b8605Smrg return 118848b8605Smrg 119848b8605Smrg def printRealHeader(self): 120b8e80941Smrg print('') 121848b8605Smrg self.printVisibility( "HIDDEN", "hidden" ) 122b8e80941Smrg print(""" 123848b8605Smrg/* 124848b8605Smrg * This file is a template which generates the OpenGL API entry point 125848b8605Smrg * functions. It should be included by a .c file which first defines 126848b8605Smrg * the following macros: 127848b8605Smrg * KEYWORD1 - usually nothing, but might be __declspec(dllexport) on Win32 128848b8605Smrg * KEYWORD2 - usually nothing, but might be __stdcall on Win32 129848b8605Smrg * NAME(n) - builds the final function name (usually add "gl" prefix) 130848b8605Smrg * DISPATCH(func, args, msg) - code to do dispatch of named function. 131848b8605Smrg * msg is a printf-style debug message. 132848b8605Smrg * RETURN_DISPATCH(func, args, msg) - code to do dispatch with a return value 133848b8605Smrg * 134848b8605Smrg * Here is an example which generates the usual OpenGL functions: 135848b8605Smrg * #define KEYWORD1 136848b8605Smrg * #define KEYWORD2 137848b8605Smrg * #define NAME(func) gl##func 138b8e80941Smrg * #define DISPATCH(func, args, msg) \\ 139b8e80941Smrg * struct _glapi_table *dispatch = CurrentClientDispatch; \\ 140848b8605Smrg * (*dispatch->func) args 141b8e80941Smrg * #define RETURN DISPATCH(func, args, msg) \\ 142b8e80941Smrg * struct _glapi_table *dispatch = CurrentClientDispatch; \\ 143848b8605Smrg * return (*dispatch->func) args 144848b8605Smrg * 145848b8605Smrg */ 146848b8605Smrg 147848b8605Smrg 148848b8605Smrg#if defined( NAME ) 149848b8605Smrg#ifndef KEYWORD1 150848b8605Smrg#define KEYWORD1 151848b8605Smrg#endif 152848b8605Smrg 153848b8605Smrg#ifndef KEYWORD1_ALT 154848b8605Smrg#define KEYWORD1_ALT HIDDEN 155848b8605Smrg#endif 156848b8605Smrg 157848b8605Smrg#ifndef KEYWORD2 158848b8605Smrg#define KEYWORD2 159848b8605Smrg#endif 160848b8605Smrg 161848b8605Smrg#ifndef DISPATCH 162848b8605Smrg#error DISPATCH must be defined 163848b8605Smrg#endif 164848b8605Smrg 165848b8605Smrg#ifndef RETURN_DISPATCH 166848b8605Smrg#error RETURN_DISPATCH must be defined 167848b8605Smrg#endif 168848b8605Smrg 169b8e80941Smrg""") 170848b8605Smrg return 171848b8605Smrg 172848b8605Smrg 173848b8605Smrg 174848b8605Smrg def printInitDispatch(self, api): 175b8e80941Smrg print(""" 176848b8605Smrg#endif /* defined( NAME ) */ 177848b8605Smrg 178848b8605Smrg/* 179848b8605Smrg * This is how a dispatch table can be initialized with all the functions 180848b8605Smrg * we generated above. 181848b8605Smrg */ 182848b8605Smrg#ifdef DISPATCH_TABLE_NAME 183848b8605Smrg 184848b8605Smrg#ifndef TABLE_ENTRY 185848b8605Smrg#error TABLE_ENTRY must be defined 186848b8605Smrg#endif 187848b8605Smrg 188848b8605Smrg#ifdef _GLAPI_SKIP_NORMAL_ENTRY_POINTS 189848b8605Smrg#error _GLAPI_SKIP_NORMAL_ENTRY_POINTS must not be defined 190848b8605Smrg#endif 191848b8605Smrg 192b8e80941Smrg_glapi_proc DISPATCH_TABLE_NAME[] = {""") 193848b8605Smrg for f in api.functionIterateByOffset(): 194b8e80941Smrg print(' TABLE_ENTRY(%s),' % (f.dispatch_name())) 195848b8605Smrg 196b8e80941Smrg print(' /* A whole bunch of no-op functions. These might be called') 197b8e80941Smrg print(' * when someone tries to call a dynamically-registered') 198b8e80941Smrg print(' * extension function without a current rendering context.') 199b8e80941Smrg print(' */') 200848b8605Smrg for i in range(1, 100): 201b8e80941Smrg print(' TABLE_ENTRY(Unused),') 202848b8605Smrg 203b8e80941Smrg print('};') 204b8e80941Smrg print('#endif /* DISPATCH_TABLE_NAME */') 205b8e80941Smrg print('') 206848b8605Smrg return 207848b8605Smrg 208848b8605Smrg 209848b8605Smrg def printAliasedTable(self, api): 210b8e80941Smrg print(""" 211848b8605Smrg/* 212848b8605Smrg * This is just used to silence compiler warnings. 213848b8605Smrg * We list the functions which are not otherwise used. 214848b8605Smrg */ 215848b8605Smrg#ifdef UNUSED_TABLE_NAME 216b8e80941Smrg_glapi_proc UNUSED_TABLE_NAME[] = {""") 217848b8605Smrg 218848b8605Smrg normal_entries = [] 219848b8605Smrg proto_entries = [] 220848b8605Smrg for f in api.functionIterateByOffset(): 221848b8605Smrg normal_ents, proto_ents = self.classifyEntryPoints(f) 222848b8605Smrg 223848b8605Smrg # exclude f.name 224848b8605Smrg if f.name in normal_ents: 225848b8605Smrg normal_ents.remove(f.name) 226848b8605Smrg elif f.name in proto_ents: 227848b8605Smrg proto_ents.remove(f.name) 228848b8605Smrg 229848b8605Smrg normal_ents = [f.static_name(ent) for ent in normal_ents] 230848b8605Smrg proto_ents = [f.static_name(ent) for ent in proto_ents] 231848b8605Smrg 232848b8605Smrg normal_entries.extend(normal_ents) 233848b8605Smrg proto_entries.extend(proto_ents) 234848b8605Smrg 235b8e80941Smrg print('#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS') 236848b8605Smrg for ent in normal_entries: 237b8e80941Smrg print(' TABLE_ENTRY(%s),' % (ent)) 238b8e80941Smrg print('#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */') 239b8e80941Smrg print('#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS') 240848b8605Smrg for ent in proto_entries: 241b8e80941Smrg print(' TABLE_ENTRY(%s),' % (ent)) 242b8e80941Smrg print('#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */') 243848b8605Smrg 244b8e80941Smrg print('};') 245b8e80941Smrg print('#endif /*UNUSED_TABLE_NAME*/') 246b8e80941Smrg print('') 247848b8605Smrg return 248848b8605Smrg 249848b8605Smrg 250848b8605Smrg def classifyEntryPoints(self, func): 251848b8605Smrg normal_names = [] 252848b8605Smrg normal_stubs = [] 253848b8605Smrg proto_names = [] 254848b8605Smrg proto_stubs = [] 255848b8605Smrg # classify the entry points 256848b8605Smrg for name in func.entry_points: 257848b8605Smrg if func.has_different_protocol(name): 258848b8605Smrg if func.is_static_entry_point(name): 259848b8605Smrg proto_names.append(name) 260848b8605Smrg else: 261848b8605Smrg proto_stubs.append(name) 262848b8605Smrg else: 263848b8605Smrg if func.is_static_entry_point(name): 264848b8605Smrg normal_names.append(name) 265848b8605Smrg else: 266848b8605Smrg normal_stubs.append(name) 267848b8605Smrg # there can be at most one stub for a function 268848b8605Smrg if normal_stubs: 269848b8605Smrg normal_names.append(normal_stubs[0]) 270848b8605Smrg elif proto_stubs: 271848b8605Smrg proto_names.append(proto_stubs[0]) 272848b8605Smrg 273848b8605Smrg return (normal_names, proto_names) 274848b8605Smrg 275848b8605Smrg def printBody(self, api): 276848b8605Smrg normal_entry_points = [] 277848b8605Smrg proto_entry_points = [] 278848b8605Smrg for func in api.functionIterateByOffset(): 279848b8605Smrg normal_ents, proto_ents = self.classifyEntryPoints(func) 280848b8605Smrg normal_entry_points.append((func, normal_ents)) 281848b8605Smrg proto_entry_points.append((func, proto_ents)) 282848b8605Smrg 283b8e80941Smrg print('#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS') 284b8e80941Smrg print('') 285848b8605Smrg for func, ents in normal_entry_points: 286848b8605Smrg for ent in ents: 287848b8605Smrg self.printFunction(func, ent) 288b8e80941Smrg print('') 289b8e80941Smrg print('#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */') 290b8e80941Smrg print('') 291b8e80941Smrg print('/* these entry points might require different protocols */') 292b8e80941Smrg print('#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS') 293b8e80941Smrg print('') 294848b8605Smrg for func, ents in proto_entry_points: 295848b8605Smrg for ent in ents: 296848b8605Smrg self.printFunction(func, ent) 297b8e80941Smrg print('') 298b8e80941Smrg print('#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */') 299b8e80941Smrg print('') 300848b8605Smrg 301848b8605Smrg self.printInitDispatch(api) 302848b8605Smrg self.printAliasedTable(api) 303848b8605Smrg return 304848b8605Smrg 305848b8605Smrg 306b8e80941Smrgdef _parser(): 307b8e80941Smrg """Parser arguments and return a namespace.""" 308b8e80941Smrg parser = argparse.ArgumentParser() 309b8e80941Smrg parser.add_argument('-f', 310b8e80941Smrg metavar='<input file name>', 311b8e80941Smrg dest='filename', 312b8e80941Smrg default="gl_API.xml", 313b8e80941Smrg help="An XML file describing the API.") 314b8e80941Smrg parser.add_argument('-c', 315b8e80941Smrg action='store_true', 316b8e80941Smrg dest='es', 317b8e80941Smrg help="Enable OpenGL ES compatibility") 318b8e80941Smrg return parser.parse_args() 319848b8605Smrg 320848b8605Smrg 321b8e80941Smrgdef main(): 322b8e80941Smrg """Main function.""" 323b8e80941Smrg args = _parser() 324848b8605Smrg 325b8e80941Smrg api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory()) 326848b8605Smrg 327b8e80941Smrg printer = PrintGlOffsets(args.es) 328848b8605Smrg printer.Print(api) 329b8e80941Smrg 330b8e80941Smrg 331b8e80941Smrgif __name__ == '__main__': 332b8e80941Smrg main() 333