VirtualBox

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

Last change on this file since 18847 was 15532, checked in by vboxsync, 16 years ago

crOpenGL: export to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 17.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
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
226
227def GetDispatchedFunctions(specFile = ""):
228 """Return sorted list of all functions handled by SPU dispatch table."""
229 d = GetFunctionDict(specFile)
230 funcs = []
231 for func in d.keys():
232 rec = d[func]
233 if (not "omit" in rec.chromium and
234 not "stub" in rec.chromium and
235 rec.alias == ''):
236 funcs.append(func)
237 funcs.sort()
238 return funcs
239
240#======================================================================
241
242def ReturnType(funcName):
243 """Return the C return type of named function.
244 Examples: "void" or "const GLubyte *". """
245 d = GetFunctionDict()
246 return d[funcName].returnType
247
248
249def Parameters(funcName):
250 """Return list of tuples (name, type, vecSize) of function parameters.
251 Example: if funcName=="ClipPlane" return
252 [ ("plane", "GLenum", 0), ("equation", "const GLdouble *", 4) ] """
253 d = GetFunctionDict()
254 return d[funcName].params
255
256def ParamAction(funcName):
257 """Return list of names of actions for testing.
258 For PackerTest only."""
259 d = GetFunctionDict()
260 return d[funcName].paramaction
261
262def ParamList(funcName):
263 """Return list of tuples (name, list of values) of function parameters.
264 For PackerTest only."""
265 d = GetFunctionDict()
266 return d[funcName].paramlist
267
268def ParamVec(funcName):
269 """Return list of tuples (name, vector of values) of function parameters.
270 For PackerTest only."""
271 d = GetFunctionDict()
272 return d[funcName].paramvec
273
274def ParamSet(funcName):
275 """Return list of tuples (name, list of values) of function parameters.
276 For PackerTest only."""
277 d = GetFunctionDict()
278 return d[funcName].paramset
279
280
281def Properties(funcName):
282 """Return list of properties of the named GL function."""
283 d = GetFunctionDict()
284 return d[funcName].props
285
286def AllWithProperty(property):
287 """Return list of functions that have the named property."""
288 funcs = []
289 for funcName in GetDispatchedFunctions():
290 if property in Properties(funcName):
291 funcs.append(funcName)
292 return funcs
293
294def Category(funcName):
295 """Return the category of the named GL function."""
296 d = GetFunctionDict()
297 return d[funcName].category
298
299def ChromiumProps(funcName):
300 """Return list of Chromium-specific properties of the named GL function."""
301 d = GetFunctionDict()
302 return d[funcName].chromium
303
304def ParamProps(funcName):
305 """Return list of Parameter-specific properties of the named GL function."""
306 d = GetFunctionDict()
307 return d[funcName].paramprop
308
309def Alias(funcName):
310 """Return the function that the named function is an alias of.
311 Ex: Alias('DrawArraysEXT') = 'DrawArrays'.
312 """
313 d = GetFunctionDict()
314 return d[funcName].alias
315
316
317def ReverseAlias(funcName):
318 """Like Alias(), but the inverse."""
319 d = GetFunctionDict()
320 if funcName in __ReverseAliases.keys():
321 return __ReverseAliases[funcName]
322 else:
323 return ''
324
325
326def NonVectorFunction(funcName):
327 """Return the non-vector version of the given function, or ''.
328 For example: NonVectorFunction("Color3fv") = "Color3f"."""
329 d = GetFunctionDict()
330 return d[funcName].vectoralias
331
332
333def VectorFunction(funcName):
334 """Return the vector version of the given non-vector-valued function,
335 or ''.
336 For example: VectorVersion("Color3f") = "Color3fv"."""
337 d = GetFunctionDict()
338 if funcName in __VectorVersion.keys():
339 return __VectorVersion[funcName]
340 else:
341 return ''
342
343
344def GetCategoryWrapper(func_name):
345 """Return a C preprocessor token to test in order to wrap code.
346 This handles extensions.
347 Example: GetTestWrapper("glActiveTextureARB") = "CR_multitexture"
348 Example: GetTestWrapper("glBegin") = ""
349 """
350 cat = Category(func_name)
351 if (cat == "1.0" or
352 cat == "1.1" or
353 cat == "1.2" or
354 cat == "Chromium" or
355 cat == "GL_chromium"):
356 return ''
357 elif cat[0] =='1':
358 # i.e. OpenGL 1.3 or 1.4 or 1.5
359 return "OPENGL_VERSION_" + string.replace(cat, ".", "_")
360 else:
361 assert cat != ''
362 return string.replace(cat, "GL_", "")
363
364
365def CanCompile(funcName):
366 """Return 1 if the function can be compiled into display lists, else 0."""
367 props = Properties(funcName)
368 if ("nolist" in props or
369 "get" in props or
370 "setclient" in props):
371 return 0
372 else:
373 return 1
374
375def HasChromiumProperty(funcName, propertyList):
376 """Return 1 if the function or any alias has any property in the
377 propertyList"""
378 for funcAlias in [funcName, NonVectorFunction(funcName), VectorFunction(funcName)]:
379 if funcAlias:
380 props = ChromiumProps(funcAlias)
381 for p in propertyList:
382 if p in props:
383 return 1
384 return 0
385
386def CanPack(funcName):
387 """Return 1 if the function can be packed, else 0."""
388 return HasChromiumProperty(funcName, ['pack', 'extpack', 'expandpack'])
389
390def HasPackOpcode(funcName):
391 """Return 1 if the function has a true pack opcode"""
392 return HasChromiumProperty(funcName, ['pack', 'extpack'])
393
394def SetsState(funcName):
395 """Return 1 if the function sets server-side state, else 0."""
396 props = Properties(funcName)
397
398 # Exceptions. The first set of these functions *do* have
399 # server-side state-changing effects, but will be missed
400 # by the general query, because they either render (e.g.
401 # Bitmap) or do not compile into display lists (e.g. all the others).
402 #
403 # The second set do *not* have server-side state-changing
404 # effects, despite the fact that they do not render
405 # and can be compiled. They are control functions
406 # that are not trackable via state.
407 if funcName in ['Bitmap', 'DeleteTextures', 'FeedbackBuffer',
408 'RenderMode', 'BindBufferARB', 'DeleteFencesNV']:
409 return 1
410 elif funcName in ['ExecuteProgramNV']:
411 return 0
412
413 # All compilable functions that do not render and that do
414 # not set or use client-side state (e.g. DrawArrays, et al.), set
415 # server-side state.
416 if CanCompile(funcName) and "render" not in props and "useclient" not in props and "setclient" not in props:
417 return 1
418
419 # All others don't set server-side state.
420 return 0
421
422def SetsClientState(funcName):
423 """Return 1 if the function sets client-side state, else 0."""
424 props = Properties(funcName)
425 if "setclient" in props:
426 return 1
427 return 0
428
429def SetsTrackedState(funcName):
430 """Return 1 if the function sets state that is tracked by
431 the state tracker, else 0."""
432 # These functions set state, but aren't tracked by the state
433 # tracker for various reasons:
434 # - because the state tracker doesn't manage display lists
435 # (e.g. CallList and CallLists)
436 # - because the client doesn't have information about what
437 # the server supports, so the function has to go to the
438 # server (e.g. CompressedTexImage calls)
439 # - because they require a round-trip to the server (e.g.
440 # the CopyTexImage calls, SetFenceNV, TrackMatrixNV)
441 if funcName in [
442 'CopyTexImage1D', 'CopyTexImage2D',
443 'CopyTexSubImage1D', 'CopyTexSubImage2D', 'CopyTexSubImage3D',
444 'CallList', 'CallLists',
445 'CompressedTexImage1DARB', 'CompressedTexSubImage1DARB',
446 'CompressedTexImage2DARB', 'CompressedTexSubImage2DARB',
447 'CompressedTexImage3DARB', 'CompressedTexSubImage3DARB',
448 'SetFenceNV'
449 ]:
450 return 0
451
452 # Anything else that affects client-side state is trackable.
453 if SetsClientState(funcName):
454 return 1
455
456 # Anything else that doesn't set state at all is certainly
457 # not trackable.
458 if not SetsState(funcName):
459 return 0
460
461 # Per-vertex state isn't tracked the way other state is
462 # tracked, so it is specifically excluded.
463 if "pervertex" in Properties(funcName):
464 return 0
465
466 # Everything else is fine
467 return 1
468
469def UsesClientState(funcName):
470 """Return 1 if the function uses client-side state, else 0."""
471 props = Properties(funcName)
472 if "pixelstore" in props or "useclient" in props:
473 return 1
474 return 0
475
476def IsQuery(funcName):
477 """Return 1 if the function returns information to the user, else 0."""
478 props = Properties(funcName)
479 if "get" in props:
480 return 1
481 return 0
482
483def FuncGetsState(funcName):
484 """Return 1 if the function gets GL state, else 0."""
485 d = GetFunctionDict()
486 props = Properties(funcName)
487 if "get" in props:
488 return 1
489 else:
490 return 0
491
492def IsPointer(dataType):
493 """Determine if the datatype is a pointer. Return 1 or 0."""
494 if string.find(dataType, "*") == -1:
495 return 0
496 else:
497 return 1
498
499
500def PointerType(pointerType):
501 """Return the type of a pointer.
502 Ex: PointerType('const GLubyte *') = 'GLubyte'
503 """
504 t = string.split(pointerType, ' ')
505 if t[0] == "const":
506 t[0] = t[1]
507 return t[0]
508
509
510
511
512def OpcodeName(funcName):
513 """Return the C token for the opcode for the given function."""
514 return "CR_" + string.upper(funcName) + "_OPCODE"
515
516
517def ExtendedOpcodeName(funcName):
518 """Return the C token for the extended opcode for the given function."""
519 return "CR_" + string.upper(funcName) + "_EXTEND_OPCODE"
520
521
522
523
524#======================================================================
525
526def MakeCallString(params):
527 """Given a list of (name, type, vectorSize) parameters, make a C-style
528 formal parameter string.
529 Ex return: 'index, x, y, z'.
530 """
531 result = ''
532 i = 1
533 n = len(params)
534 for (name, type, vecSize) in params:
535 result += name
536 if i < n:
537 result = result + ', '
538 i += 1
539 #endfor
540 return result
541#enddef
542
543
544def MakeDeclarationString(params):
545 """Given a list of (name, type, vectorSize) parameters, make a C-style
546 parameter declaration string.
547 Ex return: 'GLuint index, GLfloat x, GLfloat y, GLfloat z'.
548 """
549 n = len(params)
550 if n == 0:
551 return 'void'
552 else:
553 result = ''
554 i = 1
555 for (name, type, vecSize) in params:
556 result = result + type + ' ' + name
557 if i < n:
558 result = result + ', '
559 i += 1
560 #endfor
561 return result
562 #endif
563#enddef
564
565
566def MakePrototypeString(params):
567 """Given a list of (name, type, vectorSize) parameters, make a C-style
568 parameter prototype string (types only).
569 Ex return: 'GLuint, GLfloat, GLfloat, GLfloat'.
570 """
571 n = len(params)
572 if n == 0:
573 return 'void'
574 else:
575 result = ''
576 i = 1
577 for (name, type, vecSize) in params:
578 result = result + type
579 # see if we need a comma separator
580 if i < n:
581 result = result + ', '
582 i += 1
583 #endfor
584 return result
585 #endif
586#enddef
587
588
589#======================================================================
590
591__lengths = {
592 'GLbyte': 1,
593 'GLubyte': 1,
594 'GLshort': 2,
595 'GLushort': 2,
596 'GLint': 4,
597 'GLuint': 4,
598 'GLfloat': 4,
599 'GLclampf': 4,
600 'GLdouble': 8,
601 'GLclampd': 8,
602 'GLenum': 4,
603 'GLboolean': 1,
604 'GLsizei': 4,
605 'GLbitfield': 4,
606 'void': 0, # XXX why?
607 'int': 4,
608 'GLintptrARB': 4, # XXX or 8 bytes?
609 'GLsizeiptrARB': 4 # XXX or 8 bytes?
610}
611
612def sizeof(type):
613 """Return size of C datatype, in bytes."""
614 if not type in __lengths.keys():
615 print >>sys.stderr, "%s not in lengths!" % type
616 return __lengths[type]
617
618
619#======================================================================
620align_types = 1
621
622def FixAlignment( pos, alignment ):
623 # if we want double-alignment take word-alignment instead,
624 # yes, this is super-lame, but we know what we are doing
625 if alignment > 4:
626 alignment = 4
627 if align_types and alignment and ( pos % alignment ):
628 pos += alignment - ( pos % alignment )
629 return pos
630
631def WordAlign( pos ):
632 return FixAlignment( pos, 4 )
633
634def PointerSize():
635 return 8 # Leave room for a 64 bit pointer
636
637def PacketLength( params ):
638 len = 0
639 for (name, type, vecSize) in params:
640 if IsPointer(type):
641 size = PointerSize()
642 else:
643 assert string.find(type, "const") == -1
644 size = sizeof(type)
645 len = FixAlignment( len, size ) + size
646 len = WordAlign( len )
647 return len
648
649#======================================================================
650
651__specials = {}
652
653def LoadSpecials( filename ):
654 table = {}
655 try:
656 f = open( filename, "r" )
657 except:
658# try:
659 f = open( sys.argv[2]+"/"+filename, "r")
660# except:
661# __specials[filename] = {}
662# print "%s not present" % filename
663# return {}
664
665 for line in f.readlines():
666 line = string.strip(line)
667 if line == "" or line[0] == '#':
668 continue
669 table[line] = 1
670
671 __specials[filename] = table
672 return table
673
674
675def FindSpecial( table_file, glName ):
676 table = {}
677 filename = table_file + "_special"
678 try:
679 table = __specials[filename]
680 except KeyError:
681 table = LoadSpecials( filename )
682
683 try:
684 if (table[glName] == 1):
685 return 1
686 else:
687 return 0 #should never happen
688 except KeyError:
689 return 0
690
691
692def AllSpecials( table_file ):
693 table = {}
694 filename = table_file + "_special"
695 try:
696 table = __specials[filename]
697 except KeyError:
698 table = LoadSpecials( filename )
699
700 keys = table.keys()
701 keys.sort()
702 return keys
703
704
705def AllSpecials( table_file ):
706 filename = table_file + "_special"
707 table = {}
708 try:
709 table = __specials[filename]
710 except KeyError:
711 table = LoadSpecials(filename)
712
713 ret = table.keys()
714 ret.sort()
715 return ret
716
717
718def NumSpecials( table_file ):
719 filename = table_file + "_special"
720 table = {}
721 try:
722 table = __specials[filename]
723 except KeyError:
724 table = LoadSpecials(filename)
725 return len(table.keys())
726
727def PrintRecord(record):
728 argList = MakeDeclarationString(record.params)
729 if record.category == "Chromium":
730 prefix = "cr"
731 else:
732 prefix = "gl"
733 print '%s %s%s(%s);' % (record.returnType, prefix, record.name, argList )
734 if len(record.props) > 0:
735 print ' /* %s */' % string.join(record.props, ' ')
736
737#ProcessSpecFile("APIspec.txt", PrintRecord)
738
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