blob: 973881ac94df8c528a389f2d15b2bdafca89d188 [file] [log] [blame]
Brian Paul65ced472006-06-02 14:50:28 +00001#!/usr/bin/env python
2
3# Copyright (C) 2006 Thomas Sondergaard
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# Thomas Sondergaard <ts@medical-insight.com>
27
28import gl_XML, glX_XML, glX_proto_common, license
29import sys, getopt, copy, string
30
31def create_argument_string(parameters):
32 """Create a parameter string from a list of gl_parameters."""
33
34 list = []
35 for p in parameters:
36 list.append( p.name )
37 #if len(list) == 0: list = ["void"]
38
39 return string.join(list, ", ")
40
41def create_logfunc_string(func, name):
42 """Create a parameter string from a list of gl_parameters."""
43
44 list = []
45 list.append('"gl' + name + '("')
46 sep = None
47 for p in func.parameters:
48 if (sep):
49 list.append(sep)
50 list.append( p.name )
51 sep = '", "'
52 list.append('");"')
53 #if len(list) == 0: list = ["void"]
54
55 return "if (config.logCalls) GLTRACE_LOG(" + string.join(list, " << ")+");";
56
57class PrintGltrace(glX_proto_common.glx_print_proto): #(gl_XML.gl_print_base):
58 def __init__(self):
59 gl_XML.gl_print_base.__init__(self)
60
61 self.name = "gltrace.py"
62 self.license = license.bsd_license_template % ( \
63"""Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
64(C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
65 #self.header_tag = "_INDIRECT_H_"
66
67 self.last_category = ""
68 return
69
70
71 def printRealHeader(self):
72 print """/**
73 * \\file
74 * gl and glX wrappers for tracing
75 *
76 * \\author Thomas Sondergaard <ts@medical-insight.com>
77 */
78"""
79 #self.printVisibility( "HIDDEN", "hidden" )
80 #self.printFastcall()
81 #self.printNoinline()
82
83 print """
84#include <GL/gl.h>
85#include <GL/glx.h>
86#include <GL/glu.h>
87#include <dlfcn.h>
88#include "gltrace_support.h"
89
90using namespace gltrace;
91
92static GLenum real_glGetError() {
93 static GLenum (*real_func)(void) = 0;
94 if (!real_func) real_func = (GLenum (*)(void)) dlsym(RTLD_NEXT, "glGetError");
95 return real_func();
96}
97
98bool betweenGLBeginEnd = false;
99
100extern "C" {
101
102
103__GLXextFuncPtr real_glXGetProcAddressARB(const GLubyte *func_name) {
104 static __GLXextFuncPtr (*real_func)(const GLubyte *func_name) = 0;
105 if (!real_func) real_func = (__GLXextFuncPtr (*)(const GLubyte *func_name)) dlsym(RTLD_NEXT, "glXGetProcAddressARB");
106
107 return real_func(func_name);
108}
109
110__GLXextFuncPtr glXGetProcAddressARB(const GLubyte *func_name_ubyte) {
111 std::string func_name =
112 std::string("gltrace_")+reinterpret_cast<const char*>(func_name_ubyte);
113
114 __GLXextFuncPtr f = (__GLXextFuncPtr) dlsym(RTLD_DEFAULT, func_name.c_str());
115 if (!f) {
116 GLTRACE_LOG("warning: Could not resolve '" << func_name << "' - function will not be intercepted");
117 return real_glXGetProcAddressARB(func_name_ubyte);
118 }
119 return f;
120}
121
122"""
123
124 def printRealFooter(self):
125 print "} // Extern \"C\""
126
127 def printBody(self, api):
128 for func in api.functionIterateGlx():
129 for func_name in func.entry_points:
130 functionPrefix = ""
131 use_dlsym = True
132 if (api.get_category_for_name(func.name)[1] != None):
133 functionPrefix = "gltrace_"
134 use_dlsym = False
135
136 print '%s %sgl%s(%s) {' % (func.return_type, functionPrefix, func_name, func.get_parameter_string())
137 if (use_dlsym):
138 print ' static %s (*real_func)(%s) = 0;' % (func.return_type, func.get_parameter_string())
139 print ' if (!real_func) real_func = (%s (*)(%s)) dlsym(RTLD_NEXT, "gl%s");' % (func.return_type, func.get_parameter_string(), func_name)
140 else: # use glXGetProcAddressArb
141 print ' static %s (*real_func)(%s) = 0;' % (func.return_type, func.get_parameter_string())
142 print ' if (!real_func) real_func = (%s (*)(%s)) real_glXGetProcAddressARB((GLubyte *)"gl%s");' % (func.return_type, func.get_parameter_string(), func_name)
143 print ' ' + create_logfunc_string(func, func_name)
144 if (func.return_type == "void"):
145 print ' real_func(%s);' % (create_argument_string(func.parameters))
146 else:
147 print ' %s retval = real_func(%s);' % (func.return_type, create_argument_string(func.parameters))
148 if (func.name == "Begin"):
149 print ' betweenGLBeginEnd = true;'
150 elif (func.name == "End"):
151 print ' betweenGLBeginEnd = false;'
152 print ' if (!betweenGLBeginEnd && config.checkErrors) {'
153 print ' GLenum res;'
154 print ' while ((res = real_glGetError ()) != GL_NO_ERROR) '
155 print ' GLTRACE_LOG("OpenGL Error (" << res << "): <" << gluErrorString(res) << "> at " << gltrace::getStackTrace());'
156 print ' }'
157 if (func.return_type != "void"):
158 print " return retval;"
159 print '}'
160
161
162def show_usage():
163 print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys.argv[0]
164 print " -m output_mode Output mode can be one of 'proto', 'init_c' or 'init_h'."
165 print " -d Enable extra debug information in the generated code."
166 sys.exit(1)
167
168
169if __name__ == '__main__':
170 file_name = "gl_API.xml"
171
172 try:
173 (args, trail) = getopt.getopt(sys.argv[1:], "f:d")
174 except Exception,e:
175 show_usage()
176
177 debug = 0
178 for (arg,val) in args:
179 if arg == "-f":
180 file_name = val
181 elif arg == "-d":
182 debug = 1
183
184 printer = PrintGltrace()
185
186 printer.debug = debug
187 api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() )
188
189 printer.Print( api )