gl_apitemp.py revision 3464ebd5
1#!/usr/bin/env python 2 3# (C) Copyright IBM Corporation 2004, 2005 4# All Rights Reserved. 5# 6# Permission is hereby granted, free of charge, to any person obtaining a 7# copy of this software and associated documentation files (the "Software"), 8# to deal in the Software without restriction, including without limitation 9# on the rights to use, copy, modify, merge, publish, distribute, sub 10# license, and/or sell copies of the Software, and to permit persons to whom 11# the Software is furnished to do so, subject to the following conditions: 12# 13# The above copyright notice and this permission notice (including the next 14# paragraph) shall be included in all copies or substantial portions of the 15# Software. 16# 17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 20# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23# IN THE SOFTWARE. 24# 25# Authors: 26# Ian Romanick <idr@us.ibm.com> 27 28import gl_XML, glX_XML 29import license 30import sys, getopt 31 32class PrintGlOffsets(gl_XML.gl_print_base): 33 def __init__(self, es=False): 34 gl_XML.gl_print_base.__init__(self) 35 36 self.name = "gl_apitemp.py (from Mesa)" 37 self.license = license.bsd_license_template % ( \ 38"""Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 39(C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM") 40 41 self.es = es 42 43 self.undef_list.append( "KEYWORD1" ) 44 self.undef_list.append( "KEYWORD1_ALT" ) 45 self.undef_list.append( "KEYWORD2" ) 46 self.undef_list.append( "NAME" ) 47 self.undef_list.append( "DISPATCH" ) 48 self.undef_list.append( "RETURN_DISPATCH" ) 49 self.undef_list.append( "DISPATCH_TABLE_NAME" ) 50 self.undef_list.append( "UNUSED_TABLE_NAME" ) 51 self.undef_list.append( "TABLE_ENTRY" ) 52 53 54 def printFunction(self, f, name): 55 p_string = "" 56 o_string = "" 57 t_string = "" 58 comma = "" 59 60 if f.is_static_entry_point(name): 61 keyword = "KEYWORD1" 62 else: 63 keyword = "KEYWORD1_ALT" 64 65 n = f.static_name(name) 66 67 for p in f.parameterIterator(): 68 if p.is_padding: 69 continue 70 71 if p.is_pointer(): 72 cast = "(const void *) " 73 else: 74 cast = "" 75 76 t_string = t_string + comma + p.format_string() 77 p_string = p_string + comma + p.name 78 o_string = o_string + comma + cast + p.name 79 comma = ", " 80 81 82 if f.return_type != 'void': 83 dispatch = "RETURN_DISPATCH" 84 else: 85 dispatch = "DISPATCH" 86 87 need_proto = False 88 if not f.is_static_entry_point(name): 89 need_proto = True 90 elif self.es: 91 cat, num = api.get_category_for_name(name) 92 if (cat.startswith("es") or cat.startswith("GL_OES")): 93 need_proto = True 94 if need_proto: 95 print '%s %s KEYWORD2 NAME(%s)(%s);' % (keyword, f.return_type, n, f.get_parameter_string(name)) 96 print '' 97 98 print '%s %s KEYWORD2 NAME(%s)(%s)' % (keyword, f.return_type, n, f.get_parameter_string(name)) 99 print '{' 100 if p_string == "": 101 print ' %s(%s, (), (F, "gl%s();\\n"));' \ 102 % (dispatch, f.name, name) 103 else: 104 print ' %s(%s, (%s), (F, "gl%s(%s);\\n", %s));' \ 105 % (dispatch, f.name, p_string, name, t_string, o_string) 106 print '}' 107 print '' 108 return 109 110 def printRealHeader(self): 111 print '' 112 self.printVisibility( "HIDDEN", "hidden" ) 113 print """ 114/* 115 * This file is a template which generates the OpenGL API entry point 116 * functions. It should be included by a .c file which first defines 117 * the following macros: 118 * KEYWORD1 - usually nothing, but might be __declspec(dllexport) on Win32 119 * KEYWORD2 - usually nothing, but might be __stdcall on Win32 120 * NAME(n) - builds the final function name (usually add "gl" prefix) 121 * DISPATCH(func, args, msg) - code to do dispatch of named function. 122 * msg is a printf-style debug message. 123 * RETURN_DISPATCH(func, args, msg) - code to do dispatch with a return value 124 * 125 * Here is an example which generates the usual OpenGL functions: 126 * #define KEYWORD1 127 * #define KEYWORD2 128 * #define NAME(func) gl##func 129 * #define DISPATCH(func, args, msg) \\ 130 * struct _glapi_table *dispatch = CurrentDispatch; \\ 131 * (*dispatch->func) args 132 * #define RETURN DISPATCH(func, args, msg) \\ 133 * struct _glapi_table *dispatch = CurrentDispatch; \\ 134 * return (*dispatch->func) args 135 * 136 */ 137 138 139#if defined( NAME ) 140#ifndef KEYWORD1 141#define KEYWORD1 142#endif 143 144#ifndef KEYWORD1_ALT 145#define KEYWORD1_ALT HIDDEN 146#endif 147 148#ifndef KEYWORD2 149#define KEYWORD2 150#endif 151 152#ifndef DISPATCH 153#error DISPATCH must be defined 154#endif 155 156#ifndef RETURN_DISPATCH 157#error RETURN_DISPATCH must be defined 158#endif 159 160""" 161 return 162 163 164 165 def printInitDispatch(self, api): 166 print """ 167#endif /* defined( NAME ) */ 168 169/* 170 * This is how a dispatch table can be initialized with all the functions 171 * we generated above. 172 */ 173#ifdef DISPATCH_TABLE_NAME 174 175#ifndef TABLE_ENTRY 176#error TABLE_ENTRY must be defined 177#endif 178 179#ifdef _GLAPI_SKIP_NORMAL_ENTRY_POINTS 180#error _GLAPI_SKIP_NORMAL_ENTRY_POINTS must not be defined 181#endif 182 183_glapi_proc DISPATCH_TABLE_NAME[] = {""" 184 for f in api.functionIterateByOffset(): 185 print ' TABLE_ENTRY(%s),' % (f.dispatch_name()) 186 187 print ' /* A whole bunch of no-op functions. These might be called' 188 print ' * when someone tries to call a dynamically-registered' 189 print ' * extension function without a current rendering context.' 190 print ' */' 191 for i in range(1, 100): 192 print ' TABLE_ENTRY(Unused),' 193 194 print '};' 195 print '#endif /* DISPATCH_TABLE_NAME */' 196 print '' 197 return 198 199 200 def printAliasedTable(self, api): 201 print """ 202/* 203 * This is just used to silence compiler warnings. 204 * We list the functions which are not otherwise used. 205 */ 206#ifdef UNUSED_TABLE_NAME 207_glapi_proc UNUSED_TABLE_NAME[] = {""" 208 209 normal_entries = [] 210 proto_entries = [] 211 for f in api.functionIterateByOffset(): 212 normal_ents, proto_ents = self.classifyEntryPoints(f) 213 214 # exclude f.name 215 if f.name in normal_ents: 216 normal_ents.remove(f.name) 217 elif f.name in proto_ents: 218 proto_ents.remove(f.name) 219 220 normal_ents = [f.static_name(ent) for ent in normal_ents] 221 proto_ents = [f.static_name(ent) for ent in proto_ents] 222 223 normal_entries.extend(normal_ents) 224 proto_entries.extend(proto_ents) 225 226 print '#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS' 227 for ent in normal_entries: 228 print ' TABLE_ENTRY(%s),' % (ent) 229 print '#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */' 230 print '#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS' 231 for ent in proto_entries: 232 print ' TABLE_ENTRY(%s),' % (ent) 233 print '#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */' 234 235 print '};' 236 print '#endif /*UNUSED_TABLE_NAME*/' 237 print '' 238 return 239 240 241 def classifyEntryPoints(self, func): 242 normal_names = [] 243 normal_stubs = [] 244 proto_names = [] 245 proto_stubs = [] 246 # classify the entry points 247 for name in func.entry_points: 248 if func.has_different_protocol(name): 249 if func.is_static_entry_point(name): 250 proto_names.append(name) 251 else: 252 proto_stubs.append(name) 253 else: 254 if func.is_static_entry_point(name): 255 normal_names.append(name) 256 else: 257 normal_stubs.append(name) 258 # there can be at most one stub for a function 259 if normal_stubs: 260 normal_names.append(normal_stubs[0]) 261 elif proto_stubs: 262 proto_names.append(proto_stubs[0]) 263 264 return (normal_names, proto_names) 265 266 def printBody(self, api): 267 normal_entry_points = [] 268 proto_entry_points = [] 269 for func in api.functionIterateByOffset(): 270 normal_ents, proto_ents = self.classifyEntryPoints(func) 271 normal_entry_points.append((func, normal_ents)) 272 proto_entry_points.append((func, proto_ents)) 273 274 print '#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS' 275 print '' 276 for func, ents in normal_entry_points: 277 for ent in ents: 278 self.printFunction(func, ent) 279 print '' 280 print '#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */' 281 print '' 282 print '/* these entry points might require different protocols */' 283 print '#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS' 284 print '' 285 for func, ents in proto_entry_points: 286 for ent in ents: 287 self.printFunction(func, ent) 288 print '' 289 print '#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */' 290 print '' 291 292 self.printInitDispatch(api) 293 self.printAliasedTable(api) 294 return 295 296 297def show_usage(): 298 print "Usage: %s [-f input_file_name] [-c]" % sys.argv[0] 299 print "-c Enable compatibility with OpenGL ES." 300 sys.exit(1) 301 302if __name__ == '__main__': 303 file_name = "gl_API.xml" 304 305 try: 306 (args, trail) = getopt.getopt(sys.argv[1:], "f:c") 307 except Exception,e: 308 show_usage() 309 310 es = False 311 for (arg,val) in args: 312 if arg == "-f": 313 file_name = val 314 elif arg == "-c": 315 es = True 316 317 api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory()) 318 319 printer = PrintGlOffsets(es) 320 printer.Print(api) 321