47be8c5b4af09b6441915a355fa6ce1d310796f6
[mesa.git] / src / mapi / mapi / mapi_abi.py
1 #!/usr/bin/env python
2
3 # Mesa 3-D graphics library
4 # Version: 7.9
5 #
6 # Copyright (C) 2010 LunarG Inc.
7 #
8 # Permission is hereby granted, free of charge, to any person obtaining a
9 # copy of this software and associated documentation files (the "Software"),
10 # to deal in the Software without restriction, including without limitation
11 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 # and/or sell copies of the Software, and to permit persons to whom the
13 # Software is furnished to do so, subject to the following conditions:
14 #
15 # The above copyright notice and this permission notice shall be included
16 # in all copies or substantial portions of the Software.
17 #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 # DEALINGS IN THE SOFTWARE.
25 #
26 # Authors:
27 # Chia-I Wu <olv@lunarg.com>
28
29 import sys
30 import re
31 from optparse import OptionParser
32
33 # number of dynamic entries
34 ABI_NUM_DYNAMIC_ENTRIES = 256
35
36 class ABIEntry(object):
37 """Represent an ABI entry."""
38
39 _match_c_param = re.compile(
40 '^(?P<type>[\w\s*]+?)(?P<name>\w+)(\[(?P<array>\d+)\])?$')
41
42 def __init__(self, cols, attrs):
43 self._parse(cols)
44
45 self.slot = attrs['slot']
46 self.hidden = attrs['hidden']
47 self.alias = attrs['alias']
48 self.handcode = attrs['handcode']
49
50 def c_prototype(self):
51 return '%s %s(%s)' % (self.c_return(), self.name, self.c_params())
52
53 def c_return(self):
54 ret = self.ret
55 if not ret:
56 ret = 'void'
57
58 return ret
59
60 def c_params(self):
61 """Return the parameter list used in the entry prototype."""
62 c_params = []
63 for t, n, a in self.params:
64 sep = '' if t.endswith('*') else ' '
65 arr = '[%d]' % a if a else ''
66 c_params.append(t + sep + n + arr)
67 if not c_params:
68 c_params.append('void')
69
70 return ", ".join(c_params)
71
72 def c_args(self):
73 """Return the argument list used in the entry invocation."""
74 c_args = []
75 for t, n, a in self.params:
76 c_args.append(n)
77
78 return ", ".join(c_args)
79
80 def _parse(self, cols):
81 ret = cols.pop(0)
82 if ret == 'void':
83 ret = None
84
85 name = cols.pop(0)
86
87 params = []
88 if not cols:
89 raise Exception(cols)
90 elif len(cols) == 1 and cols[0] == 'void':
91 pass
92 else:
93 for val in cols:
94 params.append(self._parse_param(val))
95
96 self.ret = ret
97 self.name = name
98 self.params = params
99
100 def _parse_param(self, c_param):
101 m = self._match_c_param.match(c_param)
102 if not m:
103 raise Exception('unrecognized param ' + c_param)
104
105 c_type = m.group('type').strip()
106 c_name = m.group('name')
107 c_array = m.group('array')
108 c_array = int(c_array) if c_array else 0
109
110 return (c_type, c_name, c_array)
111
112 def __str__(self):
113 return self.c_prototype()
114
115 def __cmp__(self, other):
116 # compare slot, alias, and then name
117 res = cmp(self.slot, other.slot)
118 if not res:
119 if not self.alias:
120 res = -1
121 elif not other.alias:
122 res = 1
123
124 if not res:
125 res = cmp(self.name, other.name)
126
127 return res
128
129 def abi_parse_xml(xml):
130 """Parse a GLAPI XML file for ABI entries."""
131 import os
132 GLAPI = "./%s/../glapi/gen" % (os.path.dirname(sys.argv[0]))
133 sys.path.append(GLAPI)
134 import gl_XML, glX_XML
135
136 api = gl_XML.parse_GL_API(xml, glX_XML.glx_item_factory())
137
138 entry_dict = {}
139 for func in api.functionIterateByOffset():
140 # make sure func.name appear first
141 entry_points = func.entry_points[:]
142 entry_points.remove(func.name)
143 entry_points.insert(0, func.name)
144
145 for name in entry_points:
146 attrs = {
147 'slot': func.offset,
148 'hidden': not func.is_static_entry_point(name),
149 'alias': None if name == func.name else func.name,
150 'handcode': bool(func.has_different_protocol(name)),
151 }
152
153 # post-process attrs
154 if attrs['alias']:
155 try:
156 alias = entry_dict[attrs['alias']]
157 except KeyError:
158 raise Exception('failed to alias %s' % attrs['alias'])
159 if alias.alias:
160 raise Exception('recursive alias %s' % ent.name)
161 attrs['alias'] = alias
162 if attrs['handcode']:
163 attrs['handcode'] = func.static_glx_name(name)
164 else:
165 attrs['handcode'] = None
166
167 if entry_dict.has_key(name):
168 raise Exception('%s is duplicated' % (name))
169
170 cols = []
171 cols.append(func.return_type)
172 cols.append(name)
173 params = func.get_parameter_string(name)
174 cols.extend([p.strip() for p in params.split(',')])
175
176 ent = ABIEntry(cols, attrs)
177 entry_dict[ent.name] = ent
178
179 entries = entry_dict.values()
180 entries.sort()
181
182 return entries
183
184 def abi_parse_line(line):
185 cols = [col.strip() for col in line.split(',')]
186
187 attrs = {
188 'slot': -1,
189 'hidden': False,
190 'alias': None,
191 'handcode': None,
192 }
193
194 # extract attributes from the first column
195 vals = cols[0].split(':')
196 while len(vals) > 1:
197 val = vals.pop(0)
198 if val.startswith('slot='):
199 attrs['slot'] = int(val[5:])
200 elif val == 'hidden':
201 attrs['hidden'] = True
202 elif val.startswith('alias='):
203 attrs['alias'] = val[6:]
204 elif val.startswith('handcode='):
205 attrs['handcode'] = val[9:]
206 elif not val:
207 pass
208 else:
209 raise Exception('unknown attribute %s' % val)
210 cols[0] = vals[0]
211
212 return (attrs, cols)
213
214 def abi_parse(filename):
215 """Parse a CSV file for ABI entries."""
216 fp = open(filename) if filename != '-' else sys.stdin
217 lines = [line.strip() for line in fp.readlines()
218 if not line.startswith('#') and line.strip()]
219
220 entry_dict = {}
221 next_slot = 0
222 for line in lines:
223 attrs, cols = abi_parse_line(line)
224
225 # post-process attributes
226 if attrs['alias']:
227 try:
228 alias = entry_dict[attrs['alias']]
229 except KeyError:
230 raise Exception('failed to alias %s' % attrs['alias'])
231 if alias.alias:
232 raise Exception('recursive alias %s' % ent.name)
233 slot = alias.slot
234 attrs['alias'] = alias
235 else:
236 slot = next_slot
237 next_slot += 1
238
239 if attrs['slot'] < 0:
240 attrs['slot'] = slot
241 elif attrs['slot'] != slot:
242 raise Exception('invalid slot in %s' % (line))
243
244 ent = ABIEntry(cols, attrs)
245 if entry_dict.has_key(ent.name):
246 raise Exception('%s is duplicated' % (ent.name))
247 entry_dict[ent.name] = ent
248
249 entries = entry_dict.values()
250 entries.sort()
251
252 return entries
253
254 def abi_sanity_check(entries):
255 if not entries:
256 return
257
258 all_names = []
259 last_slot = entries[-1].slot
260 i = 0
261 for slot in xrange(last_slot + 1):
262 if entries[i].slot != slot:
263 raise Exception('entries are not ordered by slots')
264 if entries[i].alias:
265 raise Exception('first entry of slot %d aliases %s'
266 % (slot, entries[i].alias.name))
267 handcode = None
268 while i < len(entries) and entries[i].slot == slot:
269 ent = entries[i]
270 if not handcode and ent.handcode:
271 handcode = ent.handcode
272 elif ent.handcode != handcode:
273 raise Exception('two aliases with handcode %s != %s',
274 ent.handcode, handcode)
275
276 if ent.name in all_names:
277 raise Exception('%s is duplicated' % (ent.name))
278 if ent.alias and ent.alias.name not in all_names:
279 raise Exception('failed to alias %s' % (ent.alias.name))
280 all_names.append(ent.name)
281 i += 1
282 if i < len(entries):
283 raise Exception('there are %d invalid entries' % (len(entries) - 1))
284
285 class ABIPrinter(object):
286 """MAPI Printer"""
287
288 def __init__(self, entries):
289 self.entries = entries
290
291 # sort entries by their names
292 self.entries_sorted_by_names = self.entries[:]
293 self.entries_sorted_by_names.sort(lambda x, y: cmp(x.name, y.name))
294
295 self.indent = ' ' * 3
296 self.noop_warn = 'noop_warn'
297 self.noop_generic = 'noop_generic'
298
299 self.api_defines = []
300 self.api_headers = ['"KHR/khrplatform.h"']
301 self.api_call = 'KHRONOS_APICALL'
302 self.api_entry = 'KHRONOS_APIENTRY'
303 self.api_attrs = 'KHRONOS_APIATTRIBUTES'
304
305 self.c_header = ''
306
307 self.lib_need_table_size = True
308 self.lib_need_noop_array = True
309 self.lib_need_stubs = True
310 self.lib_need_entries = True
311
312 def c_notice(self):
313 return '/* This file is automatically generated by mapi_abi.py. Do not modify. */'
314
315 def c_public_includes(self):
316 """Return includes of the client API headers."""
317 defines = ['#define ' + d for d in self.api_defines]
318 includes = ['#include ' + h for h in self.api_headers]
319 return "\n".join(defines + includes)
320
321 def need_entry_point(self, ent):
322 """Return True if an entry point is needed for the entry."""
323 # non-handcode hidden aliases may share the entry they alias
324 use_alias = (ent.hidden and ent.alias and not ent.handcode)
325 return not use_alias
326
327 def c_public_declarations(self, prefix):
328 """Return the declarations of public entry points."""
329 decls = []
330 for ent in self.entries:
331 if not self.need_entry_point(ent):
332 continue
333 export = self.api_call if not ent.hidden else ''
334 decls.append(self._c_decl(ent, prefix, True, export) + ';')
335
336 return "\n".join(decls)
337
338 def c_mapi_table(self):
339 """Return defines of the dispatch table size."""
340 num_static_entries = 0
341 for ent in self.entries:
342 if not ent.alias:
343 num_static_entries += 1
344
345 return ('#define MAPI_TABLE_NUM_STATIC %d\n' + \
346 '#define MAPI_TABLE_NUM_DYNAMIC %d') % (
347 num_static_entries, ABI_NUM_DYNAMIC_ENTRIES)
348
349 def c_mapi_table_initializer(self, prefix):
350 """Return the array initializer for mapi_table_fill."""
351 entries = [self._c_function(ent, prefix)
352 for ent in self.entries if not ent.alias]
353 pre = self.indent + '(mapi_proc) '
354 return pre + (',\n' + pre).join(entries)
355
356 def c_mapi_table_spec(self):
357 """Return the spec for mapi_init."""
358 specv1 = []
359 line = '"1'
360 for ent in self.entries:
361 if not ent.alias:
362 line += '\\0"\n'
363 specv1.append(line)
364 line = '"'
365 line += '%s\\0' % ent.name
366 line += '";'
367 specv1.append(line)
368
369 return self.indent + self.indent.join(specv1)
370
371 def _c_function(self, ent, prefix, mangle=False, stringify=False):
372 """Return the function name of an entry."""
373 formats = {
374 True: { True: '%s_STR(%s)', False: '%s(%s)' },
375 False: { True: '"%s%s"', False: '%s%s' },
376 }
377 fmt = formats[prefix.isupper()][stringify]
378 name = ent.name
379 if mangle and ent.hidden:
380 name = '_dispatch_stub_' + str(ent.slot)
381 return fmt % (prefix, name)
382
383 def _c_function_call(self, ent, prefix):
384 """Return the function name used for calling."""
385 if ent.handcode:
386 # _c_function does not handle this case
387 formats = { True: '%s(%s)', False: '%s%s' }
388 fmt = formats[prefix.isupper()]
389 name = fmt % (prefix, ent.handcode)
390 elif self.need_entry_point(ent):
391 name = self._c_function(ent, prefix, True)
392 else:
393 name = self._c_function(ent.alias, prefix, True)
394 return name
395
396 def _c_decl(self, ent, prefix, mangle=False, export=''):
397 """Return the C declaration for the entry."""
398 decl = '%s %s %s(%s)' % (ent.c_return(), self.api_entry,
399 self._c_function(ent, prefix, mangle), ent.c_params())
400 if export:
401 decl = export + ' ' + decl
402 if self.api_attrs:
403 decl += ' ' + self.api_attrs
404
405 return decl
406
407 def _c_cast(self, ent):
408 """Return the C cast for the entry."""
409 cast = '%s (%s *)(%s)' % (
410 ent.c_return(), self.api_entry, ent.c_params())
411
412 return cast
413
414 def c_private_declarations(self, prefix):
415 """Return the declarations of private functions."""
416 decls = [self._c_decl(ent, prefix) + ';'
417 for ent in self.entries if not ent.alias]
418
419 return "\n".join(decls)
420
421 def c_public_dispatches(self, prefix):
422 """Return the public dispatch functions."""
423 dispatches = []
424 for ent in self.entries:
425 if not self.need_entry_point(ent):
426 continue
427
428 export = self.api_call if not ent.hidden else ''
429
430 proto = self._c_decl(ent, prefix, True, export)
431 cast = self._c_cast(ent)
432
433 ret = ''
434 if ent.ret:
435 ret = 'return '
436 stmt1 = self.indent
437 stmt1 += 'const struct mapi_table *_tbl = u_current_get();'
438 stmt2 = self.indent
439 stmt2 += 'mapi_func _func = ((const mapi_func *) _tbl)[%d];' % (
440 ent.slot)
441 stmt3 = self.indent
442 stmt3 += '%s((%s) _func)(%s);' % (ret, cast, ent.c_args())
443
444 disp = '%s\n{\n%s\n%s\n%s\n}' % (proto, stmt1, stmt2, stmt3)
445
446 if ent.handcode:
447 disp = '#if 0\n' + disp + '\n#endif'
448
449 dispatches.append(disp)
450
451 return '\n\n'.join(dispatches)
452
453 def c_public_initializer(self, prefix):
454 """Return the initializer for public dispatch functions."""
455 names = []
456 for ent in self.entries:
457 if ent.alias:
458 continue
459
460 name = '%s(mapi_func) %s' % (self.indent,
461 self._c_function_call(ent, prefix))
462 names.append(name)
463
464 return ',\n'.join(names)
465
466 def c_stub_string_pool(self):
467 """Return the string pool for use by stubs."""
468 # sort entries by their names
469 sorted_entries = self.entries[:]
470 sorted_entries.sort(lambda x, y: cmp(x.name, y.name))
471
472 pool = []
473 offsets = {}
474 count = 0
475 for ent in sorted_entries:
476 offsets[ent] = count
477 pool.append('%s' % (ent.name))
478 count += len(ent.name) + 1
479
480 pool_str = self.indent + '"' + \
481 ('\\0"\n' + self.indent + '"').join(pool) + '";'
482 return (pool_str, offsets)
483
484 def c_stub_initializer(self, prefix, pool_offsets):
485 """Return the initializer for struct mapi_stub array."""
486 stubs = []
487 for ent in self.entries_sorted_by_names:
488 stubs.append('%s{ (void *) %d, %d, NULL }' % (
489 self.indent, pool_offsets[ent], ent.slot))
490
491 return ',\n'.join(stubs)
492
493 def c_noop_functions(self, prefix, warn_prefix):
494 """Return the noop functions."""
495 noops = []
496 for ent in self.entries:
497 if ent.alias:
498 continue
499
500 proto = self._c_decl(ent, prefix, False, 'static')
501
502 stmt1 = self.indent + '%s(%s);' % (self.noop_warn,
503 self._c_function(ent, warn_prefix, False, True))
504
505 if ent.ret:
506 stmt2 = self.indent + 'return (%s) 0;' % (ent.ret)
507 noop = '%s\n{\n%s\n%s\n}' % (proto, stmt1, stmt2)
508 else:
509 noop = '%s\n{\n%s\n}' % (proto, stmt1)
510
511 noops.append(noop)
512
513 return '\n\n'.join(noops)
514
515 def c_noop_initializer(self, prefix, use_generic):
516 """Return an initializer for the noop dispatch table."""
517 entries = [self._c_function(ent, prefix)
518 for ent in self.entries if not ent.alias]
519 if use_generic:
520 entries = [self.noop_generic] * len(entries)
521
522 entries.extend([self.noop_generic] * ABI_NUM_DYNAMIC_ENTRIES)
523
524 pre = self.indent + '(mapi_func) '
525 return pre + (',\n' + pre).join(entries)
526
527 def c_asm_gcc(self, prefix):
528 asm = []
529
530 asm.append('__asm__(')
531 for ent in self.entries:
532 if not self.need_entry_point(ent):
533 continue
534
535 name = self._c_function(ent, prefix, True, True)
536
537 if ent.handcode:
538 asm.append('#if 0')
539
540 if ent.hidden:
541 asm.append('".hidden "%s"\\n"' % (name))
542
543 if ent.alias:
544 asm.append('".globl "%s"\\n"' % (name))
545 asm.append('".set "%s", "%s"\\n"' % (name,
546 self._c_function(ent.alias, prefix, True, True)))
547 else:
548 asm.append('STUB_ASM_ENTRY(%s)"\\n"' % (name))
549 asm.append('"\\t"STUB_ASM_CODE("%d")"\\n"' % (ent.slot))
550
551 if ent.handcode:
552 asm.append('#endif')
553 asm.append('')
554 asm.append(');')
555
556 return "\n".join(asm)
557
558 def output_for_lib(self):
559 print self.c_notice()
560
561 if self.c_header:
562 print
563 print self.c_header
564
565 print
566 print '#ifdef MAPI_TMP_DEFINES'
567 print self.c_public_includes()
568 print
569 print self.c_public_declarations(self.prefix_lib)
570 print '#undef MAPI_TMP_DEFINES'
571 print '#endif /* MAPI_TMP_DEFINES */'
572
573 if self.lib_need_table_size:
574 print
575 print '#ifdef MAPI_TMP_TABLE'
576 print self.c_mapi_table()
577 print '#undef MAPI_TMP_TABLE'
578 print '#endif /* MAPI_TMP_TABLE */'
579
580 if self.lib_need_noop_array:
581 print
582 print '#ifdef MAPI_TMP_NOOP_ARRAY'
583 print '#ifdef DEBUG'
584 print
585 print self.c_noop_functions(self.prefix_noop, self.prefix_warn)
586 print
587 print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
588 print self.c_noop_initializer(self.prefix_noop, False)
589 print '};'
590 print
591 print '#else /* DEBUG */'
592 print
593 print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
594 print self.c_noop_initializer(self.prefix_noop, True)
595 print '};'
596 print
597 print '#endif /* DEBUG */'
598 print '#undef MAPI_TMP_NOOP_ARRAY'
599 print '#endif /* MAPI_TMP_NOOP_ARRAY */'
600
601 if self.lib_need_stubs:
602 pool, pool_offsets = self.c_stub_string_pool()
603 print
604 print '#ifdef MAPI_TMP_PUBLIC_STUBS'
605 print 'static const char public_string_pool[] ='
606 print pool
607 print
608 print 'static const struct mapi_stub public_stubs[] = {'
609 print self.c_stub_initializer(self.prefix_lib, pool_offsets)
610 print '};'
611 print '#undef MAPI_TMP_PUBLIC_STUBS'
612 print '#endif /* MAPI_TMP_PUBLIC_STUBS */'
613
614 if self.lib_need_entries:
615 print
616 print '#ifdef MAPI_TMP_PUBLIC_ENTRIES'
617 print self.c_public_dispatches(self.prefix_lib)
618 print
619 print 'static const mapi_func public_entries[] = {'
620 print self.c_public_initializer(self.prefix_lib)
621 print '};'
622 print '#undef MAPI_TMP_PUBLIC_ENTRIES'
623 print '#endif /* MAPI_TMP_PUBLIC_ENTRIES */'
624
625 print
626 print '#ifdef MAPI_TMP_STUB_ASM_GCC'
627 print self.c_asm_gcc(self.prefix_lib)
628 print '#undef MAPI_TMP_STUB_ASM_GCC'
629 print '#endif /* MAPI_TMP_STUB_ASM_GCC */'
630
631 def output_for_app(self):
632 print self.c_notice()
633 print
634 print self.c_private_declarations(self.prefix_app)
635 print
636 print '#ifdef API_TMP_DEFINE_SPEC'
637 print
638 print 'static const char %s_spec[] =' % (self.prefix_app)
639 print self.c_mapi_table_spec()
640 print
641 print 'static const mapi_proc %s_procs[] = {' % (self.prefix_app)
642 print self.c_mapi_table_initializer(self.prefix_app)
643 print '};'
644 print
645 print '#endif /* API_TMP_DEFINE_SPEC */'
646
647 class GLAPIPrinter(ABIPrinter):
648 """OpenGL API Printer"""
649
650 def __init__(self, entries, api=None):
651 api_entries = self._get_api_entries(entries, api)
652 super(GLAPIPrinter, self).__init__(api_entries)
653
654 self.api_defines = ['GL_GLEXT_PROTOTYPES']
655 self.api_headers = ['"GL/gl.h"', '"GL/glext.h"']
656 self.api_call = 'GLAPI'
657 self.api_entry = 'APIENTRY'
658 self.api_attrs = ''
659
660 self.prefix_lib = 'GLAPI_PREFIX'
661 self.prefix_app = '_mesa_'
662 self.prefix_noop = 'noop'
663 self.prefix_warn = self.prefix_lib
664
665 self.c_header = self._get_c_header()
666
667 def _get_api_entries(self, entries, api):
668 """Override the entry attributes according to API."""
669 import copy
670
671 # no override
672 if api is None:
673 return entries
674
675 api_entries = {}
676 for ent in entries:
677 ent = copy.copy(ent)
678
679 # override 'hidden' and 'handcode'
680 ent.hidden = ent.name not in api
681 ent.handcode = False
682 if ent.alias:
683 ent.alias = api_entries[ent.alias.name]
684
685 api_entries[ent.name] = ent
686
687 # sanity check
688 missed = [name for name in api if name not in api_entries]
689 if missed:
690 raise Exception('%s is missing' % str(missed))
691
692 entries = api_entries.values()
693 entries.sort()
694
695 return entries
696
697 def _get_c_header(self):
698 header = """#ifndef _GLAPI_TMP_H_
699 #define _GLAPI_TMP_H_
700 #ifdef USE_MGL_NAMESPACE
701 #define GLAPI_PREFIX(func) mgl##func
702 #define GLAPI_PREFIX_STR(func) "mgl"#func
703 #else
704 #define GLAPI_PREFIX(func) gl##func
705 #define GLAPI_PREFIX_STR(func) "gl"#func
706 #endif /* USE_MGL_NAMESPACE */
707
708 typedef int GLfixed;
709 typedef int GLclampx;
710 #endif /* _GLAPI_TMP_H_ */"""
711
712 return header
713
714 class ES1APIPrinter(GLAPIPrinter):
715 """OpenGL ES 1.x API Printer"""
716
717 def __init__(self, entries):
718 es1_api = [
719 # OpenGL ES 1.1
720 'ActiveTexture',
721 'AlphaFunc',
722 'AlphaFuncx',
723 'BindBuffer',
724 'BindTexture',
725 'BlendFunc',
726 'BufferData',
727 'BufferSubData',
728 'Clear',
729 'ClearColor',
730 'ClearColorx',
731 'ClearDepthf',
732 'ClearDepthx',
733 'ClearStencil',
734 'ClientActiveTexture',
735 'ClipPlanef',
736 'ClipPlanex',
737 'Color4f',
738 'Color4ub',
739 'Color4x',
740 'ColorMask',
741 'ColorPointer',
742 'CompressedTexImage2D',
743 'CompressedTexSubImage2D',
744 'CopyTexImage2D',
745 'CopyTexSubImage2D',
746 'CullFace',
747 'DeleteBuffers',
748 'DeleteTextures',
749 'DepthFunc',
750 'DepthMask',
751 'DepthRangef',
752 'DepthRangex',
753 'Disable',
754 'DisableClientState',
755 'DrawArrays',
756 'DrawElements',
757 'Enable',
758 'EnableClientState',
759 'Finish',
760 'Flush',
761 'Fogf',
762 'Fogfv',
763 'Fogx',
764 'Fogxv',
765 'FrontFace',
766 'Frustumf',
767 'Frustumx',
768 'GenBuffers',
769 'GenTextures',
770 'GetBooleanv',
771 'GetBufferParameteriv',
772 'GetClipPlanef',
773 'GetClipPlanex',
774 'GetError',
775 'GetFixedv',
776 'GetFloatv',
777 'GetIntegerv',
778 'GetLightfv',
779 'GetLightxv',
780 'GetMaterialfv',
781 'GetMaterialxv',
782 'GetPointerv',
783 'GetString',
784 'GetTexEnvfv',
785 'GetTexEnviv',
786 'GetTexEnvxv',
787 'GetTexParameterfv',
788 'GetTexParameteriv',
789 'GetTexParameterxv',
790 'Hint',
791 'IsBuffer',
792 'IsEnabled',
793 'IsTexture',
794 'Lightf',
795 'Lightfv',
796 'LightModelf',
797 'LightModelfv',
798 'LightModelx',
799 'LightModelxv',
800 'Lightx',
801 'Lightxv',
802 'LineWidth',
803 'LineWidthx',
804 'LoadIdentity',
805 'LoadMatrixf',
806 'LoadMatrixx',
807 'LogicOp',
808 'Materialf',
809 'Materialfv',
810 'Materialx',
811 'Materialxv',
812 'MatrixMode',
813 'MultiTexCoord4f',
814 'MultiTexCoord4x',
815 'MultMatrixf',
816 'MultMatrixx',
817 'Normal3f',
818 'Normal3x',
819 'NormalPointer',
820 'Orthof',
821 'Orthox',
822 'PixelStorei',
823 'PointParameterf',
824 'PointParameterfv',
825 'PointParameterx',
826 'PointParameterxv',
827 'PointSize',
828 'PointSizex',
829 'PolygonOffset',
830 'PolygonOffsetx',
831 'PopMatrix',
832 'PushMatrix',
833 'ReadPixels',
834 'Rotatef',
835 'Rotatex',
836 'SampleCoverage',
837 'SampleCoveragex',
838 'Scalef',
839 'Scalex',
840 'Scissor',
841 'ShadeModel',
842 'StencilFunc',
843 'StencilMask',
844 'StencilOp',
845 'TexCoordPointer',
846 'TexEnvf',
847 'TexEnvfv',
848 'TexEnvi',
849 'TexEnviv',
850 'TexEnvx',
851 'TexEnvxv',
852 'TexImage2D',
853 'TexParameterf',
854 'TexParameterfv',
855 'TexParameteri',
856 'TexParameteriv',
857 'TexParameterx',
858 'TexParameterxv',
859 'TexSubImage2D',
860 'Translatef',
861 'Translatex',
862 'VertexPointer',
863 'Viewport',
864 # GL_OES_EGL_image
865 'EGLImageTargetTexture2DOES',
866 'EGLImageTargetRenderbufferStorageOES',
867 # GL_OES_mapbuffer
868 'GetBufferPointervOES',
869 'MapBufferOES',
870 'UnmapBufferOES',
871 # GL_EXT_multi_draw_arrays
872 'MultiDrawArraysEXT',
873 'MultiDrawElementsEXT',
874 # GL_OES_blend_equation_separate
875 'BlendEquationSeparateOES',
876 # GL_OES_blend_func_separate
877 'BlendFuncSeparateOES',
878 # GL_OES_blend_subtract
879 'BlendEquationOES',
880 # GL_OES_draw_texture
881 'DrawTexiOES',
882 'DrawTexivOES',
883 'DrawTexfOES',
884 'DrawTexfvOES',
885 'DrawTexsOES',
886 'DrawTexsvOES',
887 'DrawTexxOES',
888 'DrawTexxvOES',
889 # GL_OES_fixed_point
890 'AlphaFuncxOES',
891 'ClearColorxOES',
892 'ClearDepthxOES',
893 'Color4xOES',
894 'DepthRangexOES',
895 'FogxOES',
896 'FogxvOES',
897 'FrustumxOES',
898 'LightModelxOES',
899 'LightModelxvOES',
900 'LightxOES',
901 'LightxvOES',
902 'LineWidthxOES',
903 'LoadMatrixxOES',
904 'MaterialxOES',
905 'MaterialxvOES',
906 'MultiTexCoord4xOES',
907 'MultMatrixxOES',
908 'Normal3xOES',
909 'OrthoxOES',
910 'PointSizexOES',
911 'PolygonOffsetxOES',
912 'RotatexOES',
913 'SampleCoveragexOES',
914 'ScalexOES',
915 'TexEnvxOES',
916 'TexEnvxvOES',
917 'TexParameterxOES',
918 'TranslatexOES',
919 'ClipPlanexOES',
920 'GetClipPlanexOES',
921 'GetFixedvOES',
922 'GetLightxvOES',
923 'GetMaterialxvOES',
924 'GetTexEnvxvOES',
925 'GetTexParameterxvOES',
926 'PointParameterxOES',
927 'PointParameterxvOES',
928 'TexParameterxvOES',
929 # GL_OES_framebuffer_object
930 'BindFramebufferOES',
931 'BindRenderbufferOES',
932 'CheckFramebufferStatusOES',
933 'DeleteFramebuffersOES',
934 'DeleteRenderbuffersOES',
935 'FramebufferRenderbufferOES',
936 'FramebufferTexture2DOES',
937 'GenerateMipmapOES',
938 'GenFramebuffersOES',
939 'GenRenderbuffersOES',
940 'GetFramebufferAttachmentParameterivOES',
941 'GetRenderbufferParameterivOES',
942 'IsFramebufferOES',
943 'IsRenderbufferOES',
944 'RenderbufferStorageOES',
945 # GL_OES_point_size_array
946 'PointSizePointerOES',
947 # GL_OES_query_matrix
948 'QueryMatrixxOES',
949 # GL_OES_single_precision
950 'ClearDepthfOES',
951 'DepthRangefOES',
952 'FrustumfOES',
953 'OrthofOES',
954 'ClipPlanefOES',
955 'GetClipPlanefOES',
956 # GL_OES_texture_cube_map
957 'GetTexGenfvOES',
958 'GetTexGenivOES',
959 'GetTexGenxvOES',
960 'TexGenfOES',
961 'TexGenfvOES',
962 'TexGeniOES',
963 'TexGenivOES',
964 'TexGenxOES',
965 'TexGenxvOES',
966 ]
967
968 super(ES1APIPrinter, self).__init__(entries, es1_api)
969 self.prefix_lib = 'gl'
970 self.prefix_warn = 'gl'
971
972 def _get_c_header(self):
973 header = """#ifndef _GLAPI_TMP_H_
974 #define _GLAPI_TMP_H_
975 typedef int GLfixed;
976 typedef int GLclampx;
977 #endif /* _GLAPI_TMP_H_ */"""
978
979 return header
980
981 class ES2APIPrinter(GLAPIPrinter):
982 """OpenGL ES 2.x API Printer"""
983
984 def __init__(self, entries):
985 es2_api = [
986 # OpenGL ES 2.0
987 "ActiveTexture",
988 "AttachShader",
989 "BindAttribLocation",
990 "BindBuffer",
991 "BindFramebuffer",
992 "BindRenderbuffer",
993 "BindTexture",
994 "BlendColor",
995 "BlendEquation",
996 "BlendEquationSeparate",
997 "BlendFunc",
998 "BlendFuncSeparate",
999 "BufferData",
1000 "BufferSubData",
1001 "CheckFramebufferStatus",
1002 "Clear",
1003 "ClearColor",
1004 "ClearDepthf",
1005 "ClearStencil",
1006 "ColorMask",
1007 "CompileShader",
1008 "CompressedTexImage2D",
1009 "CompressedTexSubImage2D",
1010 "CopyTexImage2D",
1011 "CopyTexSubImage2D",
1012 "CreateProgram",
1013 "CreateShader",
1014 "CullFace",
1015 "DeleteBuffers",
1016 "DeleteFramebuffers",
1017 "DeleteProgram",
1018 "DeleteRenderbuffers",
1019 "DeleteShader",
1020 "DeleteTextures",
1021 "DepthFunc",
1022 "DepthMask",
1023 "DepthRangef",
1024 "DetachShader",
1025 "Disable",
1026 "DisableVertexAttribArray",
1027 "DrawArrays",
1028 "DrawElements",
1029 "Enable",
1030 "EnableVertexAttribArray",
1031 "Finish",
1032 "Flush",
1033 "FramebufferRenderbuffer",
1034 "FramebufferTexture2D",
1035 "FrontFace",
1036 "GenBuffers",
1037 "GenerateMipmap",
1038 "GenFramebuffers",
1039 "GenRenderbuffers",
1040 "GenTextures",
1041 "GetActiveAttrib",
1042 "GetActiveUniform",
1043 "GetAttachedShaders",
1044 "GetAttribLocation",
1045 "GetBooleanv",
1046 "GetBufferParameteriv",
1047 "GetError",
1048 "GetFloatv",
1049 "GetFramebufferAttachmentParameteriv",
1050 "GetIntegerv",
1051 "GetProgramInfoLog",
1052 "GetProgramiv",
1053 "GetRenderbufferParameteriv",
1054 "GetShaderInfoLog",
1055 "GetShaderiv",
1056 "GetShaderPrecisionFormat",
1057 "GetShaderSource",
1058 "GetString",
1059 "GetTexParameterfv",
1060 "GetTexParameteriv",
1061 "GetUniformfv",
1062 "GetUniformiv",
1063 "GetUniformLocation",
1064 "GetVertexAttribfv",
1065 "GetVertexAttribiv",
1066 "GetVertexAttribPointerv",
1067 "Hint",
1068 "IsBuffer",
1069 "IsEnabled",
1070 "IsFramebuffer",
1071 "IsProgram",
1072 "IsRenderbuffer",
1073 "IsShader",
1074 "IsTexture",
1075 "LineWidth",
1076 "LinkProgram",
1077 "PixelStorei",
1078 "PolygonOffset",
1079 "ReadPixels",
1080 "ReleaseShaderCompiler",
1081 "RenderbufferStorage",
1082 "SampleCoverage",
1083 "Scissor",
1084 "ShaderBinary",
1085 "ShaderSource",
1086 "StencilFunc",
1087 "StencilFuncSeparate",
1088 "StencilMask",
1089 "StencilMaskSeparate",
1090 "StencilOp",
1091 "StencilOpSeparate",
1092 "TexImage2D",
1093 "TexParameterf",
1094 "TexParameterfv",
1095 "TexParameteri",
1096 "TexParameteriv",
1097 "TexSubImage2D",
1098 "Uniform1f",
1099 "Uniform1fv",
1100 "Uniform1i",
1101 "Uniform1iv",
1102 "Uniform2f",
1103 "Uniform2fv",
1104 "Uniform2i",
1105 "Uniform2iv",
1106 "Uniform3f",
1107 "Uniform3fv",
1108 "Uniform3i",
1109 "Uniform3iv",
1110 "Uniform4f",
1111 "Uniform4fv",
1112 "Uniform4i",
1113 "Uniform4iv",
1114 "UniformMatrix2fv",
1115 "UniformMatrix3fv",
1116 "UniformMatrix4fv",
1117 "UseProgram",
1118 "ValidateProgram",
1119 "VertexAttrib1f",
1120 "VertexAttrib1fv",
1121 "VertexAttrib2f",
1122 "VertexAttrib2fv",
1123 "VertexAttrib3f",
1124 "VertexAttrib3fv",
1125 "VertexAttrib4f",
1126 "VertexAttrib4fv",
1127 "VertexAttribPointer",
1128 "Viewport",
1129 # GL_OES_EGL_image
1130 'EGLImageTargetTexture2DOES',
1131 'EGLImageTargetRenderbufferStorageOES',
1132 # GL_OES_mapbuffer
1133 'GetBufferPointervOES',
1134 'MapBufferOES',
1135 'UnmapBufferOES',
1136 # GL_EXT_multi_draw_arrays
1137 'MultiDrawArraysEXT',
1138 'MultiDrawElementsEXT',
1139 # GL_OES_texture_3D
1140 'CompressedTexImage3DOES',
1141 'CompressedTexSubImage3DOES',
1142 'CopyTexSubImage3DOES',
1143 'FramebufferTexture3DOES',
1144 'TexImage3DOES',
1145 'TexSubImage3DOES',
1146 # GL_OES_get_program_binary
1147 'GetProgramBinaryOES',
1148 'ProgramBinaryOES',
1149 ]
1150
1151 super(ES2APIPrinter, self).__init__(entries, es2_api)
1152 self.prefix_lib = 'gl'
1153 self.prefix_warn = 'gl'
1154
1155 def _get_c_header(self):
1156 header = """#ifndef _GLAPI_TMP_H_
1157 #define _GLAPI_TMP_H_
1158 typedef int GLfixed;
1159 typedef int GLclampx;
1160 #endif /* _GLAPI_TMP_H_ */"""
1161
1162 return header
1163
1164 class VGAPIPrinter(ABIPrinter):
1165 """OpenVG API Printer"""
1166
1167 def __init__(self, entries):
1168 super(VGAPIPrinter, self).__init__(entries)
1169
1170 self.api_defines = ['VG_VGEXT_PROTOTYPES']
1171 self.api_headers = ['"VG/openvg.h"', '"VG/vgext.h"']
1172 self.api_call = 'VG_API_CALL'
1173 self.api_entry = 'VG_API_ENTRY'
1174 self.api_attrs = 'VG_API_EXIT'
1175
1176 self.prefix_lib = 'vg'
1177 self.prefix_app = 'vega'
1178 self.prefix_noop = 'noop'
1179 self.prefix_warn = 'vg'
1180
1181 def parse_args():
1182 printers = ['glapi', 'es1api', 'es2api', 'vgapi']
1183 modes = ['lib', 'app']
1184
1185 parser = OptionParser(usage='usage: %prog [options] <filename>')
1186 parser.add_option('-p', '--printer', dest='printer',
1187 help='printer to use: %s' % (", ".join(printers)))
1188 parser.add_option('-m', '--mode', dest='mode',
1189 help='target user: %s' % (", ".join(modes)))
1190
1191 options, args = parser.parse_args()
1192 if not args or options.printer not in printers or \
1193 options.mode not in modes:
1194 parser.print_help()
1195 sys.exit(1)
1196
1197 return (args[0], options)
1198
1199 def main():
1200 printers = {
1201 'vgapi': VGAPIPrinter,
1202 'glapi': GLAPIPrinter,
1203 'es1api': ES1APIPrinter,
1204 'es2api': ES2APIPrinter
1205 }
1206
1207 filename, options = parse_args()
1208
1209 if filename.endswith('.xml'):
1210 entries = abi_parse_xml(filename)
1211 else:
1212 entries = abi_parse(filename)
1213 abi_sanity_check(entries)
1214
1215 printer = printers[options.printer](entries)
1216 if options.mode == 'lib':
1217 printer.output_for_lib()
1218 else:
1219 printer.output_for_app()
1220
1221 if __name__ == '__main__':
1222 main()