~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/mesa/glapi/gen/gl_XML.py

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env python
2
 
 
3
 
# (C) Copyright IBM Corporation 2004, 2005
4
 
# 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
 
 
28
 
import libxml2
29
 
import re, sys, string
30
 
import typeexpr
31
 
 
32
 
 
33
 
def parse_GL_API( file_name, factory = None ):
34
 
        doc = libxml2.readFile( file_name, None, libxml2.XML_PARSE_XINCLUDE + libxml2.XML_PARSE_NOBLANKS + libxml2.XML_PARSE_DTDVALID + libxml2.XML_PARSE_DTDATTR + libxml2.XML_PARSE_DTDLOAD + libxml2.XML_PARSE_NOENT )
35
 
        ret = doc.xincludeProcess()
36
 
 
37
 
        if not factory:
38
 
                factory = gl_item_factory()
39
 
 
40
 
        api = factory.create_item( "api", None, None )
41
 
        api.process_element( doc )
42
 
 
43
 
        # After the XML has been processed, we need to go back and assign
44
 
        # dispatch offsets to the functions that request that their offsets
45
 
        # be assigned by the scripts.  Typically this means all functions
46
 
        # that are not part of the ABI.
47
 
 
48
 
        for func in api.functionIterateByCategory():
49
 
                if func.assign_offset:
50
 
                        func.offset = api.next_offset;
51
 
                        api.next_offset += 1
52
 
 
53
 
        doc.freeDoc()
54
 
 
55
 
        return api
56
 
 
57
 
 
58
 
def is_attr_true( element, name ):
59
 
        """Read a name value from an element's attributes.
60
 
        
61
 
        The value read from the attribute list must be either 'true' or
62
 
        'false'.  If the value is 'false', zero will be returned.  If the
63
 
        value is 'true', non-zero will be returned.  An exception will be
64
 
        raised for any other value."""
65
 
 
66
 
        value = element.nsProp( name, None )
67
 
        if value == "true":
68
 
                return 1
69
 
        elif value == "false":
70
 
                return 0
71
 
        else:
72
 
                raise RuntimeError('Invalid value "%s" for boolean "%s".' % (value, name))
73
 
 
74
 
 
75
 
class gl_print_base:
76
 
        """Base class of all API pretty-printers.
77
 
 
78
 
        In the model-view-controller pattern, this is the view.  Any derived
79
 
        class will want to over-ride the printBody, printRealHader, and
80
 
        printRealFooter methods.  Some derived classes may want to over-ride
81
 
        printHeader and printFooter, or even Print (though this is unlikely).
82
 
        """
83
 
 
84
 
        def __init__(self):
85
 
                # Name of the script that is generating the output file.
86
 
                # Every derived class should set this to the name of its
87
 
                # source file.
88
 
 
89
 
                self.name = "a"
90
 
 
91
 
 
92
 
                # License on the *generated* source file.  This may differ
93
 
                # from the license on the script that is generating the file.
94
 
                # Every derived class should set this to some reasonable
95
 
                # value.
96
 
                #
97
 
                # See license.py for an example of a reasonable value.
98
 
 
99
 
                self.license = "The license for this file is unspecified."
100
 
 
101
 
                
102
 
                # The header_tag is the name of the C preprocessor define
103
 
                # used to prevent multiple inclusion.  Typically only
104
 
                # generated C header files need this to be set.  Setting it
105
 
                # causes code to be generated automatically in printHeader
106
 
                # and printFooter.
107
 
 
108
 
                self.header_tag = None
109
 
 
110
 
                
111
 
                # List of file-private defines that must be undefined at the
112
 
                # end of the file.  This can be used in header files to define
113
 
                # names for use in the file, then undefine them at the end of
114
 
                # the header file.
115
 
 
116
 
                self.undef_list = []
117
 
                return
118
 
 
119
 
 
120
 
        def Print(self, api):
121
 
                self.printHeader()
122
 
                self.printBody(api)
123
 
                self.printFooter()
124
 
                return
125
 
 
126
 
 
127
 
        def printHeader(self):
128
 
                """Print the header associated with all files and call the printRealHeader method."""
129
 
 
130
 
                print '/* DO NOT EDIT - This file generated automatically by %s script */' \
131
 
                        % (self.name)
132
 
                print ''
133
 
                print '/*'
