revert 213 commits (to 56092) from the last month. 10 still need work to resolve...
[AROS.git] / workbench / libs / mesa / src / mapi / mapi / mapi_abi.py
blobcb9fc0ef84185efd819c2c725aa728288b2b9267
1 #!/usr/bin/env python
3 # Mesa 3-D graphics library
4 # Version: 7.9
6 # Copyright (C) 2010 LunarG Inc.
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:
15 # The above copyright notice and this permission notice shall be included
16 # in all copies or substantial portions of the Software.
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.
26 # Authors:
27 # Chia-I Wu <olv@lunarg.com>
29 import sys
30 import re
31 from optparse import OptionParser
33 # number of dynamic entries
34 ABI_NUM_DYNAMIC_ENTRIES = 256
36 class ABIEntry(object):
37 """Represent an ABI entry."""
39 _match_c_param = re.compile(
40 '^(?P<type>[\w\s*]+?)(?P<name>\w+)(\[(?P<array>\d+)\])?$')
42 def __init__(self, cols, attrs):
43 self._parse(cols)
45 self.slot = attrs['slot']
46 self.hidden = attrs['hidden']
47 self.alias = attrs['alias']
48 self.handcode = attrs['handcode']
50 def c_prototype(self):
51 return '%s %s(%s)' % (self.c_return(), self.name, self.c_params())
53 def c_return(self):
54 ret = self.ret
55 if not ret:
56 ret = 'void'
58 return ret
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')
70 return ", ".join(c_params)
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)
78 return ", ".join(c_args)
80 def _parse(self, cols):
81 ret = cols.pop(0)
82 if ret == 'void':
83 ret = None
85 name = cols.pop(0)
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))
96 self.ret = ret
97 self.name = name
98 self.params = params
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)
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
110 return (c_type, c_name, c_array)
112 def __str__(self):
113 return self.c_prototype()
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
124 if not res:
125 res = cmp(self.name, other.name)
127 return res
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
136 api = gl_XML.parse_GL_API(xml, glX_XML.glx_item_factory())
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)
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)),
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
167 if entry_dict.has_key(name):
168 raise Exception('%s is duplicated' % (name))
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(',')])
176 ent = ABIEntry(cols, attrs)
177 entry_dict[ent.name] = ent
179 entries = entry_dict.values()
180 entries.sort()
182 return entries
184 def abi_parse_line(line):
185 cols = [col.strip() for col in line.split(',')]
187 attrs = {
188 'slot': -1,
189 'hidden': False,
190 'alias': None,
191 'handcode': None,
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]
212 return (attrs, cols)
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()]
220 entry_dict = {}
221 next_slot = 0
222 for line in lines:
223 attrs, cols = abi_parse_line(line)
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
239 if attrs['slot'] < 0:
240 attrs['slot'] = slot
241 elif attrs['slot'] != slot:
242 raise Exception('invalid slot in %s' % (line))
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
249 entries = entry_dict.values()
250 entries.sort()
252 return entries
254 def abi_sanity_check(entries):
255 if not entries:
256 return
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)
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))
285 class ABIPrinter(object):
286 """MAPI Printer"""
288 def __init__(self, entries):
289 self.entries = entries
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))
295 self.indent = ' ' * 3
296 self.noop_warn = 'noop_warn'
297 self.noop_generic = 'noop_generic'
298 self.current_get = 'entry_current_get'
300 self.api_defines = []
301 self.api_headers = ['"KHR/khrplatform.h"']
302 self.api_call = 'KHRONOS_APICALL'
303 self.api_entry = 'KHRONOS_APIENTRY'
304 self.api_attrs = 'KHRONOS_APIATTRIBUTES'
306 self.c_header = ''
308 self.lib_need_table_size = True
309 self.lib_need_noop_array = True
310 self.lib_need_stubs = True
311 self.lib_need_all_entries = True
312 self.lib_need_non_hidden_entries = False
314 def c_notice(self):
315 return '/* This file is automatically generated by mapi_abi.py. Do not modify. */'
317 def c_public_includes(self):
318 """Return includes of the client API headers."""
319 defines = ['#define ' + d for d in self.api_defines]
320 includes = ['#include ' + h for h in self.api_headers]
321 return "\n".join(defines + includes)
323 def need_entry_point(self, ent):
324 """Return True if an entry point is needed for the entry."""
325 # non-handcode hidden aliases may share the entry they alias
326 use_alias = (ent.hidden and ent.alias and not ent.handcode)
327 return not use_alias
329 def c_public_declarations(self, prefix):
330 """Return the declarations of public entry points."""
331 decls = []
332 for ent in self.entries:
333 if not self.need_entry_point(ent):
334 continue
335 export = self.api_call if not ent.hidden else ''
336 decls.append(self._c_decl(ent, prefix, True, export) + ';')
338 return "\n".join(decls)
340 def c_mapi_table(self):
341 """Return defines of the dispatch table size."""
342 num_static_entries = self.entries[-1].slot + 1
343 return ('#define MAPI_TABLE_NUM_STATIC %d\n' + \
344 '#define MAPI_TABLE_NUM_DYNAMIC %d') % (
345 num_static_entries, ABI_NUM_DYNAMIC_ENTRIES)
347 def c_mapi_table_initializer(self, prefix):
348 """Return the array initializer for mapi_table_fill."""
349 entries = [self._c_function(ent, prefix)
350 for ent in self.entries if not ent.alias]
351 pre = self.indent + '(mapi_proc) '
352 return pre + (',\n' + pre).join(entries)
354 def c_mapi_table_spec(self):
355 """Return the spec for mapi_init."""
356 specv1 = []
357 line = '"1'
358 for ent in self.entries:
359 if not ent.alias:
360 line += '\\0"\n'
361 specv1.append(line)
362 line = '"'
363 line += '%s\\0' % ent.name
364 line += '";'
365 specv1.append(line)
367 return self.indent + self.indent.join(specv1)
369 def _c_function(self, ent, prefix, mangle=False, stringify=False):
370 """Return the function name of an entry."""
371 formats = {
372 True: { True: '%s_STR(%s)', False: '%s(%s)' },
373 False: { True: '"%s%s"', False: '%s%s' },
375 fmt = formats[prefix.isupper()][stringify]
376 name = ent.name
377 if mangle and ent.hidden:
378 name = '_dispatch_stub_' + str(ent.slot)
379 return fmt % (prefix, name)
381 def _c_function_call(self, ent, prefix):
382 """Return the function name used for calling."""
383 if ent.handcode:
384 # _c_function does not handle this case
385 formats = { True: '%s(%s)', False: '%s%s' }
386 fmt = formats[prefix.isupper()]
387 name = fmt % (prefix, ent.handcode)
388 elif self.need_entry_point(ent):
389 name = self._c_function(ent, prefix, True)
390 else:
391 name = self._c_function(ent.alias, prefix, True)
392 return name
394 def _c_decl(self, ent, prefix, mangle=False, export=''):
395 """Return the C declaration for the entry."""
396 decl = '%s %s %s(%s)' % (ent.c_return(), self.api_entry,
397 self._c_function(ent, prefix, mangle), ent.c_params())
398 if export:
399 decl = export + ' ' + decl
400 if self.api_attrs:
401 decl += ' ' + self.api_attrs
403 return decl
405 def _c_cast(self, ent):
406 """Return the C cast for the entry."""
407 cast = '%s (%s *)(%s)' % (
408 ent.c_return(), self.api_entry, ent.c_params())
410 return cast
412 def c_private_declarations(self, prefix):
413 """Return the declarations of private functions."""
414 decls = [self._c_decl(ent, prefix) + ';'
415 for ent in self.entries if not ent.alias]
417 return "\n".join(decls)
419 def c_public_dispatches(self, prefix, no_hidden):
420 """Return the public dispatch functions."""
421 dispatches = []
422 for ent in self.entries:
423 if ent.hidden and no_hidden:
424 continue
426 if not self.need_entry_point(ent):
427 continue
429 export = self.api_call if not ent.hidden else ''
431 proto = self._c_decl(ent, prefix, True, export)
432 cast = self._c_cast(ent)
434 ret = ''
435 if ent.ret:
436 ret = 'return '
437 stmt1 = self.indent
438 stmt1 += 'const struct mapi_table *_tbl = %s();' % (
439 self.current_get)
440 stmt2 = self.indent
441 stmt2 += 'mapi_func _func = ((const mapi_func *) _tbl)[%d];' % (
442 ent.slot)
443 stmt3 = self.indent
444 stmt3 += '%s((%s) _func)(%s);' % (ret, cast, ent.c_args())
446 disp = '%s\n{\n%s\n%s\n%s\n}' % (proto, stmt1, stmt2, stmt3)
448 if ent.handcode:
449 disp = '#if 0\n' + disp + '\n#endif'
451 dispatches.append(disp)
453 return '\n\n'.join(dispatches)
455 def c_public_initializer(self, prefix):
456 """Return the initializer for public dispatch functions."""
457 names = []
458 for ent in self.entries:
459 if ent.alias:
460 continue
462 name = '%s(mapi_func) %s' % (self.indent,
463 self._c_function_call(ent, prefix))
464 names.append(name)
466 return ',\n'.join(names)
468 def c_stub_string_pool(self):
469 """Return the string pool for use by stubs."""
470 # sort entries by their names
471 sorted_entries = self.entries[:]
472 sorted_entries.sort(lambda x, y: cmp(x.name, y.name))
474 pool = []
475 offsets = {}
476 count = 0
477 for ent in sorted_entries:
478 offsets[ent] = count
479 pool.append('%s' % (ent.name))
480 count += len(ent.name) + 1
482 pool_str = self.indent + '"' + \
483 ('\\0"\n' + self.indent + '"').join(pool) + '";'
484 return (pool_str, offsets)
486 def c_stub_initializer(self, prefix, pool_offsets):
487 """Return the initializer for struct mapi_stub array."""
488 stubs = []
489 for ent in self.entries_sorted_by_names:
490 stubs.append('%s{ (void *) %d, %d, NULL }' % (
491 self.indent, pool_offsets[ent], ent.slot))
493 return ',\n'.join(stubs)
495 def c_noop_functions(self, prefix, warn_prefix):
496 """Return the noop functions."""
497 noops = []
498 for ent in self.entries:
499 if ent.alias:
500 continue
502 proto = self._c_decl(ent, prefix, False, 'static')
504 stmt1 = self.indent + '%s(%s);' % (self.noop_warn,
505 self._c_function(ent, warn_prefix, False, True))
507 if ent.ret:
508 stmt2 = self.indent + 'return (%s) 0;' % (ent.ret)
509 noop = '%s\n{\n%s\n%s\n}' % (proto, stmt1, stmt2)
510 else:
511 noop = '%s\n{\n%s\n}' % (proto, stmt1)
513 noops.append(noop)
515 return '\n\n'.join(noops)
517 def c_noop_initializer(self, prefix, use_generic):
518 """Return an initializer for the noop dispatch table."""
519 entries = [self._c_function(ent, prefix)
520 for ent in self.entries if not ent.alias]
521 if use_generic:
522 entries = [self.noop_generic] * len(entries)
524 entries.extend([self.noop_generic] * ABI_NUM_DYNAMIC_ENTRIES)
526 pre = self.indent + '(mapi_func) '
527 return pre + (',\n' + pre).join(entries)
529 def c_asm_gcc(self, prefix, no_hidden):
530 asm = []
532 for ent in self.entries:
533 if ent.hidden and no_hidden:
534 continue
536 if not self.need_entry_point(ent):
537 continue
539 name = self._c_function(ent, prefix, True, True)
541 if ent.handcode:
542 asm.append('#if 0')
544 if ent.hidden:
545 asm.append('".hidden "%s"\\n"' % (name))
547 if ent.alias and not (ent.alias.hidden and no_hidden):
548 asm.append('".globl "%s"\\n"' % (name))
549 asm.append('".set "%s", "%s"\\n"' % (name,
550 self._c_function(ent.alias, prefix, True, True)))
551 else:
552 asm.append('STUB_ASM_ENTRY(%s)"\\n"' % (name))
553 asm.append('"\\t"STUB_ASM_CODE("%d")"\\n"' % (ent.slot))
555 if ent.handcode:
556 asm.append('#endif')
557 asm.append('')
559 return "\n".join(asm)
561 def output_for_lib(self):
562 print self.c_notice()
564 if self.c_header:
565 print
566 print self.c_header
568 print
569 print '#ifdef MAPI_TMP_DEFINES'
570 print self.c_public_includes()
571 print
572 print self.c_public_declarations(self.prefix_lib)
573 print '#undef MAPI_TMP_DEFINES'
574 print '#endif /* MAPI_TMP_DEFINES */'
576 if self.lib_need_table_size:
577 print
578 print '#ifdef MAPI_TMP_TABLE'
579 print self.c_mapi_table()
580 print '#undef MAPI_TMP_TABLE'
581 print '#endif /* MAPI_TMP_TABLE */'
583 if self.lib_need_noop_array:
584 print
585 print '#ifdef MAPI_TMP_NOOP_ARRAY'
586 print '#ifdef DEBUG'
587 print
588 print self.c_noop_functions(self.prefix_noop, self.prefix_warn)
589 print
590 print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
591 print self.c_noop_initializer(self.prefix_noop, False)
592 print '};'
593 print
594 print '#else /* DEBUG */'
595 print
596 print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
597 print self.c_noop_initializer(self.prefix_noop, True)
598 print '};'
599 print
600 print '#endif /* DEBUG */'
601 print '#undef MAPI_TMP_NOOP_ARRAY'
602 print '#endif /* MAPI_TMP_NOOP_ARRAY */'
604 if self.lib_need_stubs:
605 pool, pool_offsets = self.c_stub_string_pool()
606 print
607 print '#ifdef MAPI_TMP_PUBLIC_STUBS'
608 print 'static const char public_string_pool[] ='
609 print pool
610 print
611 print 'static const struct mapi_stub public_stubs[] = {'
612 print self.c_stub_initializer(self.prefix_lib, pool_offsets)
613 print '};'
614 print '#undef MAPI_TMP_PUBLIC_STUBS'
615 print '#endif /* MAPI_TMP_PUBLIC_STUBS */'
617 if self.lib_need_all_entries:
618 print
619 print '#ifdef MAPI_TMP_PUBLIC_ENTRIES'
620 print self.c_public_dispatches(self.prefix_lib, False)
621 print
622 print 'static const mapi_func public_entries[] = {'
623 print self.c_public_initializer(self.prefix_lib)
624 print '};'
625 print '#undef MAPI_TMP_PUBLIC_ENTRIES'
626 print '#endif /* MAPI_TMP_PUBLIC_ENTRIES */'
628 print
629 print '#ifdef MAPI_TMP_STUB_ASM_GCC'
630 print '__asm__('
631 print self.c_asm_gcc(self.prefix_lib, False)
632 print ');'
633 print '#undef MAPI_TMP_STUB_ASM_GCC'
634 print '#endif /* MAPI_TMP_STUB_ASM_GCC */'
636 if self.lib_need_non_hidden_entries:
637 all_hidden = True
638 for ent in self.entries:
639 if not ent.hidden:
640 all_hidden = False
641 break
642 if not all_hidden:
643 print
644 print '#ifdef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN'
645 print self.c_public_dispatches(self.prefix_lib, True)
646 print
647 print '/* does not need public_entries */'
648 print '#undef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN'
649 print '#endif /* MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN */'
651 print
652 print '#ifdef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN'
653 print '__asm__('
654 print self.c_asm_gcc(self.prefix_lib, True)
655 print ');'
656 print '#undef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN'
657 print '#endif /* MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN */'
659 def output_for_app(self):
660 print self.c_notice()
661 print
662 print self.c_private_declarations(self.prefix_app)
663 print
664 print '#ifdef API_TMP_DEFINE_SPEC'
665 print
666 print 'static const char %s_spec[] =' % (self.prefix_app)
667 print self.c_mapi_table_spec()
668 print
669 print 'static const mapi_proc %s_procs[] = {' % (self.prefix_app)
670 print self.c_mapi_table_initializer(self.prefix_app)
671 print '};'
672 print
673 print '#endif /* API_TMP_DEFINE_SPEC */'
675 class GLAPIPrinter(ABIPrinter):
676 """OpenGL API Printer"""
678 def __init__(self, entries, api=None):
679 api_entries = self._get_api_entries(entries, api)
680 super(GLAPIPrinter, self).__init__(api_entries)
682 self.api_defines = ['GL_GLEXT_PROTOTYPES']
683 self.api_headers = ['"GL/gl.h"', '"GL/glext.h"']
684 self.api_call = 'GLAPI'
685 self.api_entry = 'APIENTRY'
686 self.api_attrs = ''
688 self.lib_need_table_size = False
689 self.lib_need_noop_array = False
690 self.lib_need_stubs = False
691 self.lib_need_all_entries = False
692 self.lib_need_non_hidden_entries = True
694 self.prefix_lib = 'GLAPI_PREFIX'
695 self.prefix_app = '_mesa_'
696 self.prefix_noop = 'noop'
697 self.prefix_warn = self.prefix_lib
699 self.c_header = self._get_c_header()
701 def _get_api_entries(self, entries, api):
702 """Override the entry attributes according to API."""
703 import copy
705 # no override
706 if api is None:
707 return entries
709 api_entries = {}
710 for ent in entries:
711 ent = copy.copy(ent)
713 # override 'hidden' and 'handcode'
714 ent.hidden = ent.name not in api
715 ent.handcode = False
716 if ent.alias:
717 ent.alias = api_entries[ent.alias.name]
719 api_entries[ent.name] = ent
721 # sanity check
722 missed = [name for name in api if name not in api_entries]
723 if missed:
724 raise Exception('%s is missing' % str(missed))
726 entries = api_entries.values()
727 entries.sort()
729 return entries
731 def _get_c_header(self):
732 header = """#ifndef _GLAPI_TMP_H_
733 #define _GLAPI_TMP_H_
734 #ifdef USE_MGL_NAMESPACE
735 #define GLAPI_PREFIX(func) mgl##func
736 #define GLAPI_PREFIX_STR(func) "mgl"#func
737 #else
738 #define GLAPI_PREFIX(func) gl##func
739 #define GLAPI_PREFIX_STR(func) "gl"#func
740 #endif /* USE_MGL_NAMESPACE */
742 typedef int GLfixed;
743 typedef int GLclampx;
744 #endif /* _GLAPI_TMP_H_ */"""
746 return header
748 class ES1APIPrinter(GLAPIPrinter):
749 """OpenGL ES 1.x API Printer"""
751 def __init__(self, entries):
752 es1_api = [
753 # OpenGL ES 1.1
754 'ActiveTexture',
755 'AlphaFunc',
756 'AlphaFuncx',
757 'BindBuffer',
758 'BindTexture',
759 'BlendFunc',
760 'BufferData',
761 'BufferSubData',
762 'Clear',
763 'ClearColor',
764 'ClearColorx',
765 'ClearDepthf',
766 'ClearDepthx',
767 'ClearStencil',
768 'ClientActiveTexture',
769 'ClipPlanef',
770 'ClipPlanex',
771 'Color4f',
772 'Color4ub',
773 'Color4x',
774 'ColorMask',
775 'ColorPointer',
776 'CompressedTexImage2D',
777 'CompressedTexSubImage2D',
778 'CopyTexImage2D',
779 'CopyTexSubImage2D',
780 'CullFace',
781 'DeleteBuffers',
782 'DeleteTextures',
783 'DepthFunc',
784 'DepthMask',
785 'DepthRangef',
786 'DepthRangex',
787 'Disable',
788 'DisableClientState',
789 'DrawArrays',
790 'DrawElements',
791 'Enable',
792 'EnableClientState',
793 'Finish',
794 'Flush',
795 'Fogf',
796 'Fogfv',
797 'Fogx',
798 'Fogxv',
799 'FrontFace',
800 'Frustumf',
801 'Frustumx',
802 'GenBuffers',
803 'GenTextures',
804 'GetBooleanv',
805 'GetBufferParameteriv',
806 'GetClipPlanef',
807 'GetClipPlanex',
808 'GetError',
809 'GetFixedv',
810 'GetFloatv',
811 'GetIntegerv',
812 'GetLightfv',
813 'GetLightxv',
814 'GetMaterialfv',
815 'GetMaterialxv',
816 'GetPointerv',
817 'GetString',
818 'GetTexEnvfv',
819 'GetTexEnviv',
820 'GetTexEnvxv',
821 'GetTexParameterfv',
822 'GetTexParameteriv',
823 'GetTexParameterxv',
824 'Hint',
825 'IsBuffer',
826 'IsEnabled',
827 'IsTexture',
828 'Lightf',
829 'Lightfv',
830 'LightModelf',
831 'LightModelfv',
832 'LightModelx',
833 'LightModelxv',
834 'Lightx',
835 'Lightxv',
836 'LineWidth',
837 'LineWidthx',
838 'LoadIdentity',
839 'LoadMatrixf',
840 'LoadMatrixx',
841 'LogicOp',
842 'Materialf',
843 'Materialfv',
844 'Materialx',
845 'Materialxv',
846 'MatrixMode',
847 'MultiTexCoord4f',
848 'MultiTexCoord4x',
849 'MultMatrixf',
850 'MultMatrixx',
851 'Normal3f',
852 'Normal3x',
853 'NormalPointer',
854 'Orthof',
855 'Orthox',
856 'PixelStorei',
857 'PointParameterf',
858 'PointParameterfv',
859 'PointParameterx',
860 'PointParameterxv',
861 'PointSize',
862 'PointSizex',
863 'PolygonOffset',
864 'PolygonOffsetx',
865 'PopMatrix',
866 'PushMatrix',
867 'ReadPixels',
868 'Rotatef',
869 'Rotatex',
870 'SampleCoverage',
871 'SampleCoveragex',
872 'Scalef',
873 'Scalex',
874 'Scissor',
875 'ShadeModel',
876 'StencilFunc',
877 'StencilMask',
878 'StencilOp',
879 'TexCoordPointer',
880 'TexEnvf',
881 'TexEnvfv',
882 'TexEnvi',
883 'TexEnviv',
884 'TexEnvx',
885 'TexEnvxv',
886 'TexImage2D',
887 'TexParameterf',
888 'TexParameterfv',
889 'TexParameteri',
890 'TexParameteriv',
891 'TexParameterx',
892 'TexParameterxv',
893 'TexSubImage2D',
894 'Translatef',
895 'Translatex',
896 'VertexPointer',
897 'Viewport',
898 # GL_OES_EGL_image
899 'EGLImageTargetTexture2DOES',
900 'EGLImageTargetRenderbufferStorageOES',
901 # GL_OES_mapbuffer
902 'GetBufferPointervOES',
903 'MapBufferOES',
904 'UnmapBufferOES',
905 # GL_EXT_multi_draw_arrays
906 'MultiDrawArraysEXT',
907 'MultiDrawElementsEXT',
908 # GL_OES_blend_equation_separate
909 'BlendEquationSeparateOES',
910 # GL_OES_blend_func_separate
911 'BlendFuncSeparateOES',
912 # GL_OES_blend_subtract
913 'BlendEquationOES',
914 # GL_OES_draw_texture
915 'DrawTexiOES',
916 'DrawTexivOES',
917 'DrawTexfOES',
918 'DrawTexfvOES',
919 'DrawTexsOES',
920 'DrawTexsvOES',
921 'DrawTexxOES',
922 'DrawTexxvOES',
923 # GL_OES_fixed_point
924 'AlphaFuncxOES',
925 'ClearColorxOES',
926 'ClearDepthxOES',
927 'Color4xOES',
928 'DepthRangexOES',
929 'FogxOES',
930 'FogxvOES',
931 'FrustumxOES',
932 'LightModelxOES',
933 'LightModelxvOES',
934 'LightxOES',
935 'LightxvOES',
936 'LineWidthxOES',
937 'LoadMatrixxOES',
938 'MaterialxOES',
939 'MaterialxvOES',
940 'MultiTexCoord4xOES',
941 'MultMatrixxOES',
942 'Normal3xOES',
943 'OrthoxOES',
944 'PointSizexOES',
945 'PolygonOffsetxOES',
946 'RotatexOES',
947 'SampleCoveragexOES',
948 'ScalexOES',
949 'TexEnvxOES',
950 'TexEnvxvOES',
951 'TexParameterxOES',
952 'TranslatexOES',
953 'ClipPlanexOES',
954 'GetClipPlanexOES',
955 'GetFixedvOES',
956 'GetLightxvOES',
957 'GetMaterialxvOES',
958 'GetTexEnvxvOES',
959 'GetTexParameterxvOES',
960 'PointParameterxOES',
961 'PointParameterxvOES',
962 'TexParameterxvOES',
963 # GL_OES_framebuffer_object
964 'BindFramebufferOES',
965 'BindRenderbufferOES',
966 'CheckFramebufferStatusOES',
967 'DeleteFramebuffersOES',
968 'DeleteRenderbuffersOES',
969 'FramebufferRenderbufferOES',
970 'FramebufferTexture2DOES',
971 'GenerateMipmapOES',
972 'GenFramebuffersOES',
973 'GenRenderbuffersOES',
974 'GetFramebufferAttachmentParameterivOES',
975 'GetRenderbufferParameterivOES',
976 'IsFramebufferOES',
977 'IsRenderbufferOES',
978 'RenderbufferStorageOES',
979 # GL_OES_point_size_array
980 'PointSizePointerOES',
981 # GL_OES_query_matrix
982 'QueryMatrixxOES',
983 # GL_OES_single_precision
984 'ClearDepthfOES',
985 'DepthRangefOES',
986 'FrustumfOES',
987 'OrthofOES',
988 'ClipPlanefOES',
989 'GetClipPlanefOES',
990 # GL_OES_texture_cube_map
991 'GetTexGenfvOES',
992 'GetTexGenivOES',
993 'GetTexGenxvOES',
994 'TexGenfOES',
995 'TexGenfvOES',
996 'TexGeniOES',
997 'TexGenivOES',
998 'TexGenxOES',
999 'TexGenxvOES',
1002 super(ES1APIPrinter, self).__init__(entries, es1_api)
1003 self.prefix_lib = 'gl'
1004 self.prefix_warn = 'gl'
1006 def _get_c_header(self):
1007 header = """#ifndef _GLAPI_TMP_H_
1008 #define _GLAPI_TMP_H_
1009 typedef int GLfixed;
1010 typedef int GLclampx;
1011 #endif /* _GLAPI_TMP_H_ */"""
1013 return header
1015 class ES2APIPrinter(GLAPIPrinter):
1016 """OpenGL ES 2.x API Printer"""
1018 def __init__(self, entries):
1019 es2_api = [
1020 # OpenGL ES 2.0
1021 "ActiveTexture",
1022 "AttachShader",
1023 "BindAttribLocation",
1024 "BindBuffer",
1025 "BindFramebuffer",
1026 "BindRenderbuffer",
1027 "BindTexture",
1028 "BlendColor",
1029 "BlendEquation",
1030 "BlendEquationSeparate",
1031 "BlendFunc",
1032 "BlendFuncSeparate",
1033 "BufferData",
1034 "BufferSubData",
1035 "CheckFramebufferStatus",
1036 "Clear",
1037 "ClearColor",
1038 "ClearDepthf",
1039 "ClearStencil",
1040 "ColorMask",
1041 "CompileShader",
1042 "CompressedTexImage2D",
1043 "CompressedTexSubImage2D",
1044 "CopyTexImage2D",
1045 "CopyTexSubImage2D",
1046 "CreateProgram",
1047 "CreateShader",
1048 "CullFace",
1049 "DeleteBuffers",
1050 "DeleteFramebuffers",
1051 "DeleteProgram",
1052 "DeleteRenderbuffers",
1053 "DeleteShader",
1054 "DeleteTextures",
1055 "DepthFunc",
1056 "DepthMask",
1057 "DepthRangef",
1058 "DetachShader",
1059 "Disable",
1060 "DisableVertexAttribArray",
1061 "DrawArrays",
1062 "DrawElements",
1063 "Enable",
1064 "EnableVertexAttribArray",
1065 "Finish",
1066 "Flush",
1067 "FramebufferRenderbuffer",
1068 "FramebufferTexture2D",
1069 "FrontFace",
1070 "GenBuffers",
1071 "GenerateMipmap",
1072 "GenFramebuffers",
1073 "GenRenderbuffers",
1074 "GenTextures",
1075 "GetActiveAttrib",
1076 "GetActiveUniform",
1077 "GetAttachedShaders",
1078 "GetAttribLocation",
1079 "GetBooleanv",
1080 "GetBufferParameteriv",
1081 "GetError",
1082 "GetFloatv",
1083 "GetFramebufferAttachmentParameteriv",
1084 "GetIntegerv",
1085 "GetProgramInfoLog",
1086 "GetProgramiv",
1087 "GetRenderbufferParameteriv",
1088 "GetShaderInfoLog",
1089 "GetShaderiv",
1090 "GetShaderPrecisionFormat",
1091 "GetShaderSource",
1092 "GetString",
1093 "GetTexParameterfv",
1094 "GetTexParameteriv",
1095 "GetUniformfv",
1096 "GetUniformiv",
1097 "GetUniformLocation",
1098 "GetVertexAttribfv",
1099 "GetVertexAttribiv",
1100 "GetVertexAttribPointerv",
1101 "Hint",
1102 "IsBuffer",
1103 "IsEnabled",
1104 "IsFramebuffer",
1105 "IsProgram",
1106 "IsRenderbuffer",
1107 "IsShader",
1108 "IsTexture",
1109 "LineWidth",
1110 "LinkProgram",
1111 "PixelStorei",
1112 "PolygonOffset",
1113 "ReadPixels",
1114 "ReleaseShaderCompiler",
1115 "RenderbufferStorage",
1116 "SampleCoverage",
1117 "Scissor",
1118 "ShaderBinary",
1119 "ShaderSource",
1120 "StencilFunc",
1121 "StencilFuncSeparate",
1122 "StencilMask",
1123 "StencilMaskSeparate",
1124 "StencilOp",
1125 "StencilOpSeparate",
1126 "TexImage2D",
1127 "TexParameterf",
1128 "TexParameterfv",
1129 "TexParameteri",
1130 "TexParameteriv",
1131 "TexSubImage2D",
1132 "Uniform1f",
1133 "Uniform1fv",
1134 "Uniform1i",
1135 "Uniform1iv",
1136 "Uniform2f",
1137 "Uniform2fv",
1138 "Uniform2i",
1139 "Uniform2iv",
1140 "Uniform3f",
1141 "Uniform3fv",
1142 "Uniform3i",
1143 "Uniform3iv",
1144 "Uniform4f",
1145 "Uniform4fv",
1146 "Uniform4i",
1147 "Uniform4iv",
1148 "UniformMatrix2fv",
1149 "UniformMatrix3fv",
1150 "UniformMatrix4fv",
1151 "UseProgram",
1152 "ValidateProgram",
1153 "VertexAttrib1f",
1154 "VertexAttrib1fv",
1155 "VertexAttrib2f",
1156 "VertexAttrib2fv",
1157 "VertexAttrib3f",
1158 "VertexAttrib3fv",
1159 "VertexAttrib4f",
1160 "VertexAttrib4fv",
1161 "VertexAttribPointer",
1162 "Viewport",
1163 # GL_OES_EGL_image
1164 'EGLImageTargetTexture2DOES',
1165 'EGLImageTargetRenderbufferStorageOES',
1166 # GL_OES_mapbuffer
1167 'GetBufferPointervOES',
1168 'MapBufferOES',
1169 'UnmapBufferOES',
1170 # GL_EXT_multi_draw_arrays
1171 'MultiDrawArraysEXT',
1172 'MultiDrawElementsEXT',
1173 # GL_OES_texture_3D
1174 'CompressedTexImage3DOES',
1175 'CompressedTexSubImage3DOES',
1176 'CopyTexSubImage3DOES',
1177 'FramebufferTexture3DOES',
1178 'TexImage3DOES',
1179 'TexSubImage3DOES',
1180 # GL_OES_get_program_binary
1181 'GetProgramBinaryOES',
1182 'ProgramBinaryOES',
1185 super(ES2APIPrinter, self).__init__(entries, es2_api)
1186 self.prefix_lib = 'gl'
1187 self.prefix_warn = 'gl'
1189 def _get_c_header(self):
1190 header = """#ifndef _GLAPI_TMP_H_
1191 #define _GLAPI_TMP_H_
1192 typedef int GLfixed;
1193 typedef int GLclampx;
1194 #endif /* _GLAPI_TMP_H_ */"""
1196 return header
1198 class SharedGLAPIPrinter(GLAPIPrinter):
1199 """Shared GLAPI API Printer"""
1201 def __init__(self, entries):
1202 super(SharedGLAPIPrinter, self).__init__(entries, [])
1204 self.lib_need_table_size = True
1205 self.lib_need_noop_array = True
1206 self.lib_need_stubs = True
1207 self.lib_need_all_entries = True
1208 self.lib_need_non_hidden_entries = False
1210 self.prefix_lib = 'shared'
1211 self.prefix_warn = 'gl'
1213 def _get_c_header(self):
1214 header = """#ifndef _GLAPI_TMP_H_
1215 #define _GLAPI_TMP_H_
1216 typedef int GLfixed;
1217 typedef int GLclampx;
1218 #endif /* _GLAPI_TMP_H_ */"""
1220 return header
1222 class VGAPIPrinter(ABIPrinter):
1223 """OpenVG API Printer"""
1225 def __init__(self, entries):
1226 super(VGAPIPrinter, self).__init__(entries)
1228 self.api_defines = ['VG_VGEXT_PROTOTYPES']
1229 self.api_headers = ['"VG/openvg.h"', '"VG/vgext.h"']
1230 self.api_call = 'VG_API_CALL'
1231 self.api_entry = 'VG_API_ENTRY'
1232 self.api_attrs = 'VG_API_EXIT'
1234 self.prefix_lib = 'vg'
1235 self.prefix_app = 'vega'
1236 self.prefix_noop = 'noop'
1237 self.prefix_warn = 'vg'
1239 def parse_args():
1240 printers = ['vgapi', 'glapi', 'es1api', 'es2api', 'shared-glapi']
1241 modes = ['lib', 'app']
1243 parser = OptionParser(usage='usage: %prog [options] <filename>')
1244 parser.add_option('-p', '--printer', dest='printer',
1245 help='printer to use: %s' % (", ".join(printers)))
1246 parser.add_option('-m', '--mode', dest='mode',
1247 help='target user: %s' % (", ".join(modes)))
1249 options, args = parser.parse_args()
1250 if not args or options.printer not in printers or \
1251 options.mode not in modes:
1252 parser.print_help()
1253 sys.exit(1)
1255 return (args[0], options)
1257 def main():
1258 printers = {
1259 'vgapi': VGAPIPrinter,
1260 'glapi': GLAPIPrinter,
1261 'es1api': ES1APIPrinter,
1262 'es2api': ES2APIPrinter,
1263 'shared-glapi': SharedGLAPIPrinter,
1266 filename, options = parse_args()
1268 if filename.endswith('.xml'):
1269 entries = abi_parse_xml(filename)
1270 else:
1271 entries = abi_parse(filename)
1272 abi_sanity_check(entries)
1274 printer = printers[options.printer](entries)
1275 if options.mode == 'lib':
1276 printer.output_for_lib()
1277 else:
1278 printer.output_for_app()
1280 if __name__ == '__main__':
1281 main()