]> git.tdb.fi Git - gldbg.git/commitdiff
Decouple the existing tools from the debugger core
authorMikko Rasa <tdb@tdb.fi>
Thu, 17 Jun 2010 08:54:12 +0000 (08:54 +0000)
committerMikko Rasa <tdb@tdb.fi>
Thu, 17 Jun 2010 08:54:12 +0000 (08:54 +0000)
16 files changed:
Makefile
flavors/gl/flavor.mk
flavors/gles2/flavor.mk
source/arraystate.h
source/bufferstate.h
source/commandinterpreter.cpp
source/commandinterpreter.h
source/gldbg.cpp
source/gldbg.h
source/inspector.cpp [new file with mode: 0644]
source/inspector.h [new file with mode: 0644]
source/profiler.cpp
source/profiler.h
source/texturestate.h
source/tracer.cpp
source/tracer.h

index 1adeb6440c91f6bf718b545dd8d3025d0d3893ee..af82389b32fc8ea45d37f7439743be8d0108f95d 100644 (file)
--- 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
index e326b8c2587f737ad4aa9f35e4fc153ab8bd6fb9..ae074f32c6c69686a179c056d302bc80f645807c 100644 (file)
@@ -1,3 +1,4 @@
 # $Id$
 
 APIS := $(FLAVOR_ROOT)/gl.api $(FLAVOR_ROOT)/glx.api
+TOOLS := tracer profiler inspector
index 3f9ac80ff6a8e84953d2f9ab0698897ec9c95389..d6ab2cb50f22297467759c14d39c85062ad33ea4 100644 (file)
@@ -2,3 +2,4 @@
 
 CPPFLAGS += -DAPIENTRY=
 APIS := $(FLAVOR_ROOT)/gles2.api $(FLAVOR_ROOT)/egl.api
+TOOLS := tracer
index 2a0f6d5cd0cd46dc4ed937ff34a8771735c6d1d9..d7552973238eab8f2878b8589795e2fc0672d0f2 100644 (file)
@@ -8,7 +8,7 @@ Distributed under the GPL
 #ifndef ARRAYSTATE_H_
 #define ARRAYSTATE_H_
 
-#include <GL/gl.h>
+#include "opengl.h"
 
 struct BufferState;
 
index 393168d72141a721afa3d8cc055dedc558c6b191..c3f504bf593ab5416bf95170a903424b69fbc5a7 100644 (file)
@@ -10,7 +10,7 @@ Distributed under the GPL
 
 #include <string>
 #include <vector>
-#include <GL/gl.h>
+#include "opengl.h"
 
 struct ArrayState;
 
index 367ac17f9651684e98113d472140cc1b23e4a4d2..2a28f69acd6e06a2dc8c523ef2e58a388a62124d 100644 (file)
@@ -8,7 +8,6 @@ Distributed under the GPL
 #include <signal.h>
 #include <readline/readline.h>
 #include <msp/core/except.h>
-#include <msp/io/file.h>
 #include <msp/io/print.h>
 #include <msp/strings/lexicalcast.h>
 #include <msp/strings/utils.h>
@@ -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<unsigned, TextureState> &textures = gldbg.get_glstate().get_textures();
-               IO::print("%d texture objects:\n", textures.size());
-               for(map<unsigned, TextureState>::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<unsigned>(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; i<tex.images.size(); ++i)
-               {
-                       const TexImageState &img = tex.images[i];
-                       IO::print("    Level %2d:      %s\n", i, img.describe());
-               }
-               IO::print("  Min. filter:     %s\n", describe_enum(tex.min_filter, "TextureMinFilter"));
-               IO::print("  Mag. filter:     %s\n", describe_enum(tex.mag_filter, "TextureMagFilter"));
-               IO::print("  Wrap modes:      S=%s / T=%s / R=%s\n", describe_enum(tex.wrap_s, "TextureWrapMode"),
-                       describe_enum(tex.wrap_t, "TextureWrapMode"), describe_enum(tex.wrap_r, "TextureWrapMode"));
-               IO::print("  Compare mode:    %s\n", describe_enum(tex.compare_mode, ""));
-               IO::print("  Compare func:    %s\n", describe_enum(tex.compare_func, "DepthFunction"));
-               IO::print("  Generate mipmap: %s\n", tex.generate_mipmap);
-       }
-}
-
-void CommandInterpreter::cmd_buffer(const string &args)
-{
-       if(args.empty())
-       {
-               const GlState::BufferMap &buffers = gldbg.get_glstate().get_buffers();
-               IO::print("%d buffers:\n", buffers.size());
-               for(GlState::BufferMap::const_iterator i=buffers.begin(); i!=buffers.end(); ++i)
-                       IO::print("  %d: %s\n", i->first, i->second.describe());
-       }
-       else
-       {
-               unsigned id = lexical_cast<unsigned>(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<BufferContent::Array> &arrays = buf.content.arrays;
-                       for(vector<BufferContent::Array>::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<BufferContent::Array>::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<n_verts; ++i)
-                       {
-                               const char *vertex = buf.data+i*buf.content.stride;
-
-                               string line;
-                               for(vector<BufferContent::Array>::const_iterator j=arrays.begin(); j!=arrays.end(); ++j)
-                               {
-                                       if(!line.empty())
-                                               line += " |";
-
-                                       const char *base = vertex+j->offset;
-                                       for(unsigned k=0; k<j->size; ++k)
-                                       {
-                                               if(j->type==GL_FLOAT)
-                                                       line += format(" %5.2f", *(reinterpret_cast<const float *>(base)+k));
-                                               else if(j->type==GL_UNSIGNED_BYTE)
-                                                       line += format(" %3u", *(reinterpret_cast<const unsigned char *>(base)+k));
-                                       }
-                               }
-
-                               IO::print("%3d:%s\n", i, line);
-                       }
-               }
-       }
-}
-
 
 void CommandInterpreter::Command::set_help(const string &d)
 {
index 487abb232fcdfcd6e4cb79cc56214db0720b19cb..63245227844d0351c41959d26022d225787cb138 100644 (file)
@@ -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
index bc621ce490e2679c91e30e6ca11348616559011d..7990fabae61f6f9ed4b1daef344b5715ded4004f 100644 (file)
@@ -16,7 +16,7 @@ Distributed under the GPL
 #include <msp/io/print.h>
 #include <msp/strings/lexicalcast.h>
 #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<Tool *>::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<Tool *>::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)
index 543df05a580265b5d88e395f995ffb2b2a0f0438..d8b56f825e2c92b0135f16e4bfd2b3db0f67fca7 100644 (file)
@@ -13,10 +13,7 @@ Distributed under the GPL
 #include <msp/core/application.h>
 #include <msp/fs/path.h>
 #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<Tool *> tools;
-       Tracer tracer;
-       GlState glstate;
-       Profiler profiler;
        bool got_sigchld;
 
        static RegApp<GlDbg> 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 (file)
index 0000000..912214d
--- /dev/null
@@ -0,0 +1,216 @@
+/* $Id$
+
+This file is part of gldbg
+Copyright © 2010  Mikko Rasa, Mikkosoft Productions
+Distributed under the GPL
+*/
+
+#include <msp/io/print.h>
+#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<unsigned, TextureState> &textures = state.get_textures();
+               IO::print("%d texture objects:\n", textures.size());
+               for(map<unsigned, TextureState>::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<unsigned>(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; i<tex.images.size(); ++i)
+               {
+                       const TexImageState &img = tex.images[i];
+                       IO::print("    Level %2d:      %s\n", i, img.describe());
+               }
+               IO::print("  Min. filter:     %s\n", describe_enum(tex.min_filter, "TextureMinFilter"));
+               IO::print("  Mag. filter:     %s\n", describe_enum(tex.mag_filter, "TextureMagFilter"));
+               IO::print("  Wrap modes:      S=%s / T=%s / R=%s\n", describe_enum(tex.wrap_s, "TextureWrapMode"),
+                       describe_enum(tex.wrap_t, "TextureWrapMode"), describe_enum(tex.wrap_r, "TextureWrapMode"));
+               IO::print("  Compare mode:    %s\n", describe_enum(tex.compare_mode, ""));
+               IO::print("  Compare func:    %s\n", describe_enum(tex.compare_func, "DepthFunction"));
+               IO::print("  Generate mipmap: %s\n", tex.generate_mipmap);
+       }
+}
+
+void Inspector::cmd_buffer(const string &args)
+{
+       if(args.empty())
+       {
+               const GlState::BufferMap &buffers = state.get_buffers();
+               IO::print("%d buffers:\n", buffers.size());
+               for(GlState::BufferMap::const_iterator i=buffers.begin(); i!=buffers.end(); ++i)
+                       IO::print("  %d: %s\n", i->first, i->second.describe());
+       }
+       else
+       {
+               unsigned id = lexical_cast<unsigned>(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<BufferContent::Array> &arrays = buf.content.arrays;
+                       for(vector<BufferContent::Array>::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<BufferContent::Array>::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<n_verts; ++i)
+                       {
+                               const char *vertex = buf.data+i*buf.content.stride;
+
+                               string line;
+                               for(vector<BufferContent::Array>::const_iterator j=arrays.begin(); j!=arrays.end(); ++j)
+                               {
+                                       if(!line.empty())
+                                               line += " |";
+
+                                       const char *base = vertex+j->offset;
+                                       for(unsigned k=0; k<j->size; ++k)
+                                       {
+                                               if(j->type==GL_FLOAT)
+                                                       line += format(" %5.2f", *(reinterpret_cast<const float *>(base)+k));
+                                               else if(j->type==GL_UNSIGNED_BYTE)
+                                                       line += format(" %3u", *(reinterpret_cast<const unsigned char *>(base)+k));
+                                       }
+                               }
+
+                               IO::print("%3d:%s\n", i, line);
+                       }
+               }
+       }
+}
diff --git a/source/inspector.h b/source/inspector.h
new file mode 100644 (file)
index 0000000..91e2a46
--- /dev/null
@@ -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<Inspector>
+{
+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
index ec9138de8794936672e00866dd8dccc0e9329ec2..37caa68636745f85c0f6290e006fef426618370c 100644 (file)
@@ -1,41 +1,55 @@
+/* $Id$
+
+This file is part of gldbg
+Copyright © 2010  Mikko Rasa, Mikkosoft Productions
+Distributed under the GPL
+*/
+
 #include <msp/io/print.h>
 #include <msp/time/units.h>
 #include <msp/time/utils.h>
+#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)
index fa6bcac65c1ddce7b397f87e0fa38af13bc228a4..4d5c5a834641300fe247730ca94dd3f1c3f7a79d 100644 (file)
@@ -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 <msp/time/timestamp.h>
 #include "gldecoder.h"
+#include "tool.h"
 
-class Profiler
+class Profiler: public RegisteredTool<Profiler>
 {
 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 *);
index 13f56744a43e9c4003dec444295ecd10d632601c..37cbfdda1ebd2464462e38fd983617f526d76b6f 100644 (file)
@@ -10,7 +10,7 @@ Distributed under the GPL
 
 #include <string>
 #include <vector>
-#include <GL/gl.h>
+#include "opengl.h"
 #include "autoconstptr.h"
 
 struct TexImageState
index d92da29b92c84cf3e08bcc5c1e4e1b610df75284..8aa12de25fd629b362c4b4eaaae3af4e3708ac85 100644 (file)
@@ -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 <msp/io/file.h>
 #include <msp/io/print.h>
+#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);
+       }
 }
index 51adb39a09f292f7ef4515559551961fd8afb2c7..651bfc1ecf1df7006d7f88170cd7a24bb129c993 100644 (file)
@@ -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 <msp/io/base.h>
+#include "tool.h"
 
 struct GlPrint;
 
-class Tracer
+class Tracer: public RegisteredTool<Tracer>
 {
 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