VirtualBox

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

Last change on this file since 69400 was 69392, checked in by vboxsync, 7 years ago

GuestHost/OpenGL: scm updates

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