134
 
                print ' * ' + self.license.replace('\n', '\n * ')
135
 
                print ' */'
136
 
                print ''
137
 
                if self.header_tag:
138
 
                    print '#if !defined( %s )' % (self.header_tag)
139
 
                    print '#  define %s' % (self.header_tag)
140
 
                    print ''
141
 
                self.printRealHeader();
142
 
                return
143
 
 
144
 
 
145
 
        def printFooter(self):
146
 
                """Print the header associated with all files and call the printRealFooter method."""
147
 
 
148
 
                self.printRealFooter()
149
 
 
150
 
                if self.undef_list:
151
 
                        print ''
152
 
                        for u in self.undef_list:
153
 
                                print "#  undef %s" % (u)
154
 
 
155
 
                if self.header_tag:
156
 
                        print ''
157
 
                        print '#endif /* !defined( %s ) */' % (self.header_tag)
158
 
 
159
 
 
160
 
        def printRealHeader(self):
161
 
                """Print the "real" header for the created file.
162
 
 
163
 
                In the base class, this function is empty.  All derived
164
 
                classes should over-ride this function."""
165
 
                return
166
 
 
167
 
 
168
 
        def printRealFooter(self):
169
 
                """Print the "real" footer for the created file.
170
 
 
171
 
                In the base class, this function is empty.  All derived
172
 
                classes should over-ride this function."""
173
 
                return
174
 
 
175
 
 
176
 
        def printPure(self):
177
 
                """Conditionally define `PURE' function attribute.
178
 
 
179
 
                Conditionally defines a preprocessor macro `PURE' that wraps
180
 
                GCC's `pure' function attribute.  The conditional code can be
181
 
                easilly adapted to other compilers that support a similar
182
 
                feature.
183
 
 
184
 
                The name is also added to the file's undef_list.
185
 
                """
186
 
                self.undef_list.append("PURE")
187
 
                print """#  if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
188
 
#    define PURE __attribute__((pure))
189
 
#  else
190
 
#    define PURE
191
 
#  endif"""
192
 
                return
193
 
 
194
 
 
195
 
        def printFastcall(self):
196
 
                """Conditionally define `FASTCALL' function attribute.
197
 
 
198
 
                Conditionally defines a preprocessor macro `FASTCALL' that
199
 
                wraps GCC's `fastcall' function attribute.  The conditional
200
 
                code can be easilly adapted to other compilers that support a
201
 
                similar feature.
202
 
 
203
 
                The name is also added to the file's undef_list.
204
 
                """
205
 
 
206
 
                self.undef_list.append("FASTCALL")
207
 
                print """#  if defined(__i386__) && defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__)
208
 
#    define FASTCALL __attribute__((fastcall))
209
 
#  else
210
 
#    define FASTCALL
211
 
#  endif"""
212
 
                return
213
 
 
214
 
 
215
 
        def printVisibility(self, S, s):
216
 
                """Conditionally define visibility function attribute.
217
 
 
218
 
                Conditionally defines a preprocessor macro name S that wraps
219
 
                GCC's visibility function attribute.  The visibility used is
220
 
                the parameter s.  The conditional code can be easilly adapted
221
 
                to other compilers that support a similar feature.
222
 
 
223
 
                The name is also added to the file's undef_list.
224
 
                """
225
 
 
226
 
                self.undef_list.append(S)
227
 
                print """#  if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) && defined(__ELF__)
228
 
#    define %s  __attribute__((visibility("%s")))
229
 
#  else
230
 
#    define %s
231
 
#  endif""" % (S, s, S)
232
 
                return
233
 
 
234
 
 
235
 
        def printNoinline(self):
236
 
                """Conditionally define `NOINLINE' function attribute.
237
 
 
238
 
                Conditionally defines a preprocessor macro `NOINLINE' that
239
 
                wraps GCC's `noinline' function attribute.  The conditional
240
 
                code can be easilly adapted to other compilers that support a
241
 
                similar feature.
242
 
 
243
 
                The name is also added to the file's undef_list.
244
 
                """
245
 
 
246
 
                self.undef_list.append("NOINLINE")
247
 
                print """#  if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
248
 
#    define NOINLINE __attribute__((noinline))
249
 
#  else
250
 
#    define NOINLINE
251
 
#  endif"""
252
 
                return
