Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5563 | serge | 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 |
||
27 | |||
28 | import gl_XML, glX_XML |
||
29 | import license |
||
30 | import sys, getopt |
||
31 | |||
32 | class 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 | silence = '' |
||
68 | space = '' |
||
69 | for p in f.parameterIterator(name): |
||
70 | if p.is_padding: |
||
71 | continue |
||
72 | |||
73 | if p.is_pointer(): |
||
74 | cast = "(const void *) " |
||
75 | else: |
||
76 | cast = "" |
||
77 | |||
78 | t_string = t_string + comma + p.format_string() |
||
79 | p_string = p_string + comma + p.name |
||
80 | o_string = o_string + comma + cast + p.name |
||
81 | comma = ", " |
||
82 | |||
83 | silence += "%s(void) %s;" % (space, p.name); |
||
84 | space = ' ' |
||
85 | |||
86 | |||
87 | if f.return_type != 'void': |
||
88 | dispatch = "RETURN_DISPATCH" |
||
89 | else: |
||
90 | dispatch = "DISPATCH" |
||
91 | |||
92 | need_proto = False |
||
93 | if not f.is_static_entry_point(name): |
||
94 | need_proto = True |
||
95 | elif self.es: |
||
96 | cat, num = api.get_category_for_name(name) |
||
97 | if (cat.startswith("es") or cat.startswith("GL_OES")): |
||
98 | need_proto = True |
||
99 | if need_proto: |
||
100 | print '%s %s KEYWORD2 NAME(%s)(%s);' % (keyword, f.return_type, n, f.get_parameter_string(name)) |
||
101 | print '' |
||
102 | |||
103 | print '%s %s KEYWORD2 NAME(%s)(%s)' % (keyword, f.return_type, n, f.get_parameter_string(name)) |
||
104 | print '{' |
||
105 | if silence: |
||
106 | print ' %s' % (silence) |
||
107 | if p_string == "": |
||
108 | print ' %s(%s, (), (F, "gl%s();\\n"));' \ |
||
109 | % (dispatch, f.name, name) |
||
110 | else: |
||
111 | print ' %s(%s, (%s), (F, "gl%s(%s);\\n", %s));' \ |
||
112 | % (dispatch, f.name, p_string, name, t_string, o_string) |
||
113 | print '}' |
||
114 | print '' |
||
115 | return |
||
116 | |||
117 | def printRealHeader(self): |
||
118 | print '' |
||
119 | self.printVisibility( "HIDDEN", "hidden" ) |
||
120 | print """ |
||
121 | /* |
||
122 | * This file is a template which generates the OpenGL API entry point |
||
123 | * functions. It should be included by a .c file which first defines |
||
124 | * the following macros: |
||
125 | * KEYWORD1 - usually nothing, but might be __declspec(dllexport) on Win32 |
||
126 | * KEYWORD2 - usually nothing, but might be __stdcall on Win32 |
||
127 | * NAME(n) - builds the final function name (usually add "gl" prefix) |
||
128 | * DISPATCH(func, args, msg) - code to do dispatch of named function. |
||
129 | * msg is a printf-style debug message. |
||
130 | * RETURN_DISPATCH(func, args, msg) - code to do dispatch with a return value |
||
131 | * |
||
132 | * Here is an example which generates the usual OpenGL functions: |
||
133 | * #define KEYWORD1 |
||
134 | * #define KEYWORD2 |
||
135 | * #define NAME(func) gl##func |
||
136 | * #define DISPATCH(func, args, msg) \\ |
||
137 | * struct _glapi_table *dispatch = CurrentDispatch; \\ |
||
138 | * (*dispatch->func) args |
||
139 | * #define RETURN DISPATCH(func, args, msg) \\ |
||
140 | * struct _glapi_table *dispatch = CurrentDispatch; \\ |
||
141 | * return (*dispatch->func) args |
||
142 | * |
||
143 | */ |
||
144 | |||
145 | |||
146 | #if defined( NAME ) |
||
147 | #ifndef KEYWORD1 |
||
148 | #define KEYWORD1 |
||
149 | #endif |
||
150 | |||
151 | #ifndef KEYWORD1_ALT |
||
152 | #define KEYWORD1_ALT HIDDEN |
||
153 | #endif |
||
154 | |||
155 | #ifndef KEYWORD2 |
||
156 | #define KEYWORD2 |
||
157 | #endif |
||
158 | |||
159 | #ifndef DISPATCH |
||
160 | #error DISPATCH must be defined |
||
161 | #endif |
||
162 | |||
163 | #ifndef RETURN_DISPATCH |
||
164 | #error RETURN_DISPATCH must be defined |
||
165 | #endif |
||
166 | |||
167 | """ |
||
168 | return |
||
169 | |||
170 | |||
171 | |||
172 | def printInitDispatch(self, api): |
||
173 | print """ |
||
174 | #endif /* defined( NAME ) */ |
||
175 | |||
176 | /* |
||
177 | * This is how a dispatch table can be initialized with all the functions |
||
178 | * we generated above. |
||
179 | */ |
||
180 | #ifdef DISPATCH_TABLE_NAME |
||
181 | |||
182 | #ifndef TABLE_ENTRY |
||
183 | #error TABLE_ENTRY must be defined |
||
184 | #endif |
||
185 | |||
186 | #ifdef _GLAPI_SKIP_NORMAL_ENTRY_POINTS |
||
187 | #error _GLAPI_SKIP_NORMAL_ENTRY_POINTS must not be defined |
||
188 | #endif |
||
189 | |||
190 | _glapi_proc DISPATCH_TABLE_NAME[] = {""" |
||
191 | for f in api.functionIterateByOffset(): |
||
192 | print ' TABLE_ENTRY(%s),' % (f.dispatch_name()) |
||
193 | |||
194 | print ' /* A whole bunch of no-op functions. These might be called' |
||
195 | print ' * when someone tries to call a dynamically-registered' |
||
196 | print ' * extension function without a current rendering context.' |
||
197 | print ' */' |
||
198 | for i in range(1, 100): |
||
199 | print ' TABLE_ENTRY(Unused),' |
||
200 | |||
201 | print '};' |
||
202 | print '#endif /* DISPATCH_TABLE_NAME */' |
||
203 | print '' |
||
204 | return |
||
205 | |||
206 | |||
207 | def printAliasedTable(self, api): |
||
208 | print """ |
||
209 | /* |
||
210 | * This is just used to silence compiler warnings. |
||
211 | * We list the functions which are not otherwise used. |
||
212 | */ |
||
213 | #ifdef UNUSED_TABLE_NAME |
||
214 | _glapi_proc UNUSED_TABLE_NAME[] = {""" |
||
215 | |||
216 | normal_entries = [] |
||
217 | proto_entries = [] |
||
218 | for f in api.functionIterateByOffset(): |
||
219 | normal_ents, proto_ents = self.classifyEntryPoints(f) |
||
220 | |||
221 | # exclude f.name |
||
222 | if f.name in normal_ents: |
||
223 | normal_ents.remove(f.name) |
||
224 | elif f.name in proto_ents: |
||
225 | proto_ents.remove(f.name) |
||
226 | |||
227 | normal_ents = [f.static_name(ent) for ent in normal_ents] |
||
228 | proto_ents = [f.static_name(ent) for ent in proto_ents] |
||
229 | |||
230 | normal_entries.extend(normal_ents) |
||
231 | proto_entries.extend(proto_ents) |
||
232 | |||
233 | print '#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS' |
||
234 | for ent in normal_entries: |
||
235 | print ' TABLE_ENTRY(%s),' % (ent) |
||
236 | print '#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */' |
||
237 | print '#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS' |
||
238 | for ent in proto_entries: |
||
239 | print ' TABLE_ENTRY(%s),' % (ent) |
||
240 | print '#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */' |
||
241 | |||
242 | print '};' |
||
243 | print '#endif /*UNUSED_TABLE_NAME*/' |
||
244 | print '' |
||
245 | return |
||
246 | |||
247 | |||
248 | def classifyEntryPoints(self, func): |
||
249 | normal_names = [] |
||
250 | normal_stubs = [] |
||
251 | proto_names = [] |
||
252 | proto_stubs = [] |
||
253 | # classify the entry points |
||
254 | for name in func.entry_points: |
||
255 | if func.has_different_protocol(name): |
||
256 | if func.is_static_entry_point(name): |
||
257 | proto_names.append(name) |
||
258 | else: |
||
259 | proto_stubs.append(name) |
||
260 | else: |
||
261 | if func.is_static_entry_point(name): |
||
262 | normal_names.append(name) |
||
263 | else: |
||
264 | normal_stubs.append(name) |
||
265 | # there can be at most one stub for a function |
||
266 | if normal_stubs: |
||
267 | normal_names.append(normal_stubs[0]) |
||
268 | elif proto_stubs: |
||
269 | proto_names.append(proto_stubs[0]) |
||
270 | |||
271 | return (normal_names, proto_names) |
||
272 | |||
273 | def printBody(self, api): |
||
274 | normal_entry_points = [] |
||
275 | proto_entry_points = [] |
||
276 | for func in api.functionIterateByOffset(): |
||
277 | normal_ents, proto_ents = self.classifyEntryPoints(func) |
||
278 | normal_entry_points.append((func, normal_ents)) |
||
279 | proto_entry_points.append((func, proto_ents)) |
||
280 | |||
281 | print '#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS' |
||
282 | print '' |
||
283 | for func, ents in normal_entry_points: |
||
284 | for ent in ents: |
||
285 | self.printFunction(func, ent) |
||
286 | print '' |
||
287 | print '#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */' |
||
288 | print '' |
||
289 | print '/* these entry points might require different protocols */' |
||
290 | print '#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS' |
||
291 | print '' |
||
292 | for func, ents in proto_entry_points: |
||
293 | for ent in ents: |
||
294 | self.printFunction(func, ent) |
||
295 | print '' |
||
296 | print '#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */' |
||
297 | print '' |
||
298 | |||
299 | self.printInitDispatch(api) |
||
300 | self.printAliasedTable(api) |
||
301 | return |
||
302 | |||
303 | |||
304 | def show_usage(): |
||
305 | print "Usage: %s [-f input_file_name] [-c]" % sys.argv[0] |
||
306 | print "-c Enable compatibility with OpenGL ES." |
||
307 | sys.exit(1) |
||
308 | |||
309 | if __name__ == '__main__': |
||
310 | file_name = "gl_API.xml" |
||
311 | |||
312 | try: |
||
313 | (args, trail) = getopt.getopt(sys.argv[1:], "f:c") |
||
314 | except Exception,e: |
||
315 | show_usage() |
||
316 | |||
317 | es = False |
||
318 | for (arg,val) in args: |
||
319 | if arg == "-f": |
||
320 | file_name = val |
||
321 | elif arg == "-c": |
||
322 | es = True |
||
323 | |||
324 | api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory()) |
||
325 | |||
326 | printer = PrintGlOffsets(es) |
||
327 | printer.Print(api) |