]> git.tdb.fi Git - gldbg.git/blob - flavors/gl/source/profiler.cpp
Use a centralized packet framework
[gldbg.git] / flavors / gl / source / profiler.cpp
1 /* $Id$
2
3 This file is part of gldbg
4 Copyright © 2010  Mikko Rasa, Mikkosoft Productions
5 Distributed under the GPL
6 */
7
8 #include <msp/io/print.h>
9 #include <msp/time/units.h>
10 #include <msp/time/utils.h>
11 #include "gldbg.h"
12 #include "profiler.h"
13
14 using namespace std;
15 using namespace Msp;
16
17 Profiler::Profiler(GlDbg &dbg):
18         decoder(gldecoder_new(this, 0)),
19         enabled(false)
20 {
21         dbg.get_command_interpreter().register_command("profile", this, &Profiler::cmd_profile)
22                 .set_help("Profiles GL usage and performance",
23                         "profile {on|off}\n"
24                         "  Enables or disables profiling\n");
25
26         decoder->glDrawArrays = glDrawArrays;
27         decoder->glDrawElements = glDrawElements;
28         decoder->glDrawRangeElements = glDrawRangeElements;
29         decoder->glXSwapBuffers = glXSwapBuffers;
30 }
31
32 void Profiler::decode(const char *data, unsigned len)
33 {
34         if(enabled)
35                 gldecoder_decode(decoder, data, len);
36 }
37
38 void Profiler::cmd_profile(const string &args)
39 {
40         if(args.empty() || args=="on")
41         {
42                 enabled = true;
43                 frames = 0;
44                 draw_calls = 0;
45                 vertices = 0;
46                 triangles = 0;
47                 start = Msp::Time::now();
48         }
49         else if(args=="off")
50                 enabled = false;
51         else
52                 throw InvalidParameterValue("Invalid argument");
53 }
54
55 void Profiler::glDrawArrays(void *user_data, GLenum mode, int, int count)
56 {
57         glDrawElements(user_data, mode, count, 0, 0);
58 }
59
60 void Profiler::glDrawElements(void *user_data, GLenum mode, int count, GLenum, const void *)
61 {
62         Profiler *self = reinterpret_cast<Profiler *>(user_data);
63
64         ++self->draw_calls;
65         self->vertices += count;
66
67         switch(mode)
68         {
69         case GL_TRIANGLES:
70                 self->triangles += count/3;
71                 break;
72         case GL_TRIANGLE_STRIP:
73         case GL_TRIANGLE_FAN:
74                 if(count>2)
75                         self->triangles += count-2;
76                 break;
77         case GL_QUADS:
78                 self->triangles += count/4;
79                 break;
80         case GL_QUAD_STRIP:
81                 if(count>3)
82                         self->triangles += count/2-1;
83                 break;
84         }
85 }
86
87 void Profiler::glDrawRangeElements(void *user_data, GLenum mode, unsigned, unsigned, int count, GLenum type, const void *data)
88 {
89         glDrawElements(user_data, mode, count, type, data);
90 }
91
92 void Profiler::glXSwapBuffers(void *user_data, Display *, GLXDrawable)
93 {
94         Profiler *self = reinterpret_cast<Profiler *>(user_data);
95
96         IO::print("%d draw calls, %d vertices, %d triangles\n", self->draw_calls, self->vertices, self->triangles);
97         self->draw_calls = 0;
98         self->vertices = 0;
99         self->triangles = 0;
100
101         ++self->frames;
102         Msp::Time::TimeStamp t = Msp::Time::now();
103         Msp::Time::TimeDelta dt = t-self->start;
104         if(dt>Msp::Time::sec)
105         {
106                 Msp::IO::print("%d frames in %s seconds\n", self->frames, dt);
107                 self->start = t;
108                 self->frames = 0;
109         }
110 }