253
 
 
254
 
 
255
 
def real_function_name(element):
256
 
        name = element.nsProp( "name", None )
257
 
        alias = element.nsProp( "alias", None )
258
 
        
259
 
        if alias:
260
 
                return alias
261
 
        else:
262
 
                return name
263
 
 
264
 
 
265
 
def real_category_name(c):
266
 
        if re.compile("[1-9][0-9]*[.][0-9]+").match(c):
267
 
                return "GL_VERSION_" + c.replace(".", "_")
268
 
        else:
269
 
                return c
270
 
 
271
 
 
272
 
def classify_category(name, number):
273
 
        """Based on the category name and number, select a numerical class for it.
274
 
        
275
 
        Categories are divided into four classes numbered 0 through 3.  The
276
 
        classes are:
277
 
 
278
 
                0. Core GL versions, sorted by version number.
279
 
                1. ARB extensions, sorted by extension number.
280
 
                2. Non-ARB extensions, sorted by extension number.
281
 
                3. Un-numbered extensions, sorted by extension name.
282
 
        """
283
 
 
284
 
        try:
285
 
                core_version = float(name)
286
 
        except Exception,e:
287
 
                core_version = 0.0
288
 
 
289
 
        if core_version > 0.0:
290
 
                cat_type = 0
291
 
                key = name
292
 
        elif name.startswith("GL_ARB_") or name.startswith("GLX_ARB_") or name.startswith("WGL_ARB_"):
293
 
                cat_type = 1
294
 
                key = int(number)
295
 
        else:
296
 
                if number != None:
297
 
                        cat_type = 2
298
 
                        key = int(number)
299
 
                else:
300
 
                        cat_type = 3
301
 
                        key = name
302
 
 
303
 
 
304
 
        return [cat_type, key]
305
 
 
306
 
 
307
 
def create_parameter_string(parameters, include_names):
308
 
        """Create a parameter string from a list of gl_parameters."""
309
 
 
310
 
        list = []
311
 
        for p in parameters:
312
 
                if p.is_padding:
313
 
                        continue
314
 
 
315
 
                if include_names:
316
 
                        list.append( p.string() )
317
 
                else:
318
 
                        list.append( p.type_string() )
319
 
 
320
 
        if len(list) == 0: list = ["void"]
321
 
 
322
 
        return string.join(list, ", ")
323
 
 
324
 
 
325
 
class gl_item:
326
 
        def __init__(self, element, context):
327
 
                self.context = context
328
 
                self.name = element.nsProp( "name", None )
329
 
                self.category = real_category_name( element.parent.nsProp( "name", None ) )
330
 
                return
331
 
 
332
 
 
333
 
class gl_type( gl_item ):
334
 
        def __init__(self, element, context):
335
 
                gl_item.__init__(self, element, context)
336
 
                self.size = int( element.nsProp( "size", None ), 0 )
337
 
 
338
 
                te = typeexpr.type_expression( None )
339
 
                tn = typeexpr.type_node()
340
 
                tn.size = int( element.nsProp( "size", None ), 0 )
341
 
                tn.integer = not is_attr_true( element, "float" )
342
 
                tn.unsigned = is_attr_true( element, "unsigned" )
343
 
                tn.name = "GL" + self.name
344
 
                te.set_base_type_node( tn )
345
 
 
346
 
                self.type_expr = te
347
 
                return
348
 
        
349
 
 
350
 
        def get_type_expression(self):
351
 
                return self.type_expr
352
 
 
353
 
 
354
 
class gl_enum( gl_item ):
355
 
        def __init__(self, element, context):
356
 
                gl_item.__init__(self, element, context)
357
 
                self.value = int( element.nsProp( "value", None ), 0 )
358
 
 
359
 
                temp = element.nsProp( "count", None )
360
 
                if not temp or temp == "?":
361
 
                        self.default_count = -1
362
 
                else:
363
 
                        try:
364
 
                                c = int(temp)
365
 
                        except Exception,e:
366
 
                                raise RuntimeError('Invalid count value "%s" for enum "%s" in function "%s" when an integer was expected.' % (temp, self.name, n))
367
 
 
368
 
                        self.default_count = c
369
 
 
370
 
                return
371
 
 
372
 
 
373
 
        def priority(self):
