blob: 6eb2f553f9679f31d37a59cc4a704015692e555b [file] [log] [blame]
Ian Romanick74764062004-12-03 20:31:59 +00001#!/usr/bin/python2
2
Ian Romanick5f1f2292005-01-07 02:39:09 +00003# (C) Copyright IBM Corporation 2004, 2005
Ian Romanick74764062004-12-03 20:31:59 +00004# All Rights Reserved.
5#
6# Permission is hereby granted, free of charge, to any person obtaining a
7# copy of this software and associated documentation files (the "Software"),
8# to deal in the Software without restriction, including without limitation
9# on the rights to use, copy, modify, merge, publish, distribute, sub
10# license, and/or sell copies of the Software, and to permit persons to whom
11# the Software is furnished to do so, subject to the following conditions:
12#
13# The above copyright notice and this permission notice (including the next
14# paragraph) shall be included in all copies or substantial portions of the
15# Software.
16#
17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23# IN THE SOFTWARE.
24#
25# Authors:
26# Ian Romanick <idr@us.ibm.com>
27
28from xml.sax import saxutils
29from xml.sax import make_parser
30from xml.sax.handler import feature_namespaces
31
32import gl_XML
33import license
34import sys, getopt
35
36
37def printPure():
38 print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
39# define PURE __attribute__((pure))
40# else
41# define PURE
42# endif"""
43
44def printFastcall():
45 print """# if defined(__i386__) && defined(__GNUC__)
46# define FASTCALL __attribute__((fastcall))
47# else
48# define FASTCALL
49# endif"""
50
51def printVisibility(S, s):
52 print """# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
53# define %s __attribute__((visibility("%s")))
54# else
55# define %s
56# endif""" % (S, s, S)
57
58def printNoinline():
59 print """# if defined(__GNUC__)
60# define NOINLINE __attribute__((noinline))
61# else
62# define NOINLINE
63# endif"""
64
Ian Romanick7f958e92005-01-24 20:08:28 +000065def printHaveAlias():
66 print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
67# define HAVE_ALIAS
68# endif"""
Ian Romanick74764062004-12-03 20:31:59 +000069
70class glXItemFactory(gl_XML.glItemFactory):
71 """Factory to create GLX protocol oriented objects derived from glItem."""
72
73 def create(self, context, name, attrs):
74 if name == "function":
75 return glXFunction(context, name, attrs)
76 elif name == "enum":
77 return glXEnum(context, name, attrs)
78 elif name == "param":
79 return glXParameter(context, name, attrs)
80 else:
81 return gl_XML.glItemFactory.create(self, context, name, attrs)
82
83class glXEnumFunction:
84 def __init__(self, name):
85 self.name = name
Ian Romanick5aa6dc322005-01-27 01:08:48 +000086 self.mode = 0
87 self.sig = None
88
Ian Romanick74764062004-12-03 20:31:59 +000089 # "enums" is a set of lists. The element in the set is the
90 # value of the enum. The list is the list of names for that
91 # value. For example, [0x8126] = {"POINT_SIZE_MIN",
92 # "POINT_SIZE_MIN_ARB", "POINT_SIZE_MIN_EXT",
93 # "POINT_SIZE_MIN_SGIS"}.
94
95 self.enums = {}
96
97 # "count" is indexed by count values. Each element of count
98 # is a list of index to "enums" that have that number of
99 # associated data elements. For example, [4] =
100 # {GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION,
101 # GL_AMBIENT_AND_DIFFUSE} (the enum names are used here,
102 # but the actual hexadecimal values would be in the array).
103
104 self.count = {}
105
106
107 def append(self, count, value, name):
108 if self.enums.has_key( value ):
109 self.enums[value].append(name)
110 else:
111 if not self.count.has_key(count):
112 self.count[count] = []
113
114 self.enums[value] = []
115 self.enums[value].append(name)
116 self.count[count].append(value)
117
118
119 def signature( self ):
Ian Romanick5aa6dc322005-01-27 01:08:48 +0000120 if self.sig == None:
121 self.sig = ""
122 for i in self.count:
Ian Romanick82e22f52005-01-27 19:39:16 +0000123 self.count[i].sort()
Ian Romanick5aa6dc322005-01-27 01:08:48 +0000124 for e in self.count[i]:
125 self.sig += "%04x,%u," % (e, i)
Ian Romanick74764062004-12-03 20:31:59 +0000126
Ian Romanick5aa6dc322005-01-27 01:08:48 +0000127 return self.sig
128
129
130 def set_mode( self, mode ):
131 """Mark an enum-function as a 'set' function."""
132
133 self.mode = mode
134
135
136 def is_set( self ):
137 return self.mode
Ian Romanick74764062004-12-03 20:31:59 +0000138
139
140 def PrintUsingTable(self):
141 """Emit the body of the __gl*_size function using a pair
142 of look-up tables and a mask. The mask is calculated such
143 that (e & mask) is unique for all the valid values of e for
144 this function. The result of (e & mask) is used as an index
145 into the first look-up table. If it matches e, then the
146 same entry of the second table is returned. Otherwise zero
147 is returned.
148
149 It seems like this should cause better code to be generated.
150 However, on x86 at least, the resulting .o file is about 20%
151 larger then the switch-statment version. I am leaving this
152 code in because the results may be different on other
153 platforms (e.g., PowerPC or x86-64)."""
154
155 return 0
156 count = 0
157 for a in self.enums:
158 count += 1
159
160 # Determine if there is some mask M, such that M = (2^N) - 1,
161 # that will generate unique values for all of the enums.
162
163 mask = 0
164 for i in [1, 2, 3, 4, 5, 6, 7, 8]:
165 mask = (1 << i) - 1
166
167 fail = 0;
168 for a in self.enums:
169 for b in self.enums:
170 if a != b:
171 if (a & mask) == (b & mask):
172 fail = 1;
173
174 if not fail:
175 break;
176 else:
177 mask = 0
178
179 if (mask != 0) and (mask < (2 * count)):
180 masked_enums = {}
181 masked_count = {}
182
183 for i in range(0, mask + 1):
184 masked_enums[i] = "0";
185 masked_count[i] = 0;
186
187 for c in self.count:
188 for e in self.count[c]:
189 i = e & mask
190 masked_enums[i] = '0x%04x /* %s */' % (e, self.enums[e][0])
191 masked_count[i] = c
192
193
194 print ' static const GLushort a[%u] = {' % (mask + 1)
195 for e in masked_enums:
196 print ' %s, ' % (masked_enums[e])
197 print ' };'
198
199 print ' static const GLubyte b[%u] = {' % (mask + 1)
200 for c in masked_count:
201 print ' %u, ' % (masked_count[c])
202 print ' };'
203
204 print ' const unsigned idx = (e & 0x%02xU);' % (mask)
205 print ''
206 print ' return (e == a[idx]) ? (GLint) b[idx] : 0;'
207 return 1;
208 else:
209 return 0;
210
211 def PrintUsingSwitch(self):
212 """Emit the body of the __gl*_size function using a
213 switch-statement."""
214
215 print ' switch( e ) {'
216
217 for c in self.count:
218 for e in self.count[c]:
219 first = 1
220
221 # There may be multiple enums with the same
222 # value. This happens has extensions are
223 # promoted from vendor-specific or EXT to
224 # ARB and to the core. Emit the first one as
225 # a case label, and emit the others as
226 # commented-out case labels.
227
228 for j in self.enums[e]:
229 if first:
230 print ' case %s:' % (j)
231 first = 0
232 else:
233 print '/* case %s:*/' % (j)
234
235 print ' return %u;' % (c)
236
237 print ' default: return 0;'
238 print ' }'
239
240
241 def Print(self, name):
242 print 'INTERNAL PURE FASTCALL GLint'
243 print '__gl%s_size( GLenum e )' % (name)
244 print '{'
245
246 if not self.PrintUsingTable():
247 self.PrintUsingSwitch()
248
249 print '}'
250 print ''
251
252
253
254class glXEnum(gl_XML.glEnum):
255 def __init__(self, context, name, attrs):
256 gl_XML.glEnum.__init__(self, context, name, attrs)
Ian Romanick0246b2a2005-01-24 20:59:32 +0000257
Ian Romanick74764062004-12-03 20:31:59 +0000258
259 def startElement(self, name, attrs):
260 if name == "size":
Ian Romanick85f0fa32005-01-25 01:20:11 +0000261 [n, c, mode] = self.process_attributes(attrs)
Ian Romanick5ff2b942005-01-24 21:29:13 +0000262
Ian Romanick74764062004-12-03 20:31:59 +0000263 if not self.context.glx_enum_functions.has_key( n ):
264 f = glXEnumFunction( n )
Ian Romanick5aa6dc322005-01-27 01:08:48 +0000265 f.set_mode( mode )
Ian Romanick74764062004-12-03 20:31:59 +0000266 self.context.glx_enum_functions[ f.name ] = f
267
Ian Romanick74764062004-12-03 20:31:59 +0000268 self.context.glx_enum_functions[ n ].append( c, self.value, self.name )
269 else:
270 gl_XML.glEnum.startElement(self, context, name, attrs)
271 return
272
273
274class glXParameter(gl_XML.glParameter):
275 def __init__(self, context, name, attrs):
276 self.order = 1;
277 gl_XML.glParameter.__init__(self, context, name, attrs);
278
279
Ian Romanick1d270842004-12-21 21:26:36 +0000280class glXParameterIterator:
281 """Class to iterate over a list of glXParameters.
282
283 Objects of this class are returned by the parameterIterator method of
284 the glXFunction class. They are used to iterate over the list of
285 parameters to the function."""
286
287 def __init__(self, data, skip_output, max_order):
288 self.data = data
289 self.index = 0
290 self.order = 0
291 self.skip_output = skip_output
292 self.max_order = max_order
293
294 def __iter__(self):
295 return self
296
297 def next(self):
298 if len( self.data ) == 0:
299 raise StopIteration
300
301 while 1:
302 if self.index == len( self.data ):
303 if self.order == self.max_order:
304 raise StopIteration
305 else:
306 self.order += 1
307 self.index = 0
308
309 i = self.index
310 self.index += 1
311
312 if self.data[i].order == self.order and not (self.data[i].is_output and self.skip_output):
313 return self.data[i]
314
315
Ian Romanick74764062004-12-03 20:31:59 +0000316class glXFunction(gl_XML.glFunction):
317 glx_rop = 0
318 glx_sop = 0
319 glx_vendorpriv = 0
320
321 # If this is set to true, it means that GLdouble parameters should be
322 # written to the GLX protocol packet in the order they appear in the
323 # prototype. This is different from the "classic" ordering. In the
324 # classic ordering GLdoubles are written to the protocol packet first,
325 # followed by non-doubles. NV_vertex_program was the first extension
326 # to break with this tradition.
327
328 glx_doubles_in_order = 0
329
330 vectorequiv = None
Ian Romanick74764062004-12-03 20:31:59 +0000331 can_be_large = 0
332
333 def __init__(self, context, name, attrs):
334 self.vectorequiv = attrs.get('vectorequiv', None)
335 self.count_parameters = None
336 self.counter = None
337 self.output = None
338 self.can_be_large = 0
339 self.reply_always_array = 0
340
Ian Romanickfdb05272005-01-28 17:30:25 +0000341 self.server_handcode = 0
342 self.client_handcode = 0
343 self.ignore = 0
344
Ian Romanick74764062004-12-03 20:31:59 +0000345 gl_XML.glFunction.__init__(self, context, name, attrs)
346 return
347
Ian Romanick1d270842004-12-21 21:26:36 +0000348
349 def parameterIterator(self, skip_output, max_order):
350 return glXParameterIterator(self.fn_parameters, skip_output, max_order)
351
352
Ian Romanick74764062004-12-03 20:31:59 +0000353 def startElement(self, name, attrs):
354 """Process elements within a function that are specific to GLX."""
355
356 if name == "glx":
357 self.glx_rop = int(attrs.get('rop', "0"))
358 self.glx_sop = int(attrs.get('sop', "0"))
359 self.glx_vendorpriv = int(attrs.get('vendorpriv', "0"))
360
Ian Romanickfdb05272005-01-28 17:30:25 +0000361 # The 'handcode' attribute can be one of 'true',
362 # 'false', 'client', or 'server'.
363
364 handcode = attrs.get('handcode', "false")
365 if handcode == "false":
366 self.server_handcode = 0
367 self.client_handcode = 0
368 elif handcode == "true":
369 self.server_handcode = 1
370 self.client_handcode = 1
371 elif handcode == "client":
372 self.server_handcode = 0
373 self.client_handcode = 1
374 elif handcode == "server":
375 self.server_handcode = 1
376 self.client_handcode = 0
Ian Romanick74764062004-12-03 20:31:59 +0000377 else:
Ian Romanickfdb05272005-01-28 17:30:25 +0000378 raise RuntimeError('Invalid handcode mode "%s" in function "%s".' % (handcode, self.name))
379
Ian Romanick74764062004-12-03 20:31:59 +0000380
381 if attrs.get('ignore', "false") == "true":
382 self.ignore = 1
383 else:
384 self.ignore = 0
385
386 if attrs.get('large', "false") == "true":
387 self.can_be_large = 1
388 else:
389 self.can_be_large = 0
390
391 if attrs.get('doubles_in_order', "false") == "true":
392 self.glx_doubles_in_order = 1
393 else:
394 self.glx_doubles_in_order = 0
395
396 if attrs.get('always_array', "false") == "true":
397 self.reply_always_array = 1
398 else:
399 self.reply_always_array = 0
400
401 else:
402 gl_XML.glFunction.startElement(self, name, attrs)
403
404
Ian Romanick7f958e92005-01-24 20:08:28 +0000405 def endElement(self, name):
406 if name == "function":
407 # Mark any function that does not have GLX protocol
408 # defined as "ignore". This prevents bad things from
409 # happening when people add new functions to the GL
410 # API XML without adding any GLX section.
411 #
412 # This will also mark functions that don't have a
413 # dispatch offset at ignored.
414
Ian Romanickfdb05272005-01-28 17:30:25 +0000415 if (self.fn_offset == -1 and not self.fn_alias) or not (self.client_handcode or self.server_handcode or self.glx_rop or self.glx_sop or self.glx_vendorpriv or self.vectorequiv or self.fn_alias):
Ian Romanick7f958e92005-01-24 20:08:28 +0000416 #if not self.ignore:
417 # if self.fn_offset == -1:
418 # print '/* %s ignored becuase no offset assigned. */' % (self.name)
419 # else:
420 # print '/* %s ignored becuase no GLX opcode assigned. */' % (self.name)
421
422 self.ignore = 1
423
424 return gl_XML.glFunction.endElement(self, name)
425
426
Ian Romanick74764062004-12-03 20:31:59 +0000427 def append(self, tag_name, p):
428 gl_XML.glFunction.append(self, tag_name, p)
429
430 if p.is_variable_length_array():
431 p.order = 2;
432 elif not self.glx_doubles_in_order and p.p_type.size == 8:
433 p.order = 0;
434
435 if p.p_count_parameters != None:
436 self.count_parameters = p.p_count_parameters
437
438 if p.is_counter:
439 self.counter = p.name
440
441 if p.is_output:
442 self.output = p
443
444 return
445
Ian Romanick0246b2a2005-01-24 20:59:32 +0000446
Ian Romanick74764062004-12-03 20:31:59 +0000447 def variable_length_parameter(self):
448 for param in self.fn_parameters:
449 if param.is_variable_length_array():
450 return param
451
452 return None
453
454
Ian Romanick0246b2a2005-01-24 20:59:32 +0000455 def offset_of_first_parameter(self):
456 """Get the offset of the first parameter in the command.
457
458 Gets the offset of the first function parameter in the GLX
459 command packet. This byte offset is measured from the end
460 of the Render / RenderLarge header. The offset for all non-
461 pixel commends is zero. The offset for pixel commands depends
462 on the number of dimensions of the pixel data."""
Ian Romanick5f1f2292005-01-07 02:39:09 +0000463
464 if self.image:
465 [dim, junk, junk, junk, junk] = self.dimensions()
Ian Romanick0246b2a2005-01-24 20:59:32 +0000466
Ian Romanick5f1f2292005-01-07 02:39:09 +0000467 # The base size is the size of the pixel pack info
468 # header used by images with the specified number
469 # of dimensions.
470
471 if dim <= 2:
Ian Romanick0246b2a2005-01-24 20:59:32 +0000472 return 20
Ian Romanick5f1f2292005-01-07 02:39:09 +0000473 elif dim <= 4:
Ian Romanick0246b2a2005-01-24 20:59:32 +0000474 return 36
Ian Romanick5f1f2292005-01-07 02:39:09 +0000475 else:
476 raise RuntimeError('Invalid number of dimensions %u for parameter "%s" in function "%s".' % (dim, self.image.name, self.name))
Ian Romanick0246b2a2005-01-24 20:59:32 +0000477 else:
478 return 0
Ian Romanick5f1f2292005-01-07 02:39:09 +0000479
Ian Romanick5f1f2292005-01-07 02:39:09 +0000480
Ian Romanick0246b2a2005-01-24 20:59:32 +0000481 def command_fixed_length(self):
482 """Return the length, in bytes as an integer, of the
483 fixed-size portion of the command."""
Ian Romanick5f1f2292005-01-07 02:39:09 +0000484
Ian Romanick0246b2a2005-01-24 20:59:32 +0000485 size = self.offset_of_first_parameter()
Ian Romanick5f1f2292005-01-07 02:39:09 +0000486
Ian Romanick0246b2a2005-01-24 20:59:32 +0000487 for p in gl_XML.glFunction.parameterIterator(self):
488 if not p.is_output:
489 size += p.size()
490 if self.pad_after(p):
491 size += 4
492
493 if self.image and self.image.img_null_flag:
494 size += 4
495
496 return size
497
498
499 def command_variable_length(self):
500 """Return the length, as a string, of the variable-sized
501 portion of the command."""
502
Ian Romanick74764062004-12-03 20:31:59 +0000503 size_string = ""
Ian Romanick1d270842004-12-21 21:26:36 +0000504 for p in gl_XML.glFunction.parameterIterator(self):
Ian Romanick0246b2a2005-01-24 20:59:32 +0000505 if (not p.is_output) and (p.size() == 0):
506 size_string = size_string + " + __GLX_PAD(%s)" % (p.size_string())
Ian Romanick74764062004-12-03 20:31:59 +0000507
Ian Romanick0246b2a2005-01-24 20:59:32 +0000508 return size_string
509
Ian Romanick74764062004-12-03 20:31:59 +0000510
511 def command_length(self):
Ian Romanick0246b2a2005-01-24 20:59:32 +0000512 size = self.command_fixed_length()
Ian Romanick74764062004-12-03 20:31:59 +0000513
514 if self.glx_rop != 0:
515 size += 4
516
517 size = ((size + 3) & ~3)
Ian Romanick0246b2a2005-01-24 20:59:32 +0000518 return "%u%s" % (size, self.command_variable_length())
Ian Romanick74764062004-12-03 20:31:59 +0000519
520
521 def opcode_real_value(self):
Ian Romanick1d270842004-12-21 21:26:36 +0000522 """Get the true numeric value of the GLX opcode
523
524 Behaves similarly to opcode_value, except for
525 X_GLXVendorPrivate and X_GLXVendorPrivateWithReply commands.
526 In these cases the value for the GLX opcode field (i.e.,
527 16 for X_GLXVendorPrivate or 17 for
528 X_GLXVendorPrivateWithReply) is returned. For other 'single'
529 commands, the opcode for the command (e.g., 101 for
530 X_GLsop_NewList) is returned."""
531
Ian Romanick74764062004-12-03 20:31:59 +0000532 if self.glx_vendorpriv != 0:
533 if self.needs_reply():
534 return 17
535 else:
536 return 16
537 else:
538 return self.opcode_value()
539
540 def opcode_value(self):
Ian Romanick1d270842004-12-21 21:26:36 +0000541 """Get the unique protocol opcode for the glXFunction"""
542
Ian Romanick74764062004-12-03 20:31:59 +0000543 if self.glx_rop != 0:
544 return self.glx_rop
545 elif self.glx_sop != 0:
546 return self.glx_sop
547 elif self.glx_vendorpriv != 0:
548 return self.glx_vendorpriv
549 else:
550 return -1
551
552 def opcode_rop_basename(self):
Ian Romanick1d270842004-12-21 21:26:36 +0000553 """Return either the name to be used for GLX protocol enum.
554
555 Returns either the name of the function or the name of the
556 name of the equivalent vector (e.g., glVertex3fv for
557 glVertex3f) function."""
558
Ian Romanick74764062004-12-03 20:31:59 +0000559 if self.vectorequiv == None:
560 return self.name
561 else:
562 return self.vectorequiv
563
564 def opcode_name(self):
Ian Romanick1d270842004-12-21 21:26:36 +0000565 """Get the unique protocol enum name for the glXFunction"""
566
Ian Romanick74764062004-12-03 20:31:59 +0000567 if self.glx_rop != 0:
568 return "X_GLrop_%s" % (self.opcode_rop_basename())
569 elif self.glx_sop != 0:
570 return "X_GLsop_%s" % (self.name)
571 elif self.glx_vendorpriv != 0:
572 return "X_GLvop_%s" % (self.name)
573 else:
574 return "ERROR"
575
576 def opcode_real_name(self):
Ian Romanick1d270842004-12-21 21:26:36 +0000577 """Get the true protocol enum name for the GLX opcode
578
579 Behaves similarly to opcode_name, except for
580 X_GLXVendorPrivate and X_GLXVendorPrivateWithReply commands.
581 In these cases the string 'X_GLXVendorPrivate' or
582 'X_GLXVendorPrivateWithReply' is returned. For other
583 single or render commands 'X_GLsop' or 'X_GLrop' plus the
584 name of the function returned."""
585
Ian Romanick74764062004-12-03 20:31:59 +0000586 if self.glx_vendorpriv != 0:
587 if self.needs_reply():
588 return "X_GLXVendorPrivateWithReply"
589 else:
590 return "X_GLXVendorPrivate"
591 else:
592 return self.opcode_name()
593
594
595 def return_string(self):
596 if self.fn_return_type != 'void':
597 return "return retval;"
598 else:
599 return "return;"
600
601
602 def needs_reply(self):
603 return self.fn_return_type != 'void' or self.output != None
604
605
Ian Romanick5f1f2292005-01-07 02:39:09 +0000606 def dimensions(self):
607 """Determine the dimensions of an image.
608
609 Returns a tuple representing the number of dimensions and the
610 string name of each of the dimensions of an image, If the
611 function is not a pixel function, the number of dimensions
612 will be zero."""
613
614 if not self.image:
615 return [0, "0", "0", "0", "0"]
616 else:
617 dim = 1
618 w = self.image.width
619
620 if self.image.height:
621 dim = 2
622 h = self.image.height
623 else:
624 h = "1"
625
626 if self.image.depth:
627 dim = 3
628 d = self.image.depth
629 else:
630 d = "1"
631
632 if self.image.extent:
633 dim = 4
634 e = self.image.extent
635 else:
636 e = "1"
637
638 return [dim, w, h, d, e]
639
640
641 def pad_after(self, p):
642 """Returns the name of the field inserted after the
643 specified field to pad out the command header."""
644
645 if self.image and self.image.img_pad_dimensions:
646 if not self.image.height:
647 if p.name == self.image.width:
648 return "height"
649 elif p.name == self.image.img_xoff:
650 return "yoffset"
651 elif not self.image.extent:
652 if p.name == self.image.depth:
653 # Should this be "size4d"?
654 return "extent"
655 elif p.name == self.image.img_zoff:
656 return "woffset"
657 return None
658
659
Ian Romanick74764062004-12-03 20:31:59 +0000660class GlxProto(gl_XML.FilterGLAPISpecBase):
661 name = "glX_proto_send.py (from Mesa)"
662
663 def __init__(self):
664 gl_XML.FilterGLAPISpecBase.__init__(self)
665 self.factory = glXItemFactory()
666 self.glx_enum_functions = {}
667
668
669 def endElement(self, name):
670 if name == 'OpenGLAPI':
671 # Once all the parsing is done, we have to go back and
672 # fix-up some cross references between different
673 # functions.
674
675 for k in self.functions:
676 f = self.functions[k]
677 if f.vectorequiv != None:
678 equiv = self.find_function(f.vectorequiv)
679 if equiv != None:
680 f.glx_doubles_in_order = equiv.glx_doubles_in_order
681 f.glx_rop = equiv.glx_rop
682 else:
683 raise RuntimeError("Could not find the vector equiv. function %s for %s!" % (f.name, f.vectorequiv))
684 else:
685 gl_XML.FilterGLAPISpecBase.endElement(self, name)
686 return