From: Mikko Rasa Date: Thu, 17 Jun 2010 08:54:12 +0000 (+0000) Subject: Decouple the existing tools from the debugger core X-Git-Url: http://git.tdb.fi/?p=gldbg.git;a=commitdiff_plain;h=7bd7fc784a6f6cff69f79914a445bc2115a7e768 Decouple the existing tools from the debugger core --- diff --git a/Makefile b/Makefile index 1adeb64..af82389 100644 --- a/Makefile +++ b/Makefile @@ -24,14 +24,15 @@ SOURCES_glwrap := source/glwrap.c \ SOURCES_gldump := source/gldump.c SOURCES_gldbg := source/gldbg.cpp \ source/commandinterpreter.cpp \ - source/tracer.cpp \ source/process.cpp \ + source/tool.cpp +SOURCES_tracer := source/tracer.cpp +SOURCES_profiler := source/profiler.cpp +SOURCES_inspector := source/inspector.cpp \ source/glstate.cpp \ - source/texturestate.cpp \ - source/bufferstate.cpp \ - source/profiler.cpp \ source/arraystate.cpp \ - source/tool.cpp + source/texturestate.cpp \ + source/bufferstate.cpp TEMPLATES := source/functions.enum.t \ source/gldecoder.funcs.t \ source/gldecoder.struct.t \ @@ -44,6 +45,12 @@ objs = $(call rename,temp,.o,$(1)) deps = $(call rename,temp,.d,$(1)) gen = $(call rename,gensrc,,$(1)) +.PHONY: all +all: glwrap.so gldump gldbg + +include flavors/$(FLAVOR)/flavor.mk + +SOURCES_gldbg += $(foreach tool,$(TOOLS),$(SOURCES_$(tool))) GENSOURCES := $(call gen,$(TEMPLATES)) SOURCES_all := $(sort $(SOURCES_libgldbg) $(SOURCES_glwrap) $(SOURCES_gldump) $(SOURCES_gldbg)) @@ -55,11 +62,6 @@ OBJECTS_gldbg := $(call objs,$(SOURCES_gldbg)) OBJECTS_all := $(call objs,$(SOURCES_all)) DEPS_all := $(call deps,$(SOURCES_all) $(TEMPLATES)) -.PHONY: all -all: glwrap.so gldump gldbg - -include flavors/$(FLAVOR)/flavor.mk - $(OBJECTS_gldbg): CXXFLAGS += $(shell pkg-config --cflags $(PACKAGES_gldbg)) gldbg: LIBS += $(shell pkg-config --libs $(PACKAGES_gldbg)) -lreadline gldump gldbg: LIBS += ./libgldbg.a diff --git a/flavors/gl/flavor.mk b/flavors/gl/flavor.mk index e326b8c..ae074f3 100644 --- a/flavors/gl/flavor.mk +++ b/flavors/gl/flavor.mk @@ -1,3 +1,4 @@ # $Id$ APIS := $(FLAVOR_ROOT)/gl.api $(FLAVOR_ROOT)/glx.api +TOOLS := tracer profiler inspector diff --git a/flavors/gles2/flavor.mk b/flavors/gles2/flavor.mk index 3f9ac80..d6ab2cb 100644 --- a/flavors/gles2/flavor.mk +++ b/flavors/gles2/flavor.mk @@ -2,3 +2,4 @@ CPPFLAGS += -DAPIENTRY= APIS := $(FLAVOR_ROOT)/gles2.api $(FLAVOR_ROOT)/egl.api +TOOLS := tracer diff --git a/source/arraystate.h b/source/arraystate.h index 2a0f6d5..d755297 100644 --- a/source/arraystate.h +++ b/source/arraystate.h @@ -8,7 +8,7 @@ Distributed under the GPL #ifndef ARRAYSTATE_H_ #define ARRAYSTATE_H_ -#include +#include "opengl.h" struct BufferState; diff --git a/source/bufferstate.h b/source/bufferstate.h index 393168d..c3f504b 100644 --- a/source/bufferstate.h +++ b/source/bufferstate.h @@ -10,7 +10,7 @@ Distributed under the GPL #include #include -#include +#include "opengl.h" struct ArrayState; diff --git a/source/commandinterpreter.cpp b/source/commandinterpreter.cpp index 367ac17..2a28f69 100644 --- a/source/commandinterpreter.cpp +++ b/source/commandinterpreter.cpp @@ -8,7 +8,6 @@ Distributed under the GPL #include #include #include -#include #include #include #include @@ -47,42 +46,6 @@ CommandInterpreter::CommandInterpreter(GlDbg &d): " execution. Currently recognized signal names are HUP, INT, TERM, SEGV\n" " and TERM.\n"); - register_command("trace", this, &CommandInterpreter::cmd_trace) - .set_help("Traces GL function calls", - "trace\n" - " Send trace output to stdout.\n\n" - "trace FILE\n" - " Send trace output to FILE (- for stdout).\n\n" - "trace {off|on}\n" - " Temporarily suspend or resume trace without closing the file.\n\n" - "trace end\n" - " Terminate trace, closing the file.\n"); - - register_command("profile", this, &CommandInterpreter::cmd_profile) - .set_help("Profiles GL usage and performance", - "profile {on|off}\n" - " Enables or disables profiling\n"); - - register_command("state", this, &CommandInterpreter::cmd_state) - .set_help("Inspects general GL state", - "state vertex\n" - " Print current vertex attributes\n\n" - "state bind\n" - " Show current bindings\n"); - - register_command("texture", this, &CommandInterpreter::cmd_texture) - .set_help("Inspect texture state", - "texture\n" - " Lists texture objects\n\n" - "texture ID\n" - " Print information about a texture object\n"); - - register_command("buffer", this, &CommandInterpreter::cmd_buffer) - .set_help("Inspect buffer object state", - "buffer\n" - " Lists buffer objects\n\n" - "buffer ID\n" - " Print information about a buffer object\n"); } void CommandInterpreter::execute(const string &cmd) @@ -184,218 +147,6 @@ void CommandInterpreter::cmd_exit(const string &) gldbg.quit(false); } -void CommandInterpreter::cmd_trace(const string &args) -{ - Tracer &tracer = gldbg.get_tracer(); - if(args.empty() || args=="-") - { - tracer.set_output(IO::cout); - IO::print("Tracing to stdout\n"); - } - else if(args=="on") - { - tracer.enable(); - IO::print("Tracing enabled\n"); - } - else if(args=="off") - { - tracer.disable(); - IO::print("Tracing disabled\n"); - } - else if(args=="end") - { - tracer.set_output(0); - IO::print("Tracing terminated\n"); - } - else - { - tracer.set_output(new IO::File(args, IO::M_WRITE)); - IO::print("Tracing to %s\n", args); - } -} - -void CommandInterpreter::cmd_profile(const string &args) -{ - Profiler &profiler = gldbg.get_profiler(); - if(args.empty() || args=="on") - profiler.enable(); - else if(args=="off") - profiler.disable(); - else - throw InvalidParameterValue("Invalid argument"); -} - -void CommandInterpreter::cmd_state(const string &args) -{ - const GlState &glstate = gldbg.get_glstate(); - if(args=="vertex") - { - IO::print("Current vertex attributes:\n"); - const Vector4 &color = glstate.get_color(); - IO::print(" Color: [%05.3f, %05.3f, %05.3f, %05.3f]\n", color.r, color.g, color.b, color.a); - for(unsigned i=0; i<8; ++i) - { - const Vector4 &texcoord = glstate.get_texcoord(i); - IO::print(" TexCoord%d: [%05.3f, %05.3f, %05.3f, %05.3f]\n", i, texcoord.s, texcoord.t, texcoord.p, texcoord.q); - } - const Vector3 &normal = glstate.get_normal(); - IO::print(" Normal: [%05.3f, %05.3f, %05.3f]\n", normal.x, normal.y, normal.z); - } - else if(args=="bind") - { - IO::print("Current bindings:\n"); - for(unsigned i=0; i<8; ++i) - { - IO::print(" Texture unit %d:\n", i); - const TexUnitState &unit = glstate.get_texture_unit(i); - IO::print(" GL_TEXTURE_2D: %s\n", unit.describe_binding(GL_TEXTURE_2D)); - IO::print(" GL_TEXTURE_3D: %s\n", unit.describe_binding(GL_TEXTURE_3D)); - } - IO::print(" Buffers:\n"); - const BufferState *buf = glstate.get_current_buffer(GL_ARRAY_BUFFER); - IO::print(" GL_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0)); - buf = glstate.get_current_buffer(GL_ELEMENT_ARRAY_BUFFER); - IO::print(" GL_ELEMENT_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0)); - } - else - throw InvalidParameterValue("Invalid or missing argument"); -} - -void CommandInterpreter::cmd_texture(const string &args) -{ - if(args.empty()) - { - const map &textures = gldbg.get_glstate().get_textures(); - IO::print("%d texture objects:\n", textures.size()); - for(map::const_iterator i = textures.begin(); i!=textures.end(); ++i) - { - const TextureState &tex = i->second; - IO::print(" %d: %s, %d images\n", i->first, tex.describe(), tex.images.size()); - } - } - else - { - unsigned id = lexical_cast(args); - const TextureState &tex = gldbg.get_glstate().get_texture(id); - IO::print("Texture object %d\n", id); - IO::print(" Target: %s\n", describe_enum(tex.target, "TextureTarget")); - IO::print(" Images:\n"); - for(unsigned i=0; ifirst, i->second.describe()); - } - else - { - unsigned id = lexical_cast(args); - const BufferState &buf = gldbg.get_glstate().get_buffer(id); - IO::print("Buffer %d:\n", id); - IO::print(" Size: %d bytes\n", buf.size); - IO::print(" Usage: %s\n", describe_enum(buf.usage, "")); - if(buf.content.stride) - { - IO::print(" Stride: %d bytes\n", buf.content.stride); - - IO::print(" Arrays:\n"); - const vector &arrays = buf.content.arrays; - for(vector::const_iterator i=arrays.begin(); i!=arrays.end(); ++i) - { - if(i->kind) - IO::print(" %2d: %s, %d %s\n", i->offset, - describe_enum(i->kind, ""), i->size, describe_enum(i->type, "DataType")); - else - IO::print(" %2d: Attrib %d, %d %s\n", i->offset, - i->index, i->size, describe_enum(i->type, "DataType")); - } - - IO::print(" Data:\n"); - string header; - for(vector::const_iterator i=arrays.begin(); i!=arrays.end(); ++i) - { - if(!header.empty()) - header += " | "; - - string label; - if(i->kind==GL_VERTEX_ARRAY) - label = "Vertex"; - else if(i->kind==GL_NORMAL_ARRAY) - label = "Normal"; - else if(i->kind==GL_COLOR_ARRAY) - label = "Color"; - else if(i->kind==GL_TEXTURE_COORD_ARRAY) - { - if(i->size==1) - label = "TexC"; - else - label = "TexCoord"; - } - else if(!i->kind) - { - if(i->size==1) - label = format("A %d", i->index); - else - label = format("Attrib %d", i->index); - } - - unsigned width = i->size; - if(i->type==GL_FLOAT) - width *= 5; - else if(i->type==GL_UNSIGNED_BYTE) - width *= 3; - width += i->size-1; - - header.append((width-label.size())/2, ' '); - header += label; - header.append((width-label.size()+1)/2, ' '); - } - IO::print(" %s\n", header); - - unsigned n_verts = buf.size/buf.content.stride; - for(unsigned i=0; i::const_iterator j=arrays.begin(); j!=arrays.end(); ++j) - { - if(!line.empty()) - line += " |"; - - const char *base = vertex+j->offset; - for(unsigned k=0; ksize; ++k) - { - if(j->type==GL_FLOAT) - line += format(" %5.2f", *(reinterpret_cast(base)+k)); - else if(j->type==GL_UNSIGNED_BYTE) - line += format(" %3u", *(reinterpret_cast(base)+k)); - } - } - - IO::print("%3d:%s\n", i, line); - } - } - } -} - void CommandInterpreter::Command::set_help(const string &d) { diff --git a/source/commandinterpreter.h b/source/commandinterpreter.h index 487abb2..6324522 100644 --- a/source/commandinterpreter.h +++ b/source/commandinterpreter.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of gldbg -Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions Distributed under the GPL */ @@ -84,11 +84,6 @@ private: void cmd_signal(const std::string &); void cmd_kill(const std::string &); void cmd_exit(const std::string &); - void cmd_trace(const std::string &); - void cmd_profile(const std::string &); - void cmd_state(const std::string &); - void cmd_texture(const std::string &); - void cmd_buffer(const std::string &); }; #endif diff --git a/source/gldbg.cpp b/source/gldbg.cpp index bc621ce..7990fab 100644 --- a/source/gldbg.cpp +++ b/source/gldbg.cpp @@ -16,7 +16,7 @@ Distributed under the GPL #include #include #include "gldbg.h" -#include "glprint.h" +#include "gldecoder.h" #include "tool.h" using namespace std; @@ -39,6 +39,12 @@ GlDbg::GlDbg(int argc, char **argv): tools.push_back((*i)->create(*this)); } +GlDbg::~GlDbg() +{ + for(list::iterator i=tools.begin(); i!=tools.end(); ++i) + delete *i; +} + int GlDbg::main() { catch_signal(SIGINT); @@ -46,7 +52,7 @@ int GlDbg::main() set_loop_mode(TICK_BUSY); IO::print("GLdbg 0.0\n"); - IO::print("Copyright © 2009 Mikkosoft Productions\n"); + IO::print("Copyright © 2009-2010 Mikkosoft Productions\n"); IO::print("Type \"help\" for a list of commands\n"); Application::main(); @@ -140,9 +146,6 @@ void GlDbg::read_stream() break; for(list::iterator i=tools.begin(); i!=tools.end(); ++i) (*i)->decode(data, size); - tracer.decode(data, len); - glstate.decode(data, len); - profiler.decode(data, len); buf_offset += size; } if(buf_offset>8192) diff --git a/source/gldbg.h b/source/gldbg.h index 543df05..d8b56f8 100644 --- a/source/gldbg.h +++ b/source/gldbg.h @@ -13,10 +13,7 @@ Distributed under the GPL #include #include #include "commandinterpreter.h" -#include "glstate.h" #include "process.h" -#include "profiler.h" -#include "tracer.h" class Tool; @@ -30,20 +27,16 @@ private: unsigned buf_offset; bool flushing; std::list tools; - Tracer tracer; - GlState glstate; - Profiler profiler; bool got_sigchld; static RegApp reg; public: GlDbg(int, char **); + ~GlDbg(); + int main(); CommandInterpreter &get_command_interpreter() { return cmd_interp; } - Tracer &get_tracer() { return tracer; } - GlState &get_glstate() { return glstate; } - Profiler &get_profiler() { return profiler; } Process &get_process() { return process; } void launch(); void quit(bool); diff --git a/source/inspector.cpp b/source/inspector.cpp new file mode 100644 index 0000000..912214d --- /dev/null +++ b/source/inspector.cpp @@ -0,0 +1,216 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#include +#include "enums.h" +#include "gldbg.h" +#include "inspector.h" + +using namespace std; +using namespace Msp; + +Inspector::Inspector(GlDbg &dbg) +{ + CommandInterpreter &cmd_interp = dbg.get_command_interpreter(); + + cmd_interp.register_command("state", this, &Inspector::cmd_state) + .set_help("Inspects general GL state", + "state vertex\n" + " Print current vertex attributes\n\n" + "state bind\n" + " Show current bindings\n"); + + cmd_interp.register_command("texture", this, &Inspector::cmd_texture) + .set_help("Inspect texture state", + "texture\n" + " Lists texture objects\n\n" + "texture ID\n" + " Print information about a texture object\n"); + + cmd_interp.register_command("buffer", this, &Inspector::cmd_buffer) + .set_help("Inspect buffer object state", + "buffer\n" + " Lists buffer objects\n\n" + "buffer ID\n" + " Print information about a buffer object\n"); +} + +void Inspector::decode(const char *data, unsigned len) +{ + state.decode(data, len); +} + +void Inspector::cmd_state(const string &args) +{ + const GlState &glstate = state; + if(args=="vertex") + { + IO::print("Current vertex attributes:\n"); + const Vector4 &color = glstate.get_color(); + IO::print(" Color: [%05.3f, %05.3f, %05.3f, %05.3f]\n", color.r, color.g, color.b, color.a); + for(unsigned i=0; i<8; ++i) + { + const Vector4 &texcoord = glstate.get_texcoord(i); + IO::print(" TexCoord%d: [%05.3f, %05.3f, %05.3f, %05.3f]\n", i, texcoord.s, texcoord.t, texcoord.p, texcoord.q); + } + const Vector3 &normal = glstate.get_normal(); + IO::print(" Normal: [%05.3f, %05.3f, %05.3f]\n", normal.x, normal.y, normal.z); + } + else if(args=="bind") + { + IO::print("Current bindings:\n"); + for(unsigned i=0; i<8; ++i) + { + IO::print(" Texture unit %d:\n", i); + const TexUnitState &unit = glstate.get_texture_unit(i); + IO::print(" GL_TEXTURE_2D: %s\n", unit.describe_binding(GL_TEXTURE_2D)); + IO::print(" GL_TEXTURE_3D: %s\n", unit.describe_binding(GL_TEXTURE_3D)); + } + IO::print(" Buffers:\n"); + const BufferState *buf = glstate.get_current_buffer(GL_ARRAY_BUFFER); + IO::print(" GL_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0)); + buf = glstate.get_current_buffer(GL_ELEMENT_ARRAY_BUFFER); + IO::print(" GL_ELEMENT_ARRAY_BUFFER: %d\n", (buf ? buf->id : 0)); + } + else + throw InvalidParameterValue("Invalid or missing argument"); +} + +void Inspector::cmd_texture(const string &args) +{ + if(args.empty()) + { + const map &textures = state.get_textures(); + IO::print("%d texture objects:\n", textures.size()); + for(map::const_iterator i = textures.begin(); i!=textures.end(); ++i) + { + const TextureState &tex = i->second; + IO::print(" %d: %s, %d images\n", i->first, tex.describe(), tex.images.size()); + } + } + else + { + unsigned id = lexical_cast(args); + const TextureState &tex = state.get_texture(id); + IO::print("Texture object %d\n", id); + IO::print(" Target: %s\n", describe_enum(tex.target, "TextureTarget")); + IO::print(" Images:\n"); + for(unsigned i=0; ifirst, i->second.describe()); + } + else + { + unsigned id = lexical_cast(args); + const BufferState &buf = state.get_buffer(id); + IO::print("Buffer %d:\n", id); + IO::print(" Size: %d bytes\n", buf.size); + IO::print(" Usage: %s\n", describe_enum(buf.usage, "")); + if(buf.content.stride) + { + IO::print(" Stride: %d bytes\n", buf.content.stride); + + IO::print(" Arrays:\n"); + const vector &arrays = buf.content.arrays; + for(vector::const_iterator i=arrays.begin(); i!=arrays.end(); ++i) + { + if(i->kind) + IO::print(" %2d: %s, %d %s\n", i->offset, + describe_enum(i->kind, ""), i->size, describe_enum(i->type, "DataType")); + else + IO::print(" %2d: Attrib %d, %d %s\n", i->offset, + i->index, i->size, describe_enum(i->type, "DataType")); + } + + IO::print(" Data:\n"); + string header; + for(vector::const_iterator i=arrays.begin(); i!=arrays.end(); ++i) + { + if(!header.empty()) + header += " | "; + + string label; + if(i->kind==GL_VERTEX_ARRAY) + label = "Vertex"; + else if(i->kind==GL_NORMAL_ARRAY) + label = "Normal"; + else if(i->kind==GL_COLOR_ARRAY) + label = "Color"; + else if(i->kind==GL_TEXTURE_COORD_ARRAY) + { + if(i->size==1) + label = "TexC"; + else + label = "TexCoord"; + } + else if(!i->kind) + { + if(i->size==1) + label = format("A %d", i->index); + else + label = format("Attrib %d", i->index); + } + + unsigned width = i->size; + if(i->type==GL_FLOAT) + width *= 5; + else if(i->type==GL_UNSIGNED_BYTE) + width *= 3; + width += i->size-1; + + header.append((width-label.size())/2, ' '); + header += label; + header.append((width-label.size()+1)/2, ' '); + } + IO::print(" %s\n", header); + + unsigned n_verts = buf.size/buf.content.stride; + for(unsigned i=0; i::const_iterator j=arrays.begin(); j!=arrays.end(); ++j) + { + if(!line.empty()) + line += " |"; + + const char *base = vertex+j->offset; + for(unsigned k=0; ksize; ++k) + { + if(j->type==GL_FLOAT) + line += format(" %5.2f", *(reinterpret_cast(base)+k)); + else if(j->type==GL_UNSIGNED_BYTE) + line += format(" %3u", *(reinterpret_cast(base)+k)); + } + } + + IO::print("%3d:%s\n", i, line); + } + } + } +} diff --git a/source/inspector.h b/source/inspector.h new file mode 100644 index 0000000..91e2a46 --- /dev/null +++ b/source/inspector.h @@ -0,0 +1,29 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#ifndef INSPECTOR_H_ +#define INSPECTOR_H_ + +#include "glstate.h" +#include "tool.h" + +class Inspector: public RegisteredTool +{ +private: + GlState state; + +public: + Inspector(GlDbg &); + + virtual void decode(const char *, unsigned); +private: + void cmd_state(const std::string &); + void cmd_texture(const std::string &); + void cmd_buffer(const std::string &); +}; + +#endif diff --git a/source/profiler.cpp b/source/profiler.cpp index ec9138d..37caa68 100644 --- a/source/profiler.cpp +++ b/source/profiler.cpp @@ -1,41 +1,55 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + #include #include #include +#include "gldbg.h" #include "profiler.h" +using namespace std; using namespace Msp; -Profiler::Profiler(): +Profiler::Profiler(GlDbg &dbg): decoder(gldecoder_new(this, 0)), enabled(false) { + dbg.get_command_interpreter().register_command("profile", this, &Profiler::cmd_profile) + .set_help("Profiles GL usage and performance", + "profile {on|off}\n" + " Enables or disables profiling\n"); + decoder->glDrawArrays = glDrawArrays; decoder->glDrawElements = glDrawElements; decoder->glDrawRangeElements = glDrawRangeElements; decoder->glXSwapBuffers = glXSwapBuffers; } -void Profiler::enable() -{ - enabled = true; - frames = 0; - draw_calls = 0; - vertices = 0; - triangles = 0; - start = Msp::Time::now(); -} - -void Profiler::disable() +void Profiler::decode(const char *data, unsigned len) { - enabled = false; + if(enabled) + gldecoder_decode(decoder, data, len); } -int Profiler::decode(const char *data, unsigned len) +void Profiler::cmd_profile(const string &args) { - if(enabled) - return gldecoder_decode(decoder, data, len); + if(args.empty() || args=="on") + { + enabled = true; + frames = 0; + draw_calls = 0; + vertices = 0; + triangles = 0; + start = Msp::Time::now(); + } + else if(args=="off") + enabled = false; else - return 0; + throw InvalidParameterValue("Invalid argument"); } void Profiler::glDrawArrays(void *user_data, GLenum mode, int, int count) diff --git a/source/profiler.h b/source/profiler.h index fa6bcac..4d5c5a8 100644 --- a/source/profiler.h +++ b/source/profiler.h @@ -1,10 +1,18 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2010 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + #ifndef PROFILER_H_ #define PROFILER_H_ #include #include "gldecoder.h" +#include "tool.h" -class Profiler +class Profiler: public RegisteredTool { private: GlDecoder *decoder; @@ -16,12 +24,12 @@ private: unsigned triangles; public: - Profiler(); + Profiler(GlDbg &); - void enable(); - void disable(); - int decode(const char *, unsigned); + virtual void decode(const char *, unsigned); private: + void cmd_profile(const std::string &); + static void glDrawArrays(void *, GLenum, int, int); static void glDrawElements(void *, GLenum, int, GLenum, const void *); static void glDrawRangeElements(void *, GLenum, unsigned, unsigned, int, GLenum, const void *); diff --git a/source/texturestate.h b/source/texturestate.h index 13f5674..37cbfdd 100644 --- a/source/texturestate.h +++ b/source/texturestate.h @@ -10,7 +10,7 @@ Distributed under the GPL #include #include -#include +#include "opengl.h" #include "autoconstptr.h" struct TexImageState diff --git a/source/tracer.cpp b/source/tracer.cpp index d92da29..8aa12de 100644 --- a/source/tracer.cpp +++ b/source/tracer.cpp @@ -1,22 +1,36 @@ /* $Id$ This file is part of gldbg -Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions Distributed under the GPL */ +#include #include +#include "gldbg.h" #include "glprint.h" #include "tracer.h" +using namespace std; using namespace Msp; -Tracer::Tracer(): +Tracer::Tracer(GlDbg &dbg): glprint(new GlPrint(0, 16384)), out(0), delete_out(true), enabled(true) -{ } +{ + dbg.get_command_interpreter().register_command("trace", this, &Tracer::cmd_trace) + .set_help("Traces GL function calls", + "trace\n" + " Send trace output to stdout.\n\n" + "trace FILE\n" + " Send trace output to FILE (- for stdout).\n\n" + "trace {off|on}\n" + " Temporarily suspend or resume trace without closing the file.\n\n" + "trace end\n" + " Terminate trace, closing the file.\n"); +} Tracer::~Tracer() { @@ -25,38 +39,51 @@ Tracer::~Tracer() delete out; } -void Tracer::set_output(IO::Base *o) +void Tracer::set_output(IO::Base *o, bool d) { if(delete_out) delete out; out = o; - delete_out = true; -} - -void Tracer::set_output(IO::Base &o) -{ - set_output(&o); - delete_out = false; -} - -void Tracer::enable() -{ - if(!out) - throw InvalidState("Output is not set"); - enabled = true; + delete_out = d; } -void Tracer::disable() -{ - enabled = false; -} - -int Tracer::decode(const char *data, unsigned len) +void Tracer::decode(const char *data, unsigned len) { if(!enabled || !out) - return 0; + return; + int ret = glprint->decode(data, len); if(ret>=0) IO::print(*out, "%s\n", glprint->get_buffer()); - return ret; +} + +void Tracer::cmd_trace(const string &args) +{ + if(args.empty() || args=="-") + { + set_output(&IO::cout, false); + IO::print("Tracing to stdout\n"); + } + else if(args=="on") + { + if(!out) + throw InvalidState("Output is not set"); + enabled = true; + IO::print("Tracing enabled\n"); + } + else if(args=="off") + { + enabled = false; + IO::print("Tracing disabled\n"); + } + else if(args=="end") + { + set_output(0, true); + IO::print("Tracing terminated\n"); + } + else + { + set_output(new IO::File(args, IO::M_WRITE), true); + IO::print("Tracing to %s\n", args); + } } diff --git a/source/tracer.h b/source/tracer.h index 51adb39..651bfc1 100644 --- a/source/tracer.h +++ b/source/tracer.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of gldbg -Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Copyright © 2009-2010 Mikko Rasa, Mikkosoft Productions Distributed under the GPL */ @@ -9,10 +9,11 @@ Distributed under the GPL #define TRACER_H_ #include +#include "tool.h" struct GlPrint; -class Tracer +class Tracer: public RegisteredTool { private: GlPrint *glprint; @@ -21,14 +22,13 @@ private: bool enabled; public: - Tracer(); + Tracer(GlDbg &); ~Tracer(); - void set_output(Msp::IO::Base *); - void set_output(Msp::IO::Base &); - void enable(); - void disable(); - int decode(const char *, unsigned); + virtual void decode(const char *, unsigned); +private: + void set_output(Msp::IO::Base *, bool); + void cmd_trace(const std::string &); }; #endif