374
 
                """Calculate a 'priority' for this enum name.
375
 
                
376
 
                When an enum is looked up by number, there may be many
377
 
                possible names, but only one is the 'prefered' name.  The
378
 
                priority is used to select which name is the 'best'.
379
 
 
380
 
                Highest precedence is given to core GL name.  ARB extension
381
 
                names have the next highest, followed by EXT extension names.
382
 
                Vendor extension names are the lowest.
383
 
                """
384
 
 
385
 
                if self.name.endswith( "_BIT" ):
386
 
                        bias = 1
387
 
                else:
388
 
                        bias = 0
389
 
 
390
 
                if self.category.startswith( "GL_VERSION_" ):
391
 
                        priority = 0
392
 
                elif self.category.startswith( "GL_ARB_" ):
393
 
                        priority = 2
394
 
                elif self.category.startswith( "GL_EXT_" ):
395
 
                        priority = 4
396
 
                else:
397
 
                        priority = 6
398
 
 
399
 
                return priority + bias
400
 
 
401
 
 
402
 
 
403
 
class gl_parameter:
404
 
        def __init__(self, element, context):
405
 
                self.name = element.nsProp( "name", None )
406
 
 
407
 
                ts = element.nsProp( "type", None )
408
 
                self.type_expr = typeexpr.type_expression( ts, context )
409
 
 
410
 
                temp = element.nsProp( "variable_param", None )
411
 
                if temp:
412
 
                        self.count_parameter_list = temp.split( ' ' )
413
 
                else:
414
 
                        self.count_parameter_list = []
415
 
 
416
 
                # The count tag can be either a numeric string or the name of
417
 
                # a variable.  If it is the name of a variable, the int(c)
418
 
                # statement will throw an exception, and the except block will
419
 
                # take over.
420
 
 
421
 
                c = element.nsProp( "count", None )
422
 
                try: 
423
 
                        count = int(c)
424
 
                        self.count = count
425
 
                        self.counter = None
426
 
                except Exception,e:
427
 
                        count = 1
428
 
                        self.count = 0
429
 
                        self.counter = c
430
 
                
431
 
                self.count_scale = int(element.nsProp( "count_scale", None ))
432
 
 
433
 
                elements = (count * self.count_scale)
434
 
                if elements == 1:
435
 
                        elements = 0
436
 
 
437
 
                #if ts == "GLdouble":
438
 
                #       print '/* stack size -> %s = %u (before)*/' % (self.name, self.type_expr.get_stack_size())
439
 
                #       print '/* # elements = %u */' % (elements)
440
 
                self.type_expr.set_elements( elements )
441
 
                #if ts == "GLdouble":
442
 
                #       print '/* stack size -> %s = %u (after) */' % (self.name, self.type_expr.get_stack_size())
443
 
 
444
 
                self.is_client_only = is_attr_true( element, 'client_only' )
445
 
                self.is_counter     = is_attr_true( element, 'counter' )
446
 
                self.is_output      = is_attr_true( element, 'output' )
447
 
 
448
 
 
449
 
                # Pixel data has special parameters.
450
 
 
451
 
                self.width      = element.nsProp('img_width',  None)
452
 
                self.height     = element.nsProp('img_height', None)
453
 
                self.depth      = element.nsProp('img_depth',  None)
454
 
                self.extent     = element.nsProp('img_extent', None)
455
 
 
456
 
                self.img_xoff   = element.nsProp('img_xoff',   None)
457
 
                self.img_yoff   = element.nsProp('img_yoff',   None)
458
 
                self.img_zoff   = element.nsProp('img_zoff',   None)
459
 
                self.img_woff   = element.nsProp('img_woff',   None)
460
 
 
461
 
                self.img_format = element.nsProp('img_format', None)
462
 
                self.img_type   = element.nsProp('img_type',   None)
463
 
                self.img_target = element.nsProp('img_target', None)
464
 
 
465
 
                self.img_pad_dimensions = is_attr_true( element, 'img_pad_dimensions' )
466
 
                self.img_null_flag      = is_attr_true( element, 'img_null_flag' )
467
 
                self.img_send_null      = is_attr_true( element, 'img_send_null' )
468
 
 
469
 
                self.is_padding = is_attr_true( element, 'padding' )
470
 
                return
471
 
 
472
 
 
473
 
        def compatible(self, other):
474
 
                return 1
