VirtualBox

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

最後變更 在這個檔案從26936是 20467,由 vboxsync 提交於 16 年 前

crOpenGL: aliases for pre opengl2.0 arb extensions

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 17.6 KB
 
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 == '1.3' or
358 cat == '1.4' or
359 cat == '1.5' or
360 cat == '2.0'):
361 # i.e. OpenGL 1.3 or 1.4 or 1.5
362 return "OPENGL_VERSION_" + string.replace(cat, ".", "_")
363 else:
364 assert cat != ''
365 return string.replace(cat, "GL_", "")
366
367
368def CanCompile(funcName):
369 """Return 1 if the function can be compiled into display lists, else 0."""
370 props = Properties(funcName)
371 if ("nolist" in props or
372 "get" in props or
373 "setclient" in props):
374 return 0
375 else:
376 return 1
377
378def HasChromiumProperty(funcName, propertyList):
379 """Return 1 if the function or any alias has any property in the
380 propertyList"""
381 for funcAlias in [funcName, NonVectorFunction(funcName), VectorFunction(funcName)]:
382 if funcAlias:
383 props = ChromiumProps(funcAlias)
384 for p in propertyList:
385 if p in props:
386 return 1
387 return 0
388
389def CanPack(funcName):
390 """Return 1 if the function can be packed, else 0."""
391 return HasChromiumProperty(funcName, ['pack', 'extpack', 'expandpack'])
392
393def HasPackOpcode(funcName):
394 """Return 1 if the function has a true pack opcode"""
395 return HasChromiumProperty(funcName, ['pack', 'extpack'])
396
397def SetsState(funcName):
398 """Return 1 if the function sets server-side state, else 0."""
399 props = Properties(funcName)
400
401 # Exceptions. The first set of these functions *do* have
402 # server-side state-changing effects, but will be missed
403 # by the general query, because they either render (e.g.
404 # Bitmap) or do not compile into display lists (e.g. all the others).
405 #
406 # The second set do *not* have server-side state-changing
407 # effects, despite the fact that they do not render
408 # and can be compiled. They are control functions
409 # that are not trackable via state.
410 if funcName in ['Bitmap', 'DeleteTextures', 'FeedbackBuffer',
411 'RenderMode', 'BindBufferARB', 'DeleteFencesNV']:
412 return 1
413 elif funcName in ['ExecuteProgramNV']:
414 return 0
415
416 # All compilable functions that do not render and that do
417 # not set or use client-side state (e.g. DrawArrays, et al.), set
418 # server-side state.
419 if CanCompile(funcName) and "render" not in props and "useclient" not in props and "setclient" not in props:
420 return 1
421
422 # All others don't set server-side state.
423 return 0
424
425def SetsClientState(funcName):
426 """Return 1 if the function sets client-side state, else 0."""
427 props = Properties(funcName)
428 if "setclient" in props:
429 return 1
430 return 0
431
432def SetsTrackedState(funcName):
433 """Return 1 if the function sets state that is tracked by
434 the state tracker, else 0."""
435 # These functions set state, but aren't tracked by the state
436 # tracker for various reasons:
437 # - because the state tracker doesn't manage display lists
438 # (e.g. CallList and CallLists)
439 # - because the client doesn't have information about what
440 # the server supports, so the function has to go to the
441 # server (e.g. CompressedTexImage calls)
442 # - because they require a round-trip to the server (e.g.
443 # the CopyTexImage calls, SetFenceNV, TrackMatrixNV)
444 if funcName in [
445 'CopyTexImage1D', 'CopyTexImage2D',
446 'CopyTexSubImage1D', 'CopyTexSubImage2D', 'CopyTexSubImage3D',
447 'CallList', 'CallLists',
448 'CompressedTexImage1DARB', 'CompressedTexSubImage1DARB',
449 'CompressedTexImage2DARB', 'CompressedTexSubImage2DARB',
450 'CompressedTexImage3DARB', 'CompressedTexSubImage3DARB',
451 'SetFenceNV'
452 ]:
453 return 0
454
455 # Anything else that affects client-side state is trackable.
456 if SetsClientState(funcName):
457 return 1
458
459 # Anything else that doesn't set state at all is certainly
460 # not trackable.
461 if not SetsState(funcName):
462 return 0
463
464 # Per-vertex state isn't tracked the way other state is
465 # tracked, so it is specifically excluded.
466 if "pervertex" in Properties(funcName):
467 return 0
468
469 # Everything else is fine
470 return 1
471
472def UsesClientState(funcName):
473 """Return 1 if the function uses client-side state, else 0."""
474 props = Properties(funcName)
475 if "pixelstore" in props or "useclient" in props:
476 return 1
477 return 0
478
479def IsQuery(funcName):
480 """Return 1 if the function returns information to the user, else 0."""
481 props = Properties(funcName)
482 if "get" in props:
483 return 1
484 return 0
485
486def FuncGetsState(funcName):
487 """Return 1 if the function gets GL state, else 0."""
488 d = GetFunctionDict()
489 props = Properties(funcName)
490 if "get" in props:
491 return 1
492 else:
493 return 0
494
495def IsPointer(dataType):
496 """Determine if the datatype is a pointer. Return 1 or 0."""
497 if string.find(dataType, "*") == -1:
498 return 0
499 else:
500 return 1
501
502
503def PointerType(pointerType):
504 """Return the type of a pointer.
505 Ex: PointerType('const GLubyte *') = 'GLubyte'
506 """
507 t = string.split(pointerType, ' ')
508 if t[0] == "const":
509 t[0] = t[1]
510 return t[0]
511
512
513
514
515def OpcodeName(funcName):
516 """Return the C token for the opcode for the given function."""
517 return "CR_" + string.upper(funcName) + "_OPCODE"
518
519
520def ExtendedOpcodeName(funcName):
521 """Return the C token for the extended opcode for the given function."""
522 return "CR_" + string.upper(funcName) + "_EXTEND_OPCODE"
523
524
525
526
527#======================================================================
528
529def MakeCallString(params):
530 """Given a list of (name, type, vectorSize) parameters, make a C-style
531 formal parameter string.
532 Ex return: 'index, x, y, z'.
533 """
534 result = ''
535 i = 1
536 n = len(params)
537 for (name, type, vecSize) in params:
538 result += name
539 if i < n:
540 result = result + ', '
541 i += 1
542 #endfor
543 return result
544#enddef
545
546
547def MakeDeclarationString(params):
548 """Given a list of (name, type, vectorSize) parameters, make a C-style
549 parameter declaration string.
550 Ex return: 'GLuint index, GLfloat x, GLfloat y, GLfloat z'.
551 """
552 n = len(params)
553 if n == 0:
554 return 'void'
555 else:
556 result = ''
557 i = 1
558 for (name, type, vecSize) in params:
559 result = result + type + ' ' + name
560 if i < n:
561 result = result + ', '
562 i += 1
563 #endfor
564 return result
565 #endif
566#enddef
567
568
569def MakePrototypeString(params):
570 """Given a list of (name, type, vectorSize) parameters, make a C-style
571 parameter prototype string (types only).
572 Ex return: 'GLuint, GLfloat, GLfloat, GLfloat'.
573 """
574 n = len(params)
575 if n == 0:
576 return 'void'
577 else:
578 result = ''
579 i = 1
580 for (name, type, vecSize) in params:
581 result = result + type
582 # see if we need a comma separator
583 if i < n:
584 result = result + ', '
585 i += 1
586 #endfor
587 return result
588 #endif
589#enddef
590
591
592#======================================================================
593
594__lengths = {
595 'GLbyte': 1,
596 'GLubyte': 1,
597 'GLshort': 2,
598 'GLushort': 2,
599 'GLint': 4,
600 'GLuint': 4,
601 'GLfloat': 4,
602 'GLclampf': 4,
603 'GLdouble': 8,
604 'GLclampd': 8,
605 'GLenum': 4,
606 'GLboolean': 1,
607 'GLsizei': 4,
608 'GLbitfield': 4,
609 'void': 0, # XXX why?
610 'int': 4,
611 'GLintptrARB': 4, # XXX or 8 bytes?
612 'GLsizeiptrARB': 4, # XXX or 8 bytes?
613 'GLhandleARB': 4,
614 'GLcharARB': 1
615}
616
617def sizeof(type):
618 """Return size of C datatype, in bytes."""
619 if not type in __lengths.keys():
620 print >>sys.stderr, "%s not in lengths!" % type
621 return __lengths[type]
622
623
624#======================================================================
625align_types = 1
626
627def FixAlignment( pos, alignment ):
628 # if we want double-alignment take word-alignment instead,
629 # yes, this is super-lame, but we know what we are doing
630 if alignment > 4:
631 alignment = 4
632 if align_types and alignment and ( pos % alignment ):
633 pos += alignment - ( pos % alignment )
634 return pos
635
636def WordAlign( pos ):
637 return FixAlignment( pos, 4 )
638
639def PointerSize():
640 return 8 # Leave room for a 64 bit pointer
641
642def PacketLength( params ):
643 len = 0
644 for (name, type, vecSize) in params:
645 if IsPointer(type):
646 size = PointerSize()
647 else:
648 assert string.find(type, "const") == -1
649 size = sizeof(type)
650 len = FixAlignment( len, size ) + size
651 len = WordAlign( len )
652 return len
653
654#======================================================================
655
656__specials = {}
657
658def LoadSpecials( filename ):
659 table = {}
660 try:
661 f = open( filename, "r" )
662 except:
663# try:
664 f = open( sys.argv[2]+"/"+filename, "r")
665# except:
666# __specials[filename] = {}
667# print "%s not present" % filename
668# return {}
669
670 for line in f.readlines():
671 line = string.strip(line)
672 if line == "" or line[0] == '#':
673 continue
674 table[line] = 1
675
676 __specials[filename] = table
677 return table
678
679
680def FindSpecial( table_file, glName ):
681 table = {}
682 filename = table_file + "_special"
683 try:
684 table = __specials[filename]
685 except KeyError:
686 table = LoadSpecials( filename )
687
688 try:
689 if (table[glName] == 1):
690 return 1
691 else:
692 return 0 #should never happen
693 except KeyError:
694 return 0
695
696
697def AllSpecials( table_file ):
698 table = {}
699 filename = table_file + "_special"
700 try:
701 table = __specials[filename]
702 except KeyError:
703 table = LoadSpecials( filename )
704
705 keys = table.keys()
706 keys.sort()
707 return keys
708
709
710def AllSpecials( table_file ):
711 filename = table_file + "_special"
712 table = {}
713 try:
714 table = __specials[filename]
715 except KeyError:
716 table = LoadSpecials(filename)
717
718 ret = table.keys()
719 ret.sort()
720 return ret
721
722
723def NumSpecials( table_file ):
724 filename = table_file + "_special"
725 table = {}
726 try:
727 table = __specials[filename]
728 except KeyError:
729 table = LoadSpecials(filename)
730 return len(table.keys())
731
732def PrintRecord(record):
733 argList = MakeDeclarationString(record.params)
734 if record.category == "Chromium":
735 prefix = "cr"
736 else:
737 prefix = "gl"
738 print '%s %s%s(%s);' % (record.returnType, prefix, record.name, argList )
739 if len(record.props) > 0:
740 print ' /* %s */' % string.join(record.props, ' ')
741
742#ProcessSpecFile("APIspec.txt", PrintRecord)
743
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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