blob: 3e3a2be817b54e3ff99b84c537702c9a3889308a [file] [log] [blame]
José Fonseca669b1222011-02-20 09:05:10 +00001##########################################################################
2#
3# Copyright 2008-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 tracing generator."""
28
29
30from glxapi import glxapi
31from trace import Tracer, dump_instance
32
33
34class GlTracer(Tracer):
35
José Fonseca14c21bc2011-02-20 23:32:22 +000036 def header(self, api):
37 Tracer.header(self, api)
38 self.state_tracker_decl(api)
39
40 def footer(self, api):
41 Tracer.footer(self, api)
42 self.state_tracker_impl(api)
43
44 array_names = {
45 "VERTEX": "glVertexPointer",
46 "NORMAL": "glNormalPointer",
47 "COLOR": "glColorPointer",
48 "INDEX": "glIndexPointer",
49 "TEX_COORD": "glTexCoordPointer",
50 "EDGE_FLAG": "glEdgeFlagPointer",
51 "FOG_COORD": "glFogCoordPointer",
52 "SECONDARY_COLOR": "glSecondaryColorPointer",
53 }
54
José Fonseca669b1222011-02-20 09:05:10 +000055 pointer_function_names = {
José Fonseca14c21bc2011-02-20 23:32:22 +000056 "glVertexPointer": "VERTEX",
57 "glNormalPointer": "NORMAL",
58 "glColorPointer": "COLOR",
59 "glIndexPointer": "INDEX",
60 "glTexCoordPointer": "TEX_COORD",
61 "glEdgeFlagPointer": "EDGE_FLAG",
62 "glFogCoordPointer": "FOG_COORD",
63 "glSecondaryColorPointer": "SECONDARY_COLOR",
64 #"glInterleavedArrays": ("InterleavedArrays", None)
65 #"glVertexPointerEXT": "VERTEX",
66 #"glNormalPointerEXT": "NORMAL",
67 #"glColorPointerEXT": "COLOR",
68 #"glIndexPointerEXT": "INDEX",
69 #"glTexCoordPointerEXT": "TEX_COORD",
70 #"glEdgeFlagPointerEXT": "EDGE_FLAG",
71 #"glFogCoordPointerEXT": "FOG_COORD",
72 #"glSecondaryColorPointerEXT": "SECONDARY_COLOR",
José Fonseca669b1222011-02-20 09:05:10 +000073
74 #"glVertexAttribPointer": "VertexAttribPointer",
75 #"glVertexAttribPointerARB": "VertexAttribPointer",
76 #"glVertexAttribPointerNV": "VertexAttribPointer",
77 #"glVertexAttribLPointer": "VertexAttribLPointer",
78
79 #"glMatrixIndexPointerARB": "MatrixIndexPointer",
80 }
81
José Fonseca14c21bc2011-02-20 23:32:22 +000082 bind_buffer_enums = [
83 'ARRAY_BUFFER',
84 'ELEMENT_ARRAY_BUFFER',
85 'PIXEL_PACK_BUFFER',
86 'PIXEL_UNPACK_BUFFER',
87 ]
José Fonseca669b1222011-02-20 09:05:10 +000088
José Fonseca14c21bc2011-02-20 23:32:22 +000089 client_state_enums = [
90 'COLOR_ARRAY',
91 'EDGE_FLAG_ARRAY',
92 'FOG_COORD_ARRAY',
93 'INDEX_ARRAY',
94 'NORMAL_ARRAY',
95 'SECONDARY_COLOR_ARRAY',
96 'TEXTURE_COORD_ARRAY',
97 'VERTEX_ARRAY',
98 ]
José Fonseca669b1222011-02-20 09:05:10 +000099
100 def state_tracker_decl(self, api):
101 # A simple state tracker to track the pointer values
102
José Fonseca669b1222011-02-20 09:05:10 +0000103 # define the NEW_XXXX dirty flags
José Fonseca14c21bc2011-02-20 23:32:22 +0000104 value = 1
105 for array_name in self.array_names.iterkeys():
106 dirtyflag = "NEW_%s" % array_name.upper()
107 print '#define %s 0x%x' % (dirtyflag, value)
108 value <<= 1
José Fonseca669b1222011-02-20 09:05:10 +0000109 print
110
111 # declare the state structure
112 print 'struct {'
José Fonseca14c21bc2011-02-20 23:32:22 +0000113 for enum in self.bind_buffer_enums:
114 print ' GLuint %s;' % (enum.lower(),)
115 for enum in self.client_state_enums:
116 print ' GLboolean %s;' % (enum.lower(),)
117 for array_name, function_name in self.array_names.iteritems():
118 function = api.get_function_by_name(function_name)
José Fonseca669b1222011-02-20 09:05:10 +0000119 print ' struct {'
120 for arg in function.args:
121 print ' %s %s;' % (arg.type, arg.name)
José Fonseca14c21bc2011-02-20 23:32:22 +0000122 print ' } %s;' % array_name.lower()
José Fonseca669b1222011-02-20 09:05:10 +0000123 print ' unsigned dirty;'
124 print '} __state;'
125 print
José Fonseca14c21bc2011-02-20 23:32:22 +0000126 print 'static void __state_update(GLsizei maxIndex);'
127 print
128
129 def trace_function_impl_body(self, function):
130 # Track bound VBOs
131 if function.name in ('glBindBuffer', 'glBindBufferARB'):
132 print ' switch(%s) {' % function.args[0].name
133 for enum in self.bind_buffer_enums:
134 print ' case GL_%s:' % enum
135 print ' __state.%s = %s;' % (enum.lower(), function.args[1].name)
136 print ' break;'
137 print ' }'
138
139 # Track enabled arrays
140 if function.name == 'glEnableClientState':
141 print ' switch(%s) {' % function.args[0].name
142 for enum in self.client_state_enums:
143 print ' case GL_%s:' % enum
144 print ' __state.%s = GL_TRUE;' % (enum.lower(),)
145 print ' break;'
146 print ' }'
147 if function.name == 'glDisableClientState':
148 print ' switch(%s) {' % function.args[0].name
149 for enum in self.client_state_enums:
150 print ' case GL_%s:' % enum
151 print ' __state.%s = GL_FALSE;' % (enum.lower(),)
152 print ' break;'
153 print ' }'
154
155 # Track array pointers
156 if function.name in self.pointer_function_names:
157 array_name = self.pointer_function_names[function.name]
158 dirtyflag = "NEW_%s" % array_name.upper()
159 for arg in function.args:
160 assert not arg.output
161 print ' __state.%s.%s = %s;' % (array_name.lower(), arg.name, arg.name)
162 print ' __state.dirty |= %s; ' % dirtyflag
163
164 # Defer tracing
165 self.dispatch_function(function)
166 return
167
168 if function.name == 'glDrawArrays':
169 print ' __state_update(first + count - 1);'
170
171 Tracer.trace_function_impl_body(self, function)
José Fonseca669b1222011-02-20 09:05:10 +0000172
173 def state_tracker_impl(self, api):
174 # A simple state tracker to track the pointer values
175
José Fonseca669b1222011-02-20 09:05:10 +0000176 # update the state
José Fonseca14c21bc2011-02-20 23:32:22 +0000177 print 'static void __state_update(GLsizei maxIndex)'
José Fonseca669b1222011-02-20 09:05:10 +0000178 print '{'
179 print ' GLint __array_buffer = 0;'
José Fonseca14c21bc2011-02-20 23:32:22 +0000180 print ' __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
181 for array_name, function_name in self.array_names.iteritems():
182 function = api.get_function_by_name(function_name)
183 dirtyflag = "NEW_%s" % array_name.upper()
184 if array_name == 'TEX_COORD':
185 enableflag = 'TEXTURE_COORD_ARRAY'.lower()
186 else:
187 enableflag = '%s_array' % array_name.lower()
188 print ' if (__state.%s && (__state.dirty & %s)) {' % (enableflag, dirtyflag)
José Fonseca669b1222011-02-20 09:05:10 +0000189 print ' unsigned __call = Trace::BeginEnter(__%s_sig);' % (function.name,)
190 for arg in function.args:
191 assert not arg.output
José Fonseca14c21bc2011-02-20 23:32:22 +0000192 value = '__state.%s.%s' % (array_name.lower(), arg.name)
José Fonseca669b1222011-02-20 09:05:10 +0000193 print ' Trace::BeginArg(%u);' % (arg.index,)
José Fonseca14c21bc2011-02-20 23:32:22 +0000194 if arg.name != 'pointer':
195 dump_instance(arg.type, value)
196 else:
197 print ' if (__state.array_buffer) {'
198 print ' Trace::LiteralOpaque((const void *)%s);' % value
199 print ' __state.dirty &= ~%s;' % dirtyflag
200 print ' } else {'
201 if array_name in ('INDEX', 'EDGE_FLAG', 'FOG_COORD'):
202 size = '1'
203 elif array_name == 'NORMAL':
204 size = '3'
205 else:
206 size = '__state.%s.size' % array_name.lower()
207 if array_name == 'EDGE_FLAG':
208 type = 'GL_BOOL'
209 else:
210 type = '__state.%s.type' % array_name.lower()
211 stride = '__state.%s.stride' % array_name.lower()
212 print ' Trace::LiteralBlob((const void *)%s, __glArrayPointer_size(%s, %s, %s, maxIndex));' % (value, size, type, stride)
213 print ' }'
214 print ' Trace::EndArg();'
José Fonseca669b1222011-02-20 09:05:10 +0000215 print ' Trace::EndEnter();'
216 print ' Trace::BeginLeave(__call);'
217 print ' Trace::EndLeave();'
218 print ' }'
219 print '}'
220 print
221
222
223
224
225
226
227