475
 
 
476
 
 
477
 
        def is_array(self):
478
 
                return self.is_pointer()
479
 
 
480
 
 
481
 
        def is_pointer(self):
482
 
                return self.type_expr.is_pointer()
483
 
 
484
 
 
485
 
        def is_image(self):
486
 
                if self.width:
487
 
                        return 1
488
 
                else:
489
 
                        return 0
490
 
 
491
 
 
492
 
        def is_variable_length(self):
493
 
                return len(self.count_parameter_list) or self.counter
494
 
 
495
 
 
496
 
        def is_64_bit(self):
497
 
                count = self.type_expr.get_element_count()
498
 
                if count:
499
 
                        if (self.size() / count) == 8:
500
 
                                return 1
501
 
                else:
502
 
                        if self.size() == 8:
503
 
                                return 1
504
 
 
505
 
                return 0
506
 
 
507
 
 
508
 
        def string(self):
509
 
                return self.type_expr.original_string + " " + self.name
510
 
 
511
 
 
512
 
        def type_string(self):
513
 
                return self.type_expr.original_string
514
 
 
515
 
 
516
 
        def get_base_type_string(self):
517
 
                return self.type_expr.get_base_name()
518
 
 
519
 
 
520
 
        def get_dimensions(self):
521
 
                if not self.width:
522
 
                        return [ 0, "0", "0", "0", "0" ]
523
 
 
524
 
                dim = 1
525
 
                w = self.width
526
 
                h = "1"
527
 
                d = "1"
528
 
                e = "1"
529
 
 
530
 
                if self.height:
531
 
                        dim = 2
532
 
                        h = self.height
533
 
 
534
 
                if self.depth:
535
 
                        dim = 3
536
 
                        d = self.depth
537
 
 
538
 
                if self.extent:
539
 
                        dim = 4
540
 
                        e = self.extent
541
 
 
542
 
                return [ dim, w, h, d, e ]
543
 
 
544
 
 
545
 
        def get_stack_size(self):
546
 
                return self.type_expr.get_stack_size()
547
 
 
548
 
 
549
 
        def size(self):
550
 
                if self.is_image():
551
 
                        return 0
552
 
                else:
553
 
                        return self.type_expr.get_element_size()
554
 
 
555
 
 
556
 
        def get_element_count(self):
557
 
                c = self.type_expr.get_element_count()
558
 
                if c == 0:
559
 
                        return 1
560
 
 
561
 
                return c
562
 
 
563
 
 
564
 
        def size_string(self, use_parens = 1):
565
 
                s = self.size()
566
 
                if self.counter or self.count_parameter_list:
567
 
                        list = [ "compsize" ]
568
 
 
569
 
                        if self.counter and self.count_parameter_list:
570
 
                                list.append( self.counter )
571
 
                        elif self.counter:
572
 
                                list = [ self.counter ]
573
 
 
574
 
                        if s > 1:
575
 
                                list.append( str(s) )
576
 
 
577
 
                        if len(list) > 1 and use_parens :
578
 
                                return "(%s)" % (string.join(list, " * "))
579
 
                        else:
580
 
                                return string.join(list, " * ")
581
 
 
582
 
                elif self.is_image():
583
 
                        return "compsize"
584
 
                else:
585
 
                        return str(s)
586
 
 
587
 
 
588
 
        def format_string(self):
589
 
                if self.type_expr.original_string == "GLenum":
590
 
                        return "0x%x"
591
 
                else:
592
 
                        return self.type_expr.format_string()
593
 
 
594
 
 
595
 
 
596
 
class gl_function( gl_item ):
597
 
        def __init__(self, element, context):
598
 
                self.context = context
599
 
                self.name = None
600
 
 
601
 
                self.entry_points = []
602
 
                self.return_type = "void"
603
 
                self.parameters = []
604
 
                self.offset = -1
605
 
                self.initialized = 0
606
 
                self.images = []
607
 
 
608
 
                self.assign_offset = 0
609
 
 
610
 
                self.static_entry_points = []
611
 
 
612
 
                # Track the parameter string (for the function prototype)
613
 
                # for each entry-point.  This is done because some functions
614
 
                # change their prototype slightly when promoted from extension
615
 
                # to ARB extension to core.  glTexImage3DEXT and glTexImage3D
