mesa/progs/tools/trace/gltrace.py

190 lines
6.1 KiB
Python

#!/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 <ts@medical-insight.com>
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 <ts@medical-insight.com>
*/
"""
#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 )