VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/glapi_parser/apiutil.py@ 43647

Last change on this file since 43647 was 43647, checked in by vboxsync, 12 years ago

crOpenGL: generate omitted aliaces for GetProcAddress

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 18.3 KB
Line 
1#!/usr/common/bin/python
2
3# apiutil.py
4#
5# This file defines a bunch of utility functions for OpenGL API code
6# generation.
7
8import sys, string, re
9
10
11#======================================================================
12
13def CopyrightC( ):
14 print """/* Copyright (c) 2001, Stanford University
15 All rights reserved.
16
17 See the file LICENSE.txt for information on redistributing this software. */
18 """
19
20def CopyrightDef( ):
21 print """; Copyright (c) 2001, Stanford University
22 ; All rights reserved.
23 ;
24 ; See the file LICENSE.txt for information on redistributing this software.
25 """
26
27
28
29#======================================================================
30
31class APIFunction:
32 """Class to represent a GL API function (name, return type,
33 parameters, etc)."""
34 def __init__(self):
35 self.name = ''
36 self.returnType = ''
37 self.category = ''
38 self.offset = -1
39 self.alias = ''
40 self.vectoralias = ''
41 self.params = []
42 self.paramlist = []
43 self.paramvec = []
44 self.paramaction = []
45 self.paramprop = []
46 self.paramset = []
47 self.props = []
48 self.chromium = []
49
50
51
52def ProcessSpecFile(filename, userFunc):
53 """Open the named API spec file and call userFunc(record) for each record
54 processed."""
55 specFile = open(filename, "r")
56 if not specFile:
57 print "Error: couldn't open %s file!" % filename
58 sys.exit()
59
60 record = APIFunction()
61
62 for line in specFile.readlines():
63
64 # split line into tokens
65 tokens = string.split(line)
66
67 if len(tokens) > 0 and line[0] != '#':
68
69 if tokens[0] == 'name':
70 if record.name != '':
71 # process the function now
72 userFunc(record)
73 # reset the record
74 record = APIFunction()
75
76 record.name = tokens[1]
77
78 elif tokens[0] == 'return':
79 record.returnType = string.join(tokens[1:], ' ')
80
81 elif tokens[0] == 'param':
82 name = tokens[1]
83 type = string.join(tokens[2:], ' ')
84 vecSize = 0
85 record.params.append((name, type, vecSize))
86
87 elif tokens[0] == 'paramprop':
88 name = tokens[1]
89 str = tokens[2:]
90 enums = []
91 for i in range(len(str)):
92 enums.append(str[i])
93 record.paramprop.append((name, enums))
94
95 elif tokens[0] == 'paramlist':
96 name = tokens[1]
97 str = tokens[2:]
98 list = []
99 for i in range(len(str)):
100 list.append(str[i])
101 record.paramlist.append((name,list))
102
103 elif tokens[0] == 'paramvec':
104 name = tokens[1]
105 str = tokens[2:]
106 vec = []
107 for i in range(len(str)):
108 vec.append(str[i])
109 record.paramvec.append((name,vec))
110
111 elif tokens[0] == 'paramset':
112 line = tokens[1:]
113 result = []
114 for i in range(len(line)):
115 tset = line[i]
116 if tset == '[':
117 nlist = []
118 elif tset == ']':
119 result.append(nlist)
120 nlist = []
121 else:
122 nlist.append(tset)
123 if result != []:
124 record.paramset.append(result)
125
126 elif tokens[0] == 'paramaction':
127 name = tokens[1]
128 str = tokens[2:]
129 list = []
130 for i in range(len(str)):
131 list.append(str[i])
132 record.paramaction.append((name,list))
133
134 elif tokens[0] == 'category':
135 record.category = tokens[1]
136
137 elif tokens[0] == 'offset':
138 if tokens[1] == '?':
139 record.offset = -2
140 else:
141 record.offset = int(tokens[1])
142
143 elif tokens[0] == 'alias':
144 record.alias = tokens[1]
145
146 elif tokens[0] == 'vectoralias':
147 record.vectoralias = tokens[1]
148
149 elif tokens[0] == 'props':
150 record.props = tokens[1:]
151
152 elif tokens[0] == 'chromium':
153 record.chromium = tokens[1:]
154
155 elif tokens[0] == 'vector':
156 vecName = tokens[1]
157 vecSize = int(tokens[2])
158 for i in range(len(record.params)):
159 (name, type, oldSize) = record.params[i]
160 if name == vecName:
161 record.params[i] = (name, type, vecSize)
162 break
163
164 else:
165 print 'Invalid token %s after function %s' % (tokens[0], record.name)
166 #endif
167 #endif
168 #endfor
169 specFile.close()
170#enddef
171
172
173
174
175
176# Dictionary [name] of APIFunction:
177__FunctionDict = {}
178
179# Dictionary [name] of name
180__VectorVersion = {}
181
182# Reverse mapping of function name aliases
183__ReverseAliases = {}
184
185
186def AddFunction(record):
187 assert not __FunctionDict.has_key(record.name)
188 #if not "omit" in record.chromium:
189 __FunctionDict[record.name] = record
190
191
192
193def GetFunctionDict(specFile = ""):
194 if not specFile:
195 specFile = sys.argv[1]+"/APIspec.txt"
196 if len(__FunctionDict) == 0:
197 ProcessSpecFile(specFile, AddFunction)
198 # Look for vector aliased functions
199 for func in __FunctionDict.keys():
200 va = __FunctionDict[func].vectoralias
201 if va != '':
202 __VectorVersion[va] = func
203 #endif
204
205 # and look for regular aliases (for glloader)
206 a = __FunctionDict[func].alias
207 if a:
208 __ReverseAliases[a] = func
209 #endif
210 #endfor
211 #endif
212 return __FunctionDict
213
214
215def GetAllFunctions(specFile = ""):
216 """Return sorted list of all functions known to Chromium."""
217 d = GetFunctionDict(specFile)
218 funcs = []
219 for func in d.keys():
220 rec = d[func]
221 if not "omit" in rec.chromium:
222 funcs.append(func)
223 funcs.sort()
224 return funcs
225
226def GetAllFunctionsAndOmittedAliases(specFile = ""):
227 """Return sorted list of all functions known to Chromium."""
228 d = GetFunctionDict(specFile)
229 funcs = []
230 for func in d.keys():
231 rec = d[func]
232 if (not "omit" in rec.chromium or
233 rec.alias != ''):
234 funcs.append(func)
235 funcs.sort()
236 return funcs
237
238def GetDispatchedFunctions(specFile = ""):
239 """Return sorted list of all functions handled by SPU dispatch table."""
240 d = GetFunctionDict(specFile)
241 funcs = []
242 for func in d.keys():
243 rec = d[func]
244 if (not "omit" in rec.chromium and
245 not "stub" in rec.chromium and
246 rec.alias == ''):
247 funcs.append(func)
248 funcs.sort()
249 return funcs
250
251#======================================================================
252
253def ReturnType(funcName):
254 """Return the C return type of named function.
255 Examples: "void" or "const GLubyte *". """
256 d = GetFunctionDict()
257 return d[funcName].returnType
258
259
260def Parameters(funcName):
261 """Return list of tuples (name, type, vecSize) of function parameters.
262 Example: if funcName=="ClipPlane" return
263 [ ("plane", "GLenum", 0), ("equation", "const GLdouble *", 4) ] """
264 d = GetFunctionDict()
265 return d[funcName].params
266
267def ParamAction(funcName):
268 """Return list of names of actions for testing.
269 For PackerTest only."""
270 d = GetFunctionDict()
271 return d[funcName].paramaction
272
273def ParamList(funcName):
274 """Return list of tuples (name, list of values) of function parameters.
275 For PackerTest only."""
276 d = GetFunctionDict()
277 return d[funcName].paramlist
278
279def ParamVec(funcName):
280 """Return list of tuples (name, vector of values) of function parameters.
281 For PackerTest only."""
282 d = GetFunctionDict()
283 return d[funcName].paramvec
284
285def ParamSet(funcName):
286 """Return list of tuples (name, list of values) of function parameters.
287 For PackerTest only."""
288 d = GetFunctionDict()
289 return d[funcName].paramset
290
291
292def Properties(funcName):
293 """Return list of properties of the named GL function."""
294 d = GetFunctionDict()
295 return d[funcName].props
296
297def AllWithProperty(property):
298 """Return list of functions that have the named property."""
299 funcs = []
300 for funcName in GetDispatchedFunctions():
301 if property in Properties(funcName):
302 funcs.append(funcName)
303 return funcs
304
305def Category(funcName):
306 """Return the category of the named GL function."""
307 d = GetFunctionDict()
308 return d[funcName].category
309
310def ChromiumProps(funcName):
311 """Return list of Chromium-specific properties of the named GL function."""
312 d = GetFunctionDict()
313 return d[funcName].chromium
314
315def ParamProps(funcName):
316 """Return list of Parameter-specific properties of the named GL function."""
317 d = GetFunctionDict()
318 return d[funcName].paramprop
319
320def Alias(funcName):
321 """Return the function that the named function is an alias of.
322 Ex: Alias('DrawArraysEXT') = 'DrawArrays'.
323 """
324 d = GetFunctionDict()
325 return d[funcName].alias
326
327
328def ReverseAlias(funcName):
329 """Like Alias(), but the inverse."""
330 d = GetFunctionDict()
331 if funcName in __ReverseAliases.keys():
332 return __ReverseAliases[funcName]
333 else:
334 return ''
335
336
337def NonVectorFunction(funcName):
338 """Return the non-vector version of the given function, or ''.
339 For example: NonVectorFunction("Color3fv") = "Color3f"."""
340 d = GetFunctionDict()
341 return d[funcName].vectoralias
342
343
344def VectorFunction(funcName):
345 """Return the vector version of the given non-vector-valued function,
346 or ''.
347 For example: VectorVersion("Color3f") = "Color3fv"."""
348 d = GetFunctionDict()
349 if funcName in __VectorVersion.keys():
350 return __VectorVersion[funcName]
351 else:
352 return ''
353
354
355def GetCategoryWrapper(func_name):
356 """Return a C preprocessor token to test in order to wrap code.
357 This handles extensions.
358 Example: GetTestWrapper("glActiveTextureARB") = "CR_multitexture"
359 Example: GetTestWrapper("glBegin") = ""
360 """
361 cat = Category(func_name)
362 if (cat == "1.0" or
363 cat == "1.1" or
364 cat == "1.2" or
365 cat == "Chromium" or
366 cat == "GL_chromium" or
367 cat == "VBox"):
368 return ''
369 elif (cat == '1.3' or
370 cat == '1.4' or
371 cat == '1.5' or
372 cat == '2.0' or
373 cat == '2.1'):
374 # i.e. OpenGL 1.3 or 1.4 or 1.5
375 return "OPENGL_VERSION_" + string.replace(cat, ".", "_")
376 else:
377 assert cat != ''
378 return string.replace(cat, "GL_", "")
379
380
381def CanCompile(funcName):
382 """Return 1 if the function can be compiled into display lists, else 0."""
383 props = Properties(funcName)
384 if ("nolist" in props or
385 "get" in props or
386 "setclient" in props):
387 return 0
388 else:
389 return 1
390
391def HasChromiumProperty(funcName, propertyList):
392 """Return 1 if the function or any alias has any property in the
393 propertyList"""
394 for funcAlias in [funcName, NonVectorFunction(funcName), VectorFunction(funcName)]:
395 if funcAlias:
396 props = ChromiumProps(funcAlias)
397 for p in propertyList:
398 if p in props:
399 return 1
400 return 0
401
402def CanPack(funcName):
403 """Return 1 if the function can be packed, else 0."""
404 return HasChromiumProperty(funcName, ['pack', 'extpack', 'expandpack'])
405
406def HasPackOpcode(funcName):
407 """Return 1 if the function has a true pack opcode"""
408 return HasChromiumProperty(funcName, ['pack', 'extpack'])
409
410def SetsState(funcName):
411 """Return 1 if the function sets server-side state, else 0."""
412 props = Properties(funcName)
413
414 # Exceptions. The first set of these functions *do* have
415 # server-side state-changing effects, but will be missed
416 # by the general query, because they either render (e.g.
417 # Bitmap) or do not compile into display lists (e.g. all the others).
418 #
419 # The second set do *not* have server-side state-changing
420 # effects, despite the fact that they do not render
421 # and can be compiled. They are control functions
422 # that are not trackable via state.
423 if funcName in ['Bitmap', 'DeleteTextures', 'FeedbackBuffer',
424 'RenderMode', 'BindBufferARB', 'DeleteFencesNV']:
425 return 1
426 elif funcName in ['ExecuteProgramNV']:
427 return 0
428
429 # All compilable functions that do not render and that do
430 # not set or use client-side state (e.g. DrawArrays, et al.), set
431 # server-side state.
432 if CanCompile(funcName) and "render" not in props and "useclient" not in props and "setclient" not in props:
433 return 1
434
435 # All others don't set server-side state.
436 return 0
437
438def SetsClientState(funcName):
439 """Return 1 if the function sets client-side state, else 0."""
440 props = Properties(funcName)
441 if "setclient" in props:
442 return 1
443 return 0
444
445def SetsTrackedState(funcName):
446 """Return 1 if the function sets state that is tracked by
447 the state tracker, else 0."""
448 # These functions set state, but aren't tracked by the state
449 # tracker for various reasons:
450 # - because the state tracker doesn't manage display lists
451 # (e.g. CallList and CallLists)
452 # - because the client doesn't have information about what
453 # the server supports, so the function has to go to the
454 # server (e.g. CompressedTexImage calls)
455 # - because they require a round-trip to the server (e.g.
456 # the CopyTexImage calls, SetFenceNV, TrackMatrixNV)
457 if funcName in [
458 'CopyTexImage1D', 'CopyTexImage2D',
459 'CopyTexSubImage1D', 'CopyTexSubImage2D', 'CopyTexSubImage3D',
460 'CallList', 'CallLists',
461 'CompressedTexImage1DARB', 'CompressedTexSubImage1DARB',
462 'CompressedTexImage2DARB', 'CompressedTexSubImage2DARB',
463 'CompressedTexImage3DARB', 'CompressedTexSubImage3DARB',
464 'SetFenceNV'
465 ]:
466 return 0
467
468 # Anything else that affects client-side state is trackable.
469 if SetsClientState(funcName):
470 return 1
471
472 # Anything else that doesn't set state at all is certainly
473 # not trackable.
474 if not SetsState(funcName):
475 return 0
476
477 # Per-vertex state isn't tracked the way other state is
478 # tracked, so it is specifically excluded.
479 if "pervertex" in Properties(funcName):
480 return 0
481
482 # Everything else is fine
483 return 1
484
485def UsesClientState(funcName):
486 """Return 1 if the function uses client-side state, else 0."""
487 props = Properties(funcName)
488 if "pixelstore" in props or "useclient" in props:
489 return 1
490 return 0
491
492def IsQuery(funcName):
493 """Return 1 if the function returns information to the user, else 0."""
494 props = Properties(funcName)
495 if "get" in props:
496 return 1
497 return 0
498
499def FuncGetsState(funcName):
500 """Return 1 if the function gets GL state, else 0."""
501 d = GetFunctionDict()
502 props = Properties(funcName)
503 if "get" in props:
504 return 1
505 else:
506 return 0
507
508def IsPointer(dataType):
509 """Determine if the datatype is a pointer. Return 1 or 0."""
510 if string.find(dataType, "*") == -1:
511 return 0
512 else:
513 return 1
514
515
516def PointerType(pointerType):
517 """Return the type of a pointer.
518 Ex: PointerType('const GLubyte *') = 'GLubyte'
519 """
520 t = string.split(pointerType, ' ')
521 if t[0] == "const":
522 t[0] = t[1]
523 return t[0]
524
525
526
527
528def OpcodeName(funcName):
529 """Return the C token for the opcode for the given function."""
530 return "CR_" + string.upper(funcName) + "_OPCODE"
531
532
533def ExtendedOpcodeName(funcName):
534 """Return the C token for the extended opcode for the given function."""
535 return "CR_" + string.upper(funcName) + "_EXTEND_OPCODE"
536
537
538
539
540#======================================================================
541
542def MakeCallString(params):
543 """Given a list of (name, type, vectorSize) parameters, make a C-style
544 formal parameter string.
545 Ex return: 'index, x, y, z'.
546 """
547 result = ''
548 i = 1
549 n = len(params)
550 for (name, type, vecSize) in params:
551 result += name
552 if i < n:
553 result = result + ', '
554 i += 1
555 #endfor
556 return result
557#enddef
558
559
560def MakeDeclarationString(params):
561 """Given a list of (name, type, vectorSize) parameters, make a C-style
562 parameter declaration string.
563 Ex return: 'GLuint index, GLfloat x, GLfloat y, GLfloat z'.
564 """
565 n = len(params)
566 if n == 0:
567 return 'void'
568 else:
569 result = ''
570 i = 1
571 for (name, type, vecSize) in params:
572 result = result + type + ' ' + name
573 if i < n:
574 result = result + ', '
575 i += 1
576 #endfor
577 return result
578 #endif
579#enddef
580
581def MakeDeclarationStringWithContext(ctx_macro_prefix, params):
582 """Same as MakeDeclarationString, but adds a context macro
583 """
584
585 n = len(params)
586 if n == 0:
587 return ctx_macro_prefix + '_ARGSINGLEDECL'
588 else:
589 result = MakeDeclarationString(params)
590 return ctx_macro_prefix + '_ARGDECL ' + result
591 #endif
592#enddef
593
594
595def MakePrototypeString(params):
596 """Given a list of (name, type, vectorSize) parameters, make a C-style
597 parameter prototype string (types only).
598 Ex return: 'GLuint, GLfloat, GLfloat, GLfloat'.
599 """
600 n = len(params)
601 if n == 0:
602 return 'void'
603 else:
604 result = ''
605 i = 1
606 for (name, type, vecSize) in params:
607 result = result + type
608 # see if we need a comma separator
609 if i < n:
610 result = result + ', '
611 i += 1
612 #endfor
613 return result
614 #endif
615#enddef
616
617
618#======================================================================
619
620__lengths = {
621 'GLbyte': 1,
622 'GLubyte': 1,
623 'GLshort': 2,
624 'GLushort': 2,
625 'GLint': 4,
626 'GLuint': 4,
627 'GLfloat': 4,
628 'GLclampf': 4,
629 'GLdouble': 8,
630 'GLclampd': 8,
631 'GLenum': 4,
632 'GLboolean': 1,
633 'GLsizei': 4,
634 'GLbitfield': 4,
635 'void': 0, # XXX why?
636 'int': 4,
637 'GLintptrARB': 4, # XXX or 8 bytes?
638 'GLsizeiptrARB': 4, # XXX or 8 bytes?
639 'GLhandleARB': 4,
640 'GLcharARB': 1,
641 'uintptr_t': 4
642}
643
644def sizeof(type):
645 """Return size of C datatype, in bytes."""
646 if not type in __lengths.keys():
647 print >>sys.stderr, "%s not in lengths!" % type
648 return __lengths[type]
649
650
651#======================================================================
652align_types = 1
653
654def FixAlignment( pos, alignment ):
655 # if we want double-alignment take word-alignment instead,
656 # yes, this is super-lame, but we know what we are doing
657 if alignment > 4:
658 alignment = 4
659 if align_types and alignment and ( pos % alignment ):
660 pos += alignment - ( pos % alignment )
661 return pos
662
663def WordAlign( pos ):
664 return FixAlignment( pos, 4 )
665
666def PointerSize():
667 return 8 # Leave room for a 64 bit pointer
668
669def PacketLength( params ):
670 len = 0
671 for (name, type, vecSize) in params:
672 if IsPointer(type):
673 size = PointerSize()
674 else:
675 assert string.find(type, "const") == -1
676 size = sizeof(type)
677 len = FixAlignment( len, size ) + size
678 len = WordAlign( len )
679 return len
680
681#======================================================================
682
683__specials = {}
684
685def LoadSpecials( filename ):
686 table = {}
687 try:
688 f = open( filename, "r" )
689 except:
690# try:
691 f = open( sys.argv[2]+"/"+filename, "r")
692# except:
693# __specials[filename] = {}
694# print "%s not present" % filename
695# return {}
696
697 for line in f.readlines():
698 line = string.strip(line)
699 if line == "" or line[0] == '#':
700 continue
701 table[line] = 1
702
703 __specials[filename] = table
704 return table
705
706
707def FindSpecial( table_file, glName ):
708 table = {}
709 filename = table_file + "_special"
710 try:
711 table = __specials[filename]
712 except KeyError:
713 table = LoadSpecials( filename )
714
715 try:
716 if (table[glName] == 1):
717 return 1
718 else:
719 return 0 #should never happen
720 except KeyError:
721 return 0
722
723
724def AllSpecials( table_file ):
725 table = {}
726 filename = table_file + "_special"
727 try:
728 table = __specials[filename]
729 except KeyError:
730 table = LoadSpecials( filename )
731
732 keys = table.keys()
733 keys.sort()
734 return keys
735
736
737def AllSpecials( table_file ):
738 filename = table_file + "_special"
739 table = {}
740 try:
741 table = __specials[filename]
742 except KeyError:
743 table = LoadSpecials(filename)
744
745 ret = table.keys()
746 ret.sort()
747 return ret
748
749
750def NumSpecials( table_file ):
751 filename = table_file + "_special"
752 table = {}
753 try:
754 table = __specials[filename]
755 except KeyError:
756 table = LoadSpecials(filename)
757 return len(table.keys())
758
759def PrintRecord(record):
760 argList = MakeDeclarationString(record.params)
761 if record.category == "Chromium":
762 prefix = "cr"
763 else:
764 prefix = "gl"
765 print '%s %s%s(%s);' % (record.returnType, prefix, record.name, argList )
766 if len(record.props) > 0:
767 print ' /* %s */' % string.join(record.props, ' ')
768
769#ProcessSpecFile("APIspec.txt", PrintRecord)
770
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette