X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=flavors%2Fgl%2Fsource%2Fprofiler.cpp;fp=flavors%2Fgl%2Fsource%2Fprofiler.cpp;h=37caa68636745f85c0f6290e006fef426618370c;hb=f53057ce9b5eb3c7256a4aca95b4944733e14503;hp=0000000000000000000000000000000000000000;hpb=73c55fc88d8bad336fbd6cfecedc0cf18d06167c;p=gldbg.git diff --git a/flavors/gl/source/profiler.cpp b/flavors/gl/source/profiler.cpp new file mode 100644 index 0000000..37caa68 --- /dev/null +++ b/flavors/gl/source/profiler.cpp @@ -0,0 +1,110 @@ +/* $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(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::decode(const char *data, unsigned len) +{ + if(enabled) + gldecoder_decode(decoder, data, len); +} + +void Profiler::cmd_profile(const string &args) +{ + 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 + throw InvalidParameterValue("Invalid argument"); +} + +void Profiler::glDrawArrays(void *user_data, GLenum mode, int, int count) +{ + glDrawElements(user_data, mode, count, 0, 0); +} + +void Profiler::glDrawElements(void *user_data, GLenum mode, int count, GLenum, const void *) +{ + Profiler *self = reinterpret_cast(user_data); + + ++self->draw_calls; + self->vertices += count; + + switch(mode) + { + case GL_TRIANGLES: + self->triangles += count/3; + break; + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: + if(count>2) + self->triangles += count-2; + break; + case GL_QUADS: + self->triangles += count/4; + break; + case GL_QUAD_STRIP: + if(count>3) + self->triangles += count/2-1; + break; + } +} + +void Profiler::glDrawRangeElements(void *user_data, GLenum mode, unsigned, unsigned, int count, GLenum type, const void *data) +{ + glDrawElements(user_data, mode, count, type, data); +} + +void Profiler::glXSwapBuffers(void *user_data, Display *, GLXDrawable) +{ + Profiler *self = reinterpret_cast(user_data); + + IO::print("%d draw calls, %d vertices, %d triangles\n", self->draw_calls, self->vertices, self->triangles); + self->draw_calls = 0; + self->vertices = 0; + self->triangles = 0; + + ++self->frames; + Msp::Time::TimeStamp t = Msp::Time::now(); + Msp::Time::TimeDelta dt = t-self->start; + if(dt>Msp::Time::sec) + { + Msp::IO::print("%d frames in %s seconds\n", self->frames, dt); + self->start = t; + self->frames = 0; + } +}