diff options
author | José Fonseca <jose.r.fonseca@gmail.com> | 2011-02-20 23:32:22 +0000 |
---|---|---|
committer | José Fonseca <jose.r.fonseca@gmail.com> | 2011-02-22 07:15:58 +0000 |
commit | 14c21bc57f0772c50850c4a91c0668cd4e6e45b6 (patch) | |
tree | f8d220e2fe4c77a8cc2bb6e1afc5d0266e670b86 /gltrace.py | |
parent | 669b2008e4244152c1c624ca190afaba1a0f2c9a (diff) |
Basic DrawArrays support.
Diffstat (limited to 'gltrace.py')
-rw-r--r-- | gltrace.py | 188 |
1 files changed, 143 insertions, 45 deletions
@@ -33,24 +33,43 @@ from trace import Tracer, dump_instance 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", @@ -60,60 +79,139 @@ class GlTracer(Tracer): #"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();' |