])
def call_function(self, function):
- if (function.name in self.draw_array_function_names or
- function.name in self.draw_elements_function_names):
+ if function.name in self.draw_elements_function_names:
print ' GLint __array_buffer = 0;'
print ' glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
print ' if (!__array_buffer) {'
pointer_function_names = set([
"glColorPointer",
- "glColorPointerEXT",
+ #"glColorPointerEXT",
"glEdgeFlagPointer",
- "glEdgeFlagPointerEXT",
+ #"glEdgeFlagPointerEXT",
"glFogCoordPointer",
- "glFogCoordPointerEXT",
+ #"glFogCoordPointerEXT",
"glIndexPointer",
- "glIndexPointerEXT",
- "glMatrixIndexPointerARB",
+ #"glIndexPointerEXT",
+ #"glMatrixIndexPointerARB",
"glNormalPointer",
- "glNormalPointerEXT",
+ #"glNormalPointerEXT",
"glSecondaryColorPointer",
- "glSecondaryColorPointerEXT",
+ #"glSecondaryColorPointerEXT",
"glTexCoordPointer",
- "glTexCoordPointerEXT",
- "glVertexAttribLPointer",
- "glVertexAttribPointer",
- "glVertexAttribPointerARB",
- "glVertexAttribPointerNV",
+ #"glTexCoordPointerEXT",
+ #"glVertexAttribLPointer",
+ #"glVertexAttribPointer",
+ #"glVertexAttribPointerARB",
+ #"glVertexAttribPointerNV",
"glVertexPointer",
- "glVertexPointerEXT",
+ #"glVertexPointerEXT",
])
def extract_arg(self, function, arg, arg_type, lvalue, rvalue):
- if (function.name in self.pointer_function_names and arg.name == 'pointer' or
- function.name in self.draw_elements_function_names and arg.name == 'indices'):
+ if function.name in self.pointer_function_names and arg.name == 'pointer':
+ print ' %s = dynamic_cast<void *>(&%s);' % (lvalue, rvalue)
+ return
+
+ if function.name in self.draw_elements_function_names and arg.name == 'indices':
print ' if (dynamic_cast<Trace::Null *>(&%s)) {' % rvalue
print ' %s = 0;' % (lvalue)
print ' } else {'
class GlTracer(Tracer):
+ def header(self, api):
+ Tracer.header(self, api)
+ self.state_tracker_decl(api)
+
+ def footer(self, api):
+ Tracer.footer(self, api)
+ self.state_tracker_impl(api)
+
+ array_names = {
+ "VERTEX": "glVertexPointer",
+ "NORMAL": "glNormalPointer",
+ "COLOR": "glColorPointer",
+ "INDEX": "glIndexPointer",
+ "TEX_COORD": "glTexCoordPointer",
+ "EDGE_FLAG": "glEdgeFlagPointer",
+ "FOG_COORD": "glFogCoordPointer",
+ "SECONDARY_COLOR": "glSecondaryColorPointer",
+ }
+
pointer_function_names = {
- "glVertexPointer": "VertexPointer",
- "glVertexPointerEXT": "VertexPointer",
- "glNormalPointer": "NormalPointer",
- "glNormalPointerEXT": "NormalPointer",
- "glColorPointer": "ColorPointer",
- "glColorPointerEXT": "ColorPointer",
- "glIndexPointer": "IndexPointer",
- "glIndexPointerEXT": "IndexPointer",
- "glTexCoordPointer": "TexCoordPointer",
- "glTexCoordPointerEXT": "TexCoordPointer",
- "glEdgeFlagPointer": "EdgeFlagPointer",
- "glEdgeFlagPointerEXT": "EdgeFlagPointer",
- "glFogCoordPointer": "FogCoordPointer",
- "glFogCoordPointerEXT": "FogCoordPointer",
- "glSecondaryColorPointer": "SecondaryColorPointer",
- "glSecondaryColorPointerEXT": "SecondaryColorPointer",
- "glInterleavedArrays": "InterleavedArrays",
+ "glVertexPointer": "VERTEX",
+ "glNormalPointer": "NORMAL",
+ "glColorPointer": "COLOR",
+ "glIndexPointer": "INDEX",
+ "glTexCoordPointer": "TEX_COORD",
+ "glEdgeFlagPointer": "EDGE_FLAG",
+ "glFogCoordPointer": "FOG_COORD",
+ "glSecondaryColorPointer": "SECONDARY_COLOR",
+ #"glInterleavedArrays": ("InterleavedArrays", None)
+ #"glVertexPointerEXT": "VERTEX",
+ #"glNormalPointerEXT": "NORMAL",
+ #"glColorPointerEXT": "COLOR",
+ #"glIndexPointerEXT": "INDEX",
+ #"glTexCoordPointerEXT": "TEX_COORD",
+ #"glEdgeFlagPointerEXT": "EDGE_FLAG",
+ #"glFogCoordPointerEXT": "FOG_COORD",
+ #"glSecondaryColorPointerEXT": "SECONDARY_COLOR",
#"glVertexAttribPointer": "VertexAttribPointer",
#"glVertexAttribPointerARB": "VertexAttribPointer",
#"glMatrixIndexPointerARB": "MatrixIndexPointer",
}
- def header(self, api):
- Tracer.header(self, api)
- self.state_tracker_decl(api)
-
- def footer(self, api):
- Tracer.footer(self, api)
- self.state_tracker_impl(api)
+ bind_buffer_enums = [
+ 'ARRAY_BUFFER',
+ 'ELEMENT_ARRAY_BUFFER',
+ 'PIXEL_PACK_BUFFER',
+ 'PIXEL_UNPACK_BUFFER',
+ ]
+
+ client_state_enums = [
+ 'COLOR_ARRAY',
+ 'EDGE_FLAG_ARRAY',
+ 'FOG_COORD_ARRAY',
+ 'INDEX_ARRAY',
+ 'NORMAL_ARRAY',
+ 'SECONDARY_COLOR_ARRAY',
+ 'TEXTURE_COORD_ARRAY',
+ 'VERTEX_ARRAY',
+ ]
def state_tracker_decl(self, api):
# A simple state tracker to track the pointer values
- atoms = list(set(self.pointer_function_names.itervalues()))
- atoms.sort()
-
# define the NEW_XXXX dirty flags
- for i in range(len(atoms)):
- atom = atoms[i]
- dirtyflag = "NEW_%s" % atom.upper()
- print '#define %s 0x%x' % (dirtyflag, 1 << i)
+ value = 1
+ for array_name in self.array_names.iterkeys():
+ dirtyflag = "NEW_%s" % array_name.upper()
+ print '#define %s 0x%x' % (dirtyflag, value)
+ value <<= 1
print
# declare the state structure
print 'struct {'
- for atom in atoms:
- function = api.get_function_by_name('gl%s' % atom)
+ for enum in self.bind_buffer_enums:
+ print ' GLuint %s;' % (enum.lower(),)
+ for enum in self.client_state_enums:
+ print ' GLboolean %s;' % (enum.lower(),)
+ for array_name, function_name in self.array_names.iteritems():
+ function = api.get_function_by_name(function_name)
print ' struct {'
for arg in function.args:
print ' %s %s;' % (arg.type, arg.name)
- print ' } %s;' % atom
+ print ' } %s;' % array_name.lower()
print ' unsigned dirty;'
print '} __state;'
print
+ print 'static void __state_update(GLsizei maxIndex);'
+ print
+
+ def trace_function_impl_body(self, function):
+ # Track bound VBOs
+ if function.name in ('glBindBuffer', 'glBindBufferARB'):
+ print ' switch(%s) {' % function.args[0].name
+ for enum in self.bind_buffer_enums:
+ print ' case GL_%s:' % enum
+ print ' __state.%s = %s;' % (enum.lower(), function.args[1].name)
+ print ' break;'
+ print ' }'
+
+ # Track enabled arrays
+ if function.name == 'glEnableClientState':
+ print ' switch(%s) {' % function.args[0].name
+ for enum in self.client_state_enums:
+ print ' case GL_%s:' % enum
+ print ' __state.%s = GL_TRUE;' % (enum.lower(),)
+ print ' break;'
+ print ' }'
+ if function.name == 'glDisableClientState':
+ print ' switch(%s) {' % function.args[0].name
+ for enum in self.client_state_enums:
+ print ' case GL_%s:' % enum
+ print ' __state.%s = GL_FALSE;' % (enum.lower(),)
+ print ' break;'
+ print ' }'
+
+ # Track array pointers
+ if function.name in self.pointer_function_names:
+ array_name = self.pointer_function_names[function.name]
+ dirtyflag = "NEW_%s" % array_name.upper()
+ for arg in function.args:
+ assert not arg.output
+ print ' __state.%s.%s = %s;' % (array_name.lower(), arg.name, arg.name)
+ print ' __state.dirty |= %s; ' % dirtyflag
+
+ # Defer tracing
+ self.dispatch_function(function)
+ return
+
+ if function.name == 'glDrawArrays':
+ print ' __state_update(first + count - 1);'
+
+ Tracer.trace_function_impl_body(self, function)
def state_tracker_impl(self, api):
# A simple state tracker to track the pointer values
- atoms = list(set(self.pointer_function_names.itervalues()))
- atoms.sort()
-
# update the state
- print 'void __state_update(GLsizei )'
+ print 'static void __state_update(GLsizei maxIndex)'
print '{'
print ' GLint __array_buffer = 0;'
- print ' glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
- for atom in atoms:
- function = api.get_function_by_name('gl%s' % atom)
- dirtyflag = "NEW_%s" % atom.upper()
- print ' if (__state.dirty & %s) {' % dirtyflag
+ print ' __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
+ for array_name, function_name in self.array_names.iteritems():
+ function = api.get_function_by_name(function_name)
+ dirtyflag = "NEW_%s" % array_name.upper()
+ if array_name == 'TEX_COORD':
+ enableflag = 'TEXTURE_COORD_ARRAY'.lower()
+ else:
+ enableflag = '%s_array' % array_name.lower()
+ print ' if (__state.%s && (__state.dirty & %s)) {' % (enableflag, dirtyflag)
print ' unsigned __call = Trace::BeginEnter(__%s_sig);' % (function.name,)
for arg in function.args:
assert not arg.output
+ value = '__state.%s.%s' % (array_name.lower(), arg.name)
print ' Trace::BeginArg(%u);' % (arg.index,)
- dump_instance(arg.type, '__state.%s.%s' % (atom, arg.name))
- print ' Trace::EndArg();'
+ if arg.name != 'pointer':
+ dump_instance(arg.type, value)
+ else:
+ print ' if (__state.array_buffer) {'
+ print ' Trace::LiteralOpaque((const void *)%s);' % value
+ print ' __state.dirty &= ~%s;' % dirtyflag
+ print ' } else {'
+ if array_name in ('INDEX', 'EDGE_FLAG', 'FOG_COORD'):
+ size = '1'
+ elif array_name == 'NORMAL':
+ size = '3'
+ else:
+ size = '__state.%s.size' % array_name.lower()
+ if array_name == 'EDGE_FLAG':
+ type = 'GL_BOOL'
+ else:
+ type = '__state.%s.type' % array_name.lower()
+ stride = '__state.%s.stride' % array_name.lower()
+ print ' Trace::LiteralBlob((const void *)%s, __glArrayPointer_size(%s, %s, %s, maxIndex));' % (value, size, type, stride)
+ print ' }'
+ print ' Trace::EndArg();'
print ' Trace::EndEnter();'
print ' Trace::BeginLeave(__call);'
print ' Trace::EndLeave();'
pass
def trace_function_decl(self, function):
+ # Per-function declarations
+
if function.args:
- print ' static const char * __%s_args[%u] = {%s};' % (function.name, len(function.args), ', '.join(['"%s"' % arg.name for arg in function.args]))
+ print 'static const char * __%s_args[%u] = {%s};' % (function.name, len(function.args), ', '.join(['"%s"' % arg.name for arg in function.args]))
else:
- print ' static const char ** __%s_args = NULL;' % (function.name,)
- print ' static const Trace::FunctionSig __%s_sig = {%u, "%s", %u, __%s_args};' % (function.name, int(function.id), function.name, len(function.args), function.name)
+ print 'static const char ** __%s_args = NULL;' % (function.name,)
+ print 'static const Trace::FunctionSig __%s_sig = {%u, "%s", %u, __%s_args};' % (function.name, int(function.id), function.name, len(function.args), function.name)
print
- def trace_function_fail(self, function):
- if function.fail is not None:
- if function.type is stdapi.Void:
- assert function.fail == ''
- print ' return;'
- else:
- assert function.fail != ''
- print ' return %s;' % function.fail
- else:
- print ' Trace::Abort();'
-
def get_dispatch_function(self, function):
return '__' + function.name
def trace_function_impl(self, function):
print 'extern "C" ' + function.prototype() + ' {'
- if function.type is stdapi.Void:
- result = ''
- else:
+ if function.type is not stdapi.Void:
print ' %s __result;' % function.type
- result = '__result = '
+ self.trace_function_impl_body(function)
+ if function.type is not stdapi.Void:
+ self.wrap_ret(function, "__result")
+ print ' return __result;'
+ print '}'
+ print
+
+ def trace_function_impl_body(self, function):
print ' unsigned __call = Trace::BeginEnter(__%s_sig);' % (function.name,)
for arg in function.args:
if not arg.output:
self.unwrap_arg(function, arg)
self.dump_arg(function, arg)
print ' Trace::EndEnter();'
- dispatch = self.get_dispatch_function(function)
- print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
+ self.dispatch_function(function)
print ' Trace::BeginLeave(__call);'
for arg in function.args:
if arg.output:
if function.type is not stdapi.Void:
self.dump_ret(function, "__result")
print ' Trace::EndLeave();'
- if function.type is not stdapi.Void:
- self.wrap_ret(function, "__result")
- print ' return __result;'
- print '}'
- print
+
+ def dispatch_function(self, function):
+ if function.type is stdapi.Void:
+ result = ''
+ else:
+ result = '__result = '
+ dispatch = self.get_dispatch_function(function)
+ print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
def dump_arg(self, function, arg):
print ' Trace::BeginArg(%u);' % (arg.index,)