]> git.cworth.org Git - apitrace/blob - retrace/glretrace.py
retrace: Implement glxCopySubBufferMESA
[apitrace] / retrace / glretrace.py
1 ##########################################################################
2 #
3 # Copyright 2010 VMware, Inc.
4 # All Rights Reserved.
5 #
6 # Permission is hereby granted, free of charge, to any person obtaining a copy
7 # of this software and associated documentation files (the "Software"), to deal
8 # in the Software without restriction, including without limitation the rights
9 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 # copies of the Software, and to permit persons to whom the Software is
11 # furnished to do so, subject to the following conditions:
12 #
13 # The above copyright notice and this permission notice shall be included in
14 # all copies or substantial portions of the Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 # THE SOFTWARE.
23 #
24 ##########################################################################/
25
26
27 """GL retracer generator."""
28
29
30 from retrace import Retracer
31 import specs.stdapi as stdapi
32 import specs.glapi as glapi
33 import specs.glesapi as glesapi
34
35
36 class GlRetracer(Retracer):
37
38     table_name = 'glretrace::gl_callbacks'
39
40     def retraceFunction(self, function):
41         Retracer.retraceFunction(self, function)
42
43     array_pointer_function_names = set((
44         "glVertexPointer",
45         "glNormalPointer",
46         "glColorPointer",
47         "glIndexPointer",
48         "glTexCoordPointer",
49         "glEdgeFlagPointer",
50         "glFogCoordPointer",
51         "glSecondaryColorPointer",
52
53         "glInterleavedArrays",
54
55         "glVertexPointerEXT",
56         "glNormalPointerEXT",
57         "glColorPointerEXT",
58         "glIndexPointerEXT",
59         "glTexCoordPointerEXT",
60         "glEdgeFlagPointerEXT",
61         "glFogCoordPointerEXT",
62         "glSecondaryColorPointerEXT",
63
64         "glVertexAttribPointer",
65         "glVertexAttribPointerARB",
66         "glVertexAttribPointerNV",
67         "glVertexAttribIPointer",
68         "glVertexAttribIPointerEXT",
69         "glVertexAttribLPointer",
70         "glVertexAttribLPointerEXT",
71         
72         #"glMatrixIndexPointerARB",
73     ))
74
75     draw_array_function_names = set([
76         "glDrawArrays",
77         "glDrawArraysEXT",
78         "glDrawArraysIndirect",
79         "glDrawArraysInstanced",
80         "glDrawArraysInstancedARB",
81         "glDrawArraysInstancedEXT",
82         "glDrawArraysInstancedBaseInstance",
83         "glDrawMeshArraysSUN",
84         "glMultiDrawArrays",
85         "glMultiDrawArraysEXT",
86         "glMultiModeDrawArraysIBM",
87         'glMultiDrawArraysIndirect',
88         'glMultiDrawArraysIndirectAMD',
89     ])
90
91     draw_elements_function_names = set([
92         "glDrawElements",
93         "glDrawElementsBaseVertex",
94         "glDrawElementsIndirect",
95         "glDrawElementsInstanced",
96         "glDrawElementsInstancedARB",
97         "glDrawElementsInstancedEXT",
98         "glDrawElementsInstancedBaseVertex",
99         "glDrawElementsInstancedBaseInstance",
100         "glDrawElementsInstancedBaseVertexBaseInstance",
101         "glDrawRangeElements",
102         "glDrawRangeElementsEXT",
103         "glDrawRangeElementsBaseVertex",
104         "glMultiDrawElements",
105         "glMultiDrawElementsBaseVertex",
106         "glMultiDrawElementsEXT",
107         "glMultiModeDrawElementsIBM",
108         'glMultiDrawElementsIndirect',
109         'glMultiDrawElementsIndirectAMD',
110     ])
111
112     draw_indirect_function_names = set([
113         "glDrawArraysIndirect",
114         "glDrawElementsIndirect",
115         'glMultiDrawArraysIndirect',
116         'glMultiDrawArraysIndirectAMD',
117         'glMultiDrawElementsIndirect',
118         'glMultiDrawElementsIndirectAMD',
119     ])
120
121     misc_draw_function_names = set([
122         "glCallList",
123         "glCallLists",
124         "glClear",
125         "glEnd",
126         "glDrawPixels",
127         "glBlitFramebuffer",
128         "glBlitFramebufferEXT",
129     ])
130
131     bind_framebuffer_function_names = set([
132         "glBindFramebuffer",
133         "glBindFramebufferEXT",
134         "glBindFramebufferOES",
135     ])
136
137     # Names of the functions that can pack into the current pixel buffer
138     # object.  See also the ARB_pixel_buffer_object specification.
139     pack_function_names = set([
140         'glGetCompressedTexImage',
141         'glGetCompressedTexImageARB',
142         'glGetCompressedTextureImageEXT',
143         'glGetCompressedMultiTexImageEXT',
144         'glGetConvolutionFilter',
145         'glGetHistogram',
146         'glGetMinmax',
147         'glGetPixelMapfv',
148         'glGetPixelMapuiv',
149         'glGetPixelMapusv',
150         'glGetPolygonStipple',
151         'glGetSeparableFilter',
152         'glGetTexImage',
153         'glGetTextureImageEXT',
154         'glGetMultiTexImageEXT',
155         'glReadPixels',
156         'glGetnCompressedTexImageARB',
157         'glGetnConvolutionFilterARB',
158         'glGetnHistogramARB',
159         'glGetnMinmaxARB',
160         'glGetnPixelMapfvARB',
161         'glGetnPixelMapuivARB',
162         'glGetnPixelMapusvARB',
163         'glGetnPolygonStippleARB',
164         'glGetnSeparableFilterARB',
165         'glGetnTexImageARB',
166         'glReadnPixelsARB',
167     ])
168
169     map_function_names = set([
170         'glMapBuffer',
171         'glMapBufferARB',
172         'glMapBufferOES',
173         'glMapBufferRange',
174         'glMapNamedBufferEXT',
175         'glMapNamedBufferRangeEXT',
176         'glMapObjectBufferATI',
177     ])
178
179     unmap_function_names = set([
180         'glUnmapBuffer',
181         'glUnmapBufferARB',
182         'glUnmapBufferOES',
183         'glUnmapNamedBufferEXT',
184         'glUnmapObjectBufferATI',
185     ])
186
187     def retraceFunctionBody(self, function):
188         is_array_pointer = function.name in self.array_pointer_function_names
189         is_draw_array = function.name in self.draw_array_function_names
190         is_draw_elements = function.name in self.draw_elements_function_names
191         is_misc_draw = function.name in self.misc_draw_function_names
192
193         if is_array_pointer or is_draw_array or is_draw_elements:
194             print '    if (retrace::parser.version < 1) {'
195
196             if is_array_pointer or is_draw_array:
197                 print '        GLint _array_buffer = 0;'
198                 print '        glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &_array_buffer);'
199                 print '        if (!_array_buffer) {'
200                 self.failFunction(function)
201                 print '        }'
202
203             if is_draw_elements:
204                 print '        GLint _element_array_buffer = 0;'
205                 print '        glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &_element_array_buffer);'
206                 print '        if (!_element_array_buffer) {'
207                 self.failFunction(function)
208                 print '        }'
209             
210             print '    }'
211
212         # When no pack buffer object is bound, the pack functions are no-ops.
213         if function.name in self.pack_function_names:
214             print '    GLint _pack_buffer = 0;'
215             print '    glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &_pack_buffer);'
216             print '    if (!_pack_buffer) {'
217             print '        return;'
218             print '    }'
219
220         # Pre-snapshots
221         if function.name in self.bind_framebuffer_function_names:
222             print '    assert(call.flags & trace::CALL_FLAG_SWAP_RENDERTARGET);'
223         if function.name == 'glFrameTerminatorGREMEDY':
224             print '    glretrace::frame_complete(call);'
225             return
226
227         Retracer.retraceFunctionBody(self, function)
228
229         # Post-snapshots
230         if function.name in ('glFlush', 'glFinish'):
231             print '    if (!retrace::doubleBuffer) {'
232             print '        glretrace::frame_complete(call);'
233             print '    }'
234         if is_draw_array or is_draw_elements or is_misc_draw:
235             print '    assert(call.flags & trace::CALL_FLAG_RENDER);'
236
237
238     def invokeFunction(self, function):
239         # Infer the drawable size from GL calls
240         if function.name == "glViewport":
241             print '    glretrace::updateDrawable(x + width, y + height);'
242         if function.name == "glViewportArray":
243             # We are concerned about drawables so only care for the first viewport
244             print '    if (first == 0 && count > 0) {'
245             print '        GLfloat x = v[0], y = v[1], w = v[2], h = v[3];'
246             print '        glretrace::updateDrawable(x + w, y + h);'
247             print '    }'
248         if function.name == "glViewportIndexedf":
249             print '    if (index == 0) {'
250             print '        glretrace::updateDrawable(x + w, y + h);'
251             print '    }'
252         if function.name == "glViewportIndexedfv":
253             print '    if (index == 0) {'
254             print '        GLfloat x = v[0], y = v[1], w = v[2], h = v[3];'
255             print '        glretrace::updateDrawable(x + w, y + h);'
256             print '    }'
257         if function.name in ('glBlitFramebuffer', 'glBlitFramebufferEXT'):
258             # Some applications do all their rendering in a framebuffer, and
259             # then just blit to the drawable without ever calling glViewport.
260             print '    glretrace::updateDrawable(std::max(dstX0, dstX1), std::max(dstY0, dstY1));'
261
262         if function.name == "glEnd":
263             print '    glretrace::insideGlBeginEnd = false;'
264
265         if function.name.startswith('gl') and not function.name.startswith('glX'):
266             print r'    if (retrace::debug && !glretrace::getCurrentContext()) {'
267             print r'        retrace::warning(call) << "no current context\n";'
268             print r'    }'
269
270         if function.name == 'memcpy':
271             print '    if (!dest || !src || !n) return;'
272
273         # Skip glEnable/Disable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB) as we don't
274         # faithfully set the CONTEXT_DEBUG_BIT_ARB flags on context creation.
275         if function.name in ('glEnable', 'glDisable'):
276             print '    if (cap == GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB) return;'
277
278         # Destroy the buffer mapping
279         if function.name in self.unmap_function_names:
280             print r'        GLvoid *ptr = NULL;'
281             if function.name == 'glUnmapBuffer':
282                 print r'            glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &ptr);'
283             elif function.name == 'glUnmapBufferARB':
284                 print r'            glGetBufferPointervARB(target, GL_BUFFER_MAP_POINTER_ARB, &ptr);'
285             elif function.name == 'glUnmapBufferOES':
286                 print r'            glGetBufferPointervOES(target, GL_BUFFER_MAP_POINTER_OES, &ptr);'
287             elif function.name == 'glUnmapNamedBufferEXT':
288                 print r'            glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &ptr);'
289             elif function.name == 'glUnmapObjectBufferATI':
290                 # TODO
291                 pass
292             else:
293                 assert False
294             print r'        if (ptr) {'
295             print r'            retrace::delRegionByPointer(ptr);'
296             print r'        } else {'
297             print r'            retrace::warning(call) << "no current context\n";'
298             print r'        }'
299
300         if function.name in ('glBindProgramPipeline', 'glBindProgramPipelineEXT'):
301             # Note if glBindProgramPipeline has ever been called
302             print r'    if (pipeline) {'
303             print r'        _pipelineHasBeenBound = true;'
304             print r'    }'
305
306         profileDraw = (
307             function.name in self.draw_array_function_names or
308             function.name in self.draw_elements_function_names or
309             function.name in self.draw_indirect_function_names or
310             function.name in self.misc_draw_function_names or
311             function.name == 'glBegin'
312         )
313
314         if function.name in ('glUseProgram', 'glUseProgramObjectARB'):
315             print r'    glretrace::Context *currentContext = glretrace::getCurrentContext();'
316             print r'    if (currentContext) {'
317             print r'        currentContext->activeProgram = call.arg(0).toUInt();'
318             print r'    }'
319
320         # Only profile if not inside a list as the queries get inserted into list
321         if function.name == 'glNewList':
322             print r'    glretrace::insideList = true;'
323
324         if function.name == 'glEndList':
325             print r'    glretrace::insideList = false;'
326
327         if function.name != 'glEnd':
328             print r'    if (!glretrace::insideList && !glretrace::insideGlBeginEnd && retrace::profiling) {'
329             if profileDraw:
330                 print r'        glretrace::beginProfile(call, true);'
331             else:
332                 print r'        glretrace::beginProfile(call, false);'
333             print r'    }'
334
335         if function.name == 'glCreateShaderProgramv':
336             # When dumping state, break down glCreateShaderProgramv so that the
337             # shader source can be recovered.
338             print r'    if (retrace::dumpingState) {'
339             print r'        GLuint _shader = glCreateShader(type);'
340             print r'        if (_shader) {'
341             print r'            glShaderSource(_shader, count, strings, NULL);'
342             print r'            glCompileShader(_shader);'
343             print r'            const GLuint _program = glCreateProgram();'
344             print r'            if (_program) {'
345             print r'                GLint compiled = GL_FALSE;'
346             print r'                glGetShaderiv(_shader, GL_COMPILE_STATUS, &compiled);'
347             print r'                glProgramParameteri(_program, GL_PROGRAM_SEPARABLE, GL_TRUE);'
348             print r'                if (compiled) {'
349             print r'                    glAttachShader(_program, _shader);'
350             print r'                    glLinkProgram(_program);'
351             print r'                    //glDetachShader(_program, _shader);'
352             print r'                }'
353             print r'                //append-shader-info-log-to-program-info-log'
354             print r'            }'
355             print r'            //glDeleteShader(_shader);'
356             print r'            _result = _program;'
357             print r'        } else {'
358             print r'            _result = 0;'
359             print r'        }'
360             print r'    } else {'
361             Retracer.invokeFunction(self, function)
362             print r'    }'
363         else:
364             Retracer.invokeFunction(self, function)
365
366         if function.name == "glBegin":
367             print '    glretrace::insideGlBeginEnd = true;'
368
369         print r'    if (!glretrace::insideList && !glretrace::insideGlBeginEnd && retrace::profiling) {'
370         if profileDraw:
371             print r'        glretrace::endProfile(call, true);'
372         else:
373             print r'        glretrace::endProfile(call, false);'
374         print r'    }'
375
376         # Error checking
377         if function.name.startswith('gl'):
378             # glGetError is not allowed inside glBegin/glEnd
379             print '    if (retrace::debug && !glretrace::insideGlBeginEnd && glretrace::getCurrentContext()) {'
380             print '        glretrace::checkGlError(call);'
381             if function.name in ('glProgramStringARB', 'glProgramStringNV'):
382                 print r'        GLint error_position = -1;'
383                 print r'        glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_position);'
384                 print r'        if (error_position != -1) {'
385                 print r'            const char *error_string = (const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB);'
386                 print r'            retrace::warning(call) << error_string << "\n";'
387                 print r'        }'
388             if function.name == 'glCompileShader':
389                 print r'        GLint compile_status = 0;'
390                 print r'        glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);'
391                 print r'        if (!compile_status) {'
392                 print r'             GLint info_log_length = 0;'
393                 print r'             glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length);'
394                 print r'             GLchar *infoLog = new GLchar[info_log_length];'
395                 print r'             glGetShaderInfoLog(shader, info_log_length, NULL, infoLog);'
396                 print r'             retrace::warning(call) << infoLog << "\n";'
397                 print r'             delete [] infoLog;'
398                 print r'        }'
399             if function.name in ('glLinkProgram', 'glCreateShaderProgramv', 'glCreateShaderProgramEXT'):
400                 if function.name != 'glLinkProgram':
401                     print r'        GLuint program = _result;'
402                 print r'        GLint link_status = 0;'
403                 print r'        glGetProgramiv(program, GL_LINK_STATUS, &link_status);'
404                 print r'        if (!link_status) {'
405                 print r'             GLint info_log_length = 0;'
406                 print r'             glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length);'
407                 print r'             GLchar *infoLog = new GLchar[info_log_length];'
408                 print r'             glGetProgramInfoLog(program, info_log_length, NULL, infoLog);'
409                 print r'             retrace::warning(call) << infoLog << "\n";'
410                 print r'             delete [] infoLog;'
411                 print r'        }'
412             if function.name == 'glCompileShaderARB':
413                 print r'        GLint compile_status = 0;'
414                 print r'        glGetObjectParameterivARB(shaderObj, GL_OBJECT_COMPILE_STATUS_ARB, &compile_status);'
415                 print r'        if (!compile_status) {'
416                 print r'             GLint info_log_length = 0;'
417                 print r'             glGetObjectParameterivARB(shaderObj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_log_length);'
418                 print r'             GLchar *infoLog = new GLchar[info_log_length];'
419                 print r'             glGetInfoLogARB(shaderObj, info_log_length, NULL, infoLog);'
420                 print r'             retrace::warning(call) << infoLog << "\n";'
421                 print r'             delete [] infoLog;'
422                 print r'        }'
423             if function.name == 'glLinkProgramARB':
424                 print r'        GLint link_status = 0;'
425                 print r'        glGetObjectParameterivARB(programObj, GL_OBJECT_LINK_STATUS_ARB, &link_status);'
426                 print r'        if (!link_status) {'
427                 print r'             GLint info_log_length = 0;'
428                 print r'             glGetObjectParameterivARB(programObj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_log_length);'
429                 print r'             GLchar *infoLog = new GLchar[info_log_length];'
430                 print r'             glGetInfoLogARB(programObj, info_log_length, NULL, infoLog);'
431                 print r'             retrace::warning(call) << infoLog << "\n";'
432                 print r'             delete [] infoLog;'
433                 print r'        }'
434             if function.name in self.map_function_names:
435                 print r'        if (!_result) {'
436                 print r'             retrace::warning(call) << "failed to map buffer\n";'
437                 print r'        }'
438             if function.name in self.unmap_function_names and function.type is not stdapi.Void:
439                 print r'        if (!_result) {'
440                 print r'             retrace::warning(call) << "failed to unmap buffer\n";'
441                 print r'        }'
442             if function.name in ('glGetAttribLocation', 'glGetAttribLocationARB'):
443                 print r'    GLint _origResult = call.ret->toSInt();'
444                 print r'    if (_result != _origResult) {'
445                 print r'        retrace::warning(call) << "vertex attrib location mismatch " << _origResult << " -> " << _result << "\n";'
446                 print r'    }'
447             if function.name in ('glCheckFramebufferStatus', 'glCheckFramebufferStatusEXT', 'glCheckNamedFramebufferStatusEXT'):
448                 print r'    GLint _origResult = call.ret->toSInt();'
449                 print r'    if (_origResult == GL_FRAMEBUFFER_COMPLETE &&'
450                 print r'        _result != GL_FRAMEBUFFER_COMPLETE) {'
451                 print r'        retrace::warning(call) << "incomplete framebuffer (" << glstate::enumToString(_result) << ")\n";'
452                 print r'    }'
453             print '    }'
454
455         # Query the buffer length for whole buffer mappings
456         if function.name in self.map_function_names:
457             if 'length' in function.argNames():
458                 assert 'BufferRange' in function.name
459             else:
460                 assert 'BufferRange' not in function.name
461                 print r'    GLint length = 0;'
462                 if function.name in ('glMapBuffer', 'glMapBufferOES'):
463                     print r'    glGetBufferParameteriv(target, GL_BUFFER_SIZE, &length);'
464                 elif function.name == 'glMapBufferARB':
465                     print r'    glGetBufferParameterivARB(target, GL_BUFFER_SIZE_ARB, &length);'
466                 elif function.name == 'glMapNamedBufferEXT':
467                     print r'    glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_SIZE, &length);'
468                 elif function.name == 'glMapObjectBufferATI':
469                     print r'    glGetObjectBufferivATI(buffer, GL_OBJECT_BUFFER_SIZE_ATI, &length);'
470                 else:
471                     assert False
472
473     def extractArg(self, function, arg, arg_type, lvalue, rvalue):
474         if function.name in self.array_pointer_function_names and arg.name == 'pointer':
475             print '    %s = static_cast<%s>(retrace::toPointer(%s, true));' % (lvalue, arg_type, rvalue)
476             return
477
478         if function.name in self.draw_elements_function_names and arg.name == 'indices' or\
479            function.name in self.draw_indirect_function_names and arg.name == 'indirect':
480             self.extractOpaqueArg(function, arg, arg_type, lvalue, rvalue)
481             return
482
483         # Handle pointer with offsets into the current pack pixel buffer
484         # object.
485         if function.name in self.pack_function_names and arg.output:
486             assert isinstance(arg_type, (stdapi.Pointer, stdapi.Array, stdapi.Blob, stdapi.Opaque))
487             print '    %s = static_cast<%s>((%s).toPointer());' % (lvalue, arg_type, rvalue)
488             return
489
490         if arg.type is glapi.GLlocation \
491            and 'program' not in function.argNames():
492             # Determine the active program for uniforms swizzling
493             print '    GLint program = -1;'
494             print '    if (glretrace::insideList) {'
495             print '        // glUseProgram & glUseProgramObjectARB are display-list-able'
496             print r'    glretrace::Context *currentContext = glretrace::getCurrentContext();'
497             print '        program = _program_map[currentContext->activeProgram];'
498             print '    } else {'
499             print '        GLint pipeline = 0;'
500             print '        if (_pipelineHasBeenBound) {'
501             print '            glGetIntegerv(GL_PROGRAM_PIPELINE_BINDING, &pipeline);'
502             print '        }'
503             print '        if (pipeline) {'
504             print '            glGetProgramPipelineiv(pipeline, GL_ACTIVE_PROGRAM, &program);'
505             print '        } else {'
506             print '            glGetIntegerv(GL_CURRENT_PROGRAM, &program);'
507             print '        }'
508             print '    }'
509             print
510
511         if arg.type is glapi.GLlocationARB \
512            and 'programObj' not in function.argNames():
513             print '    GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);'
514
515         Retracer.extractArg(self, function, arg, arg_type, lvalue, rvalue)
516
517         # Don't try to use more samples than the implementation supports
518         if arg.name == 'samples':
519             assert arg.type is glapi.GLsizei
520             print '    GLint max_samples = 0;'
521             print '    glGetIntegerv(GL_MAX_SAMPLES, &max_samples);'
522             print '    if (samples > max_samples) {'
523             print '        samples = max_samples;'
524             print '    }'
525
526         # These parameters are referred beyond the call life-time
527         # TODO: Replace ad-hoc solution for bindable parameters with general one
528         if function.name in ('glFeedbackBuffer', 'glSelectBuffer') and arg.output:
529             print '    _allocator.bind(%s);' % arg.name
530
531
532
533 if __name__ == '__main__':
534     print r'''
535 #include <string.h>
536
537 #include "glproc.hpp"
538 #include "glretrace.hpp"
539 #include "glstate.hpp"
540
541
542 static bool _pipelineHasBeenBound = false;
543 '''
544     api = stdapi.API()
545     api.addModule(glapi.glapi)
546     api.addModule(glesapi.glesapi)
547     retracer = GlRetracer()
548     retracer.retraceApi(api)