616
 
                # are good examples of this.  Scripts that need to generate
617
 
                # code for these differing aliases need to real prototype
618
 
                # for each entry-point.  Otherwise, they may generate code
619
 
                # that won't compile.
620
 
 
621
 
                self.parameter_strings = {}
622
 
 
623
 
                self.process_element( element )
624
 
 
625
 
                return
626
 
 
627
 
        
628
 
        def process_element(self, element):
629
 
                name = element.nsProp( "name", None )
630
 
                alias = element.nsProp( "alias", None )
631
 
 
632
 
                if is_attr_true(element, "static_dispatch"):
633
 
                        self.static_entry_points.append(name)
634
 
 
635
 
                self.entry_points.append( name )
636
 
                if alias:
637
 
                        true_name = alias
638
 
                else:
639
 
                        true_name = name
640
 
 
641
 
                        # Only try to set the offset when a non-alias
642
 
                        # entry-point is being processes.
643
 
 
644
 
                        offset = element.nsProp( "offset", None )
645
 
                        if offset:
646
 
                                try:
647
 
                                        o = int( offset )
648
 
                                        self.offset = o
649
 
                                except Exception, e:
650
 
                                        self.offset = -1
651
 
                                        if offset == "assign":
652
 
                                                self.assign_offset = 1
653
 
 
654
 
 
655
 
                if not self.name:
656
 
                        self.name = true_name
657
 
                elif self.name != true_name:
658
 
                        raise RuntimeError("Function true name redefined.  Was %s, now %s." % (self.name, true_name))
659
 
 
660
 
 
661
 
                # There are two possible cases.  The first time an entry-point
662
 
                # with data is seen, self.initialized will be 0.  On that
663
 
                # pass, we just fill in the data.  The next time an
664
 
                # entry-point with data is seen, self.initialized will be 1.
665
 
                # On that pass we have to make that the new values match the
666
 
                # valuse from the previous entry-point.
667
 
 
668
 
                parameters = []
669
 
                return_type = "void"
670
 
                child = element.children
671
 
                while child:
672
 
                        if child.type == "element":
673
 
                                if child.name == "return":
674
 
                                        return_type = child.nsProp( "type", None )
675
 
                                elif child.name == "param":
676
 
                                        param = self.context.factory.create_item( "parameter", child, self.context)
677
 
                                        parameters.append( param )
678
 
 
679
 
                        child = child.next
680
 
 
681
 
 
682
 
                if self.initialized:
683
 
                        if self.return_type != return_type:
684
 
                                raise RuntimeError( "Return type changed in %s.  Was %s, now %s." % (name, self.return_type, return_type))
685
 
 
686
 
                        if len(parameters) != len(self.parameters):
687
 
                                raise RuntimeError( "Parameter count mismatch in %s.  Was %d, now %d." % (name, len(self.parameters), len(parameters)))
688
 
 
689
 
                        for j in range(0, len(parameters)):
690
 
                                p1 = parameters[j]
691
 
                                p2 = self.parameters[j]
692
 
                                if not p1.compatible( p2 ):
693
 
                                        raise RuntimeError( 'Parameter type mismatch in %s.  "%s" was "%s", now "%s".' % (name, p2.name, p2.type_expr.original_string, p1.type_expr.original_string))
694
 
 
695
 
 
696
 
                if true_name == name or not self.initialized:
697
 
                        self.return_type = return_type
698
 
                        self.parameters = parameters
699
 
 
700
 
                        for param in self.parameters:
701
 
                                if param.is_image():
702
 
                                        self.images.append( param )
703
 
 
704
 
                if element.children:
705
 
                        self.initialized = 1
706
 
                        self.parameter_strings[name] = create_parameter_string(parameters, 1)
707
 
                else:
708
 
                        self.parameter_strings[name] = None
709
 
 
710
 
                return
711
 
 
712
 
 
713
 
        def get_images(self):
714
 
                """Return potentially empty list of input images."""
715
 
                return self.images
716
 
 
717
 
 
718
 
        def parameterIterator(self):
719
 
                return self.parameters.__iter__();
720
 
 
721
 
 
722
 
        def get_parameter_string(self, entrypoint = None):
723
 
                if entrypoint:
724
 
                        s = self.parameter_strings[ entrypoint ]
725
 
                        if s:
726
 
                                return s
727
 
                
728
 
                return create_parameter_string( self.parameters, 1 )
729
 
 
730
 
        def get_called_parameter_string(self):
731
 
                p_string = ""
732
 
                comma = ""
733
 
 
734
 
                for p in self.parameterIterator():
735
 
                        p_string = p_string + comma + p.name
736
 
                        comma = ", "
737
 
 
738
 
                return p_string
739
 
 
740
 
 
741
 
        def is_abi(self):
742
 
                return (self.offset >= 0 and not self.assign_offset)
743
 
 
744
 
        def is_static_entry_point(self, name):
745
 
                return name in self.static_entry_points
746
 
 
747
 
        def dispatch_name(self):
748
 
                if self.name in self.static_entry_points:
749
 
                        return self.name
750
 
                else:
751
 
                        return "_dispatch_stub_%u" % (self.offset)
752
 
 
753
 
        def static_name(self, name):
754
 
                if name in self.static_entry_points:
755
 
                        return name
756
 
                else:
757
 
                        return "_dispatch_stub_%u" % (self.offset)
758
 
 
759
 
 
760
 
class gl_item_factory:
761
 
        """Factory to create objects derived from gl_item."""
762
 
 
763
 
        def create_item(self, item_name, element, context):
764
 
                if item_name == "function":
765
 
                        return gl_function(element, context)
766
 
                if item_name == "type":
767
 
                        return gl_type(element, context)
768
 
                elif item_name == "enum":
769
 
                        return gl_enum(element, context)
770
 
                elif item_name == "parameter":
771
 
                        return gl_parameter(element, context)
772
 
                elif item_name == "api":
773
 
                        return gl_api(self)
774
 
                else:
775
 
                        return None
776
 
 
777
 
 
778
 
class gl_api:
779
 
        def __init__(self, factory):
780
 
                self.functions_by_name = {}
781
 
                self.enums_by_name = {}
782
 
                self.types_by_name = {}
783
 
 
784
 
                self.category_dict = {}
785
 
                self.categories = [{}, {}, {}, {}]
786
 
 
787
 
                self.factory = factory
788
 
 
789
 
                self.next_offset = 0
790
 
 
791
 
                typeexpr.create_initial_types()
792
 
                return
793
 
 
794
 
 
795
 
        def process_element(self, doc):
796
 
                element = doc.children
797
 
                while element.type != "element" or element.name != "OpenGLAPI":
798
 
                        element = element.next
799
 
 
800
 
                if element:
801
 
                        self.process_OpenGLAPI(element)
802
 
                return
803
 
 
804
 
 
805
 
        def process_OpenGLAPI(self, element):
806
 
                child = element.children
807
 
                while child:
808
 
                        if child.type == "element":
809
 
                                if child.name == "category":
810
 
                                        self.process_category( child )
811
 
                                elif child.name == "OpenGLAPI":
812
 
                                        self.process_OpenGLAPI( child )
813
 
 
814
 
                        child = child.next
815
 
 
816
 
                return
817
 
 
818
 
 
819
 
        def process_category(self, cat):
820
 
                cat_name = cat.nsProp( "name", None )
821
 
                cat_number = cat.nsProp( "number", None )
822
 
 
823
 
                [cat_type, key] = classify_category(cat_name, cat_number)
824
 
                self.categories[cat_type][key] = [cat_name, cat_number]
825
 
 
826
 
                child = cat.children
827
 
                while child:
828
 
                        if child.type == "element":
829
 
                                if child.name == "function":
830
 
                                        func_name = real_function_name( child )
831
 
 
832
 
                                        temp_name = child.nsProp( "name", None )
833
 
                                        self.category_dict[ temp_name ] = [cat_name, cat_number]
834
 
 
835
 
                                        if self.functions_by_name.has_key( func_name ):
836
 
                                                func = self.functions_by_name[ func_name ]
837
 
                                                func.process_element( child )
838
 
                                        else:
839
 
                                                func = self.factory.create_item( "function", child, self )
840
 
                                                self.functions_by_name[ func_name ] = func
841
 
 
842
 
                                        if func.offset >= self.next_offset:
843
 
                                                self.next_offset = func.offset + 1
844
 
 
845
 
 
846
 
                                elif child.name == "enum":
847
 
                                        enum = self.factory.create_item( "enum", child, self )
848
 
                                        self.enums_by_name[ enum.name ] = enum
849
 
                                elif child.name == "type":
850
 
                                        t = self.factory.create_item( "type", child, self )
851
 
                                        self.types_by_name[ "GL" + t.name ] = t
852
 
 
853
 
 
854
 
                        child = child.next
855
 
 
856
 
                return
857
 
 
858
 
 
859
 
        def functionIterateByCategory(self, cat = None):
860
 
                """Iterate over functions by category.
861
 
                
862
 
                If cat is None, all known functions are iterated in category
863
 
                order.  See classify_category for details of the ordering.
864
 
                Within a category, functions are sorted by name.  If cat is
865
 
                not None, then only functions in that category are iterated.
866
 
                """
867
 
                lists = [{}, {}, {}, {}]
868
 
 
869
 
                for func in self.functionIterateAll():
870
 
                        [cat_name, cat_number] = self.category_dict[func.name]
871
 
 
872
 
                        if (cat == None) or (cat == cat_name):
873
 
                                [func_cat_type, key] = classify_category(cat_name, cat_number)
874
 
 
875
 
                                if not lists[func_cat_type].has_key(key):
876
 
                                        lists[func_cat_type][key] = {}
877
 
 
878
 
                                lists[func_cat_type][key][func.name] = func
879
 
 
880
 
 
881
 
                functions = []
882
 
                for func_cat_type in range(0,4):
883
 
                        keys = lists[func_cat_type].keys()
884
 
                        keys.sort()
885
 
 
886
 
                        for key in keys:
887
 
                                names = lists[func_cat_type][key].keys()
888
 
                                names.sort()
889
 
 
890
 
                                for name in names:
891
 
                                        functions.append(lists[func_cat_type][key][name])
892
 
 
893
 
                return functions.__iter__()
894
 
 
895
 
 
896
 
        def functionIterateByOffset(self):
897
 
                max_offset = -1
898
 
                for func in self.functions_by_name.itervalues():
899
 
                        if func.offset > max_offset:
900
 
                                max_offset = func.offset
901
 
 
902
 
 
903
 
                temp = [None for i in range(0, max_offset + 1)]
904
 
                for func in self.functions_by_name.itervalues():
905
 
                        if func.offset != -1:
906
 
                                temp[ func.offset ] = func
907
 
 
908
 
 
909
 
                list = []
910
 
                for i in range(0, max_offset + 1):
911
 
                        if temp[i]:
912
 
                                list.append(temp[i])
913
 
 
914
 
                return list.__iter__();
915
 
 
916
 
 
917
 
        def functionIterateAll(self):
918
 
                return self.functions_by_name.itervalues()
919
 
 
920
 
 
921
 
        def enumIterateByName(self):
922
 
                keys = self.enums_by_name.keys()
923
 
                keys.sort()
924
 
                
925
 
                list = []
926
 
                for enum in keys:
927
 
                        list.append( self.enums_by_name[ enum ] )
928
 
 
929
 
                return list.__iter__()
930
 
 
931
 
 
932
 
        def categoryIterate(self):
933
 
                """Iterate over categories.
934
 
                
935
 
                Iterate over all known categories in the order specified by
936
 
                classify_category.  Each iterated value is a tuple of the
937
 
                name and number (which may be None) of the category.
938
 
                """
939
 
 
940
 
                list = []
941
 
                for cat_type in range(0,4):
942
 
                        keys = self.categories[cat_type].keys()
943
 
                        keys.sort()
944
 
                        
945
 
                        for key in keys:
946
 
                                list.append(self.categories[cat_type][key])
947
 
                                
948
 
                return list.__iter__()
949
 
 
950
 
 
951
 
        def get_category_for_name( self, name ):
952
 
                if self.category_dict.has_key(name):
953
 
                        return self.category_dict[name]
954
 
                else:
955
 
                        return ["<unknown category>", None]
956
 
 
957
 
 
958
 
        def typeIterate(self):
959
 
                return self.types_by_name.itervalues()
960
 
 
961
 
 
962
 
        def find_type( self, type_name ):
963
 
                if type_name in self.types_by_name:
964
 
                        return self.types_by_name[ type_name ].type_expr
965
 
                else:
966
 
                        print "Unable to find base type matching \"%s\"." % (type_name)
967
 
                        return None