diff options
author | Brian Paul <[email protected]> | 2006-06-02 14:50:28 +0000 |
---|---|---|
committer | Brian Paul <[email protected]> | 2006-06-02 14:50:28 +0000 |
commit | 65ced474536bad23ee204170918f56eb8f8c4bf9 (patch) | |
tree | 737457c8263b5fcf8bcc0756f0e61b2578f32774 /progs/tools/trace/gltrace.py | |
parent | 21fbdb14e9a189272fd7398be525e087dbf017dc (diff) |
Thomas Sondergaard's API tracer
Diffstat (limited to 'progs/tools/trace/gltrace.py')
-rw-r--r-- | progs/tools/trace/gltrace.py | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/progs/tools/trace/gltrace.py b/progs/tools/trace/gltrace.py new file mode 100644 index 00000000000..973881ac94d --- /dev/null +++ b/progs/tools/trace/gltrace.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python + +# Copyright (C) 2006 Thomas Sondergaard +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, and/or sell copies of the Software, and to permit persons to whom +# the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# Authors: +# Thomas Sondergaard <[email protected]> + +import gl_XML, glX_XML, glX_proto_common, license +import sys, getopt, copy, string + +def create_argument_string(parameters): + """Create a parameter string from a list of gl_parameters.""" + + list = [] + for p in parameters: + list.append( p.name ) + #if len(list) == 0: list = ["void"] + + return string.join(list, ", ") + +def create_logfunc_string(func, name): + """Create a parameter string from a list of gl_parameters.""" + + list = [] + list.append('"gl' + name + '("') + sep = None + for p in func.parameters: + if (sep): + list.append(sep) + list.append( p.name ) + sep = '", "' + list.append('");"') + #if len(list) == 0: list = ["void"] + + return "if (config.logCalls) GLTRACE_LOG(" + string.join(list, " << ")+");"; + +class PrintGltrace(glX_proto_common.glx_print_proto): #(gl_XML.gl_print_base): + def __init__(self): + gl_XML.gl_print_base.__init__(self) + + self.name = "gltrace.py" + self.license = license.bsd_license_template % ( \ +"""Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +(C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM") + #self.header_tag = "_INDIRECT_H_" + + self.last_category = "" + return + + + def printRealHeader(self): + print """/** + * \\file + * gl and glX wrappers for tracing + * + * \\author Thomas Sondergaard <[email protected]> + */ +""" + #self.printVisibility( "HIDDEN", "hidden" ) + #self.printFastcall() + #self.printNoinline() + + print """ +#include <GL/gl.h> +#include <GL/glx.h> +#include <GL/glu.h> +#include <dlfcn.h> +#include "gltrace_support.h" + +using namespace gltrace; + +static GLenum real_glGetError() { + static GLenum (*real_func)(void) = 0; + if (!real_func) real_func = (GLenum (*)(void)) dlsym(RTLD_NEXT, "glGetError"); + return real_func(); +} + +bool betweenGLBeginEnd = false; + +extern "C" { + + +__GLXextFuncPtr real_glXGetProcAddressARB(const GLubyte *func_name) { + static __GLXextFuncPtr (*real_func)(const GLubyte *func_name) = 0; + if (!real_func) real_func = (__GLXextFuncPtr (*)(const GLubyte *func_name)) dlsym(RTLD_NEXT, "glXGetProcAddressARB"); + + return real_func(func_name); +} + +__GLXextFuncPtr glXGetProcAddressARB(const GLubyte *func_name_ubyte) { + std::string func_name = + std::string("gltrace_")+reinterpret_cast<const char*>(func_name_ubyte); + + __GLXextFuncPtr f = (__GLXextFuncPtr) dlsym(RTLD_DEFAULT, func_name.c_str()); + if (!f) { + GLTRACE_LOG("warning: Could not resolve '" << func_name << "' - function will not be intercepted"); + return real_glXGetProcAddressARB(func_name_ubyte); + } + return f; +} + +""" + + def printRealFooter(self): + print "} // Extern \"C\"" + + def printBody(self, api): + for func in api.functionIterateGlx(): + for func_name in func.entry_points: + functionPrefix = "" + use_dlsym = True + if (api.get_category_for_name(func.name)[1] != None): + functionPrefix = "gltrace_" + use_dlsym = False + + print '%s %sgl%s(%s) {' % (func.return_type, functionPrefix, func_name, func.get_parameter_string()) + if (use_dlsym): + print ' static %s (*real_func)(%s) = 0;' % (func.return_type, func.get_parameter_string()) + print ' if (!real_func) real_func = (%s (*)(%s)) dlsym(RTLD_NEXT, "gl%s");' % (func.return_type, func.get_parameter_string(), func_name) + else: # use glXGetProcAddressArb + print ' static %s (*real_func)(%s) = 0;' % (func.return_type, func.get_parameter_string()) + print ' if (!real_func) real_func = (%s (*)(%s)) real_glXGetProcAddressARB((GLubyte *)"gl%s");' % (func.return_type, func.get_parameter_string(), func_name) + print ' ' + create_logfunc_string(func, func_name) + if (func.return_type == "void"): + print ' real_func(%s);' % (create_argument_string(func.parameters)) + else: + print ' %s retval = real_func(%s);' % (func.return_type, create_argument_string(func.parameters)) + if (func.name == "Begin"): + print ' betweenGLBeginEnd = true;' + elif (func.name == "End"): + print ' betweenGLBeginEnd = false;' + print ' if (!betweenGLBeginEnd && config.checkErrors) {' + print ' GLenum res;' + print ' while ((res = real_glGetError ()) != GL_NO_ERROR) ' + print ' GLTRACE_LOG("OpenGL Error (" << res << "): <" << gluErrorString(res) << "> at " << gltrace::getStackTrace());' + print ' }' + if (func.return_type != "void"): + print " return retval;" + print '}' + + +def show_usage(): + print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys.argv[0] + print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'." + print " -d Enable extra debug information in the generated code." + sys.exit(1) + + +if __name__ == '__main__': + file_name = "gl_API.xml" + + try: + (args, trail) = getopt.getopt(sys.argv[1:], "f:d") + except Exception,e: + show_usage() + + debug = 0 + for (arg,val) in args: + if arg == "-f": + file_name = val + elif arg == "-d": + debug = 1 + + printer = PrintGltrace() + + printer.debug = debug + api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() ) + + printer.Print( api ) |