]> git.tdb.fi Git - gldbg.git/blob - source/profiler.cpp
Add a performance profiler
[gldbg.git] / source / profiler.cpp
1 #include <msp/io/print.h>
2 #include <msp/time/units.h>
3 #include <msp/time/utils.h>
4 #include "profiler.h"
5
6 using namespace Msp;
7
8 Profiler::Profiler():
9         decoder(gldecoder_new(this, 0)),
10         enabled(false)
11 {
12         decoder->glDrawArrays = glDrawArrays;
13         decoder->glDrawElements = glDrawElements;
14         decoder->glDrawRangeElements = glDrawRangeElements;
15         decoder->glXSwapBuffers = glXSwapBuffers;
16 }
17
18 void Profiler::enable()
19 {
20         enabled = true;
21         frames = 0;
22         draw_calls = 0;
23         vertices = 0;
24         triangles = 0;
25         start = Msp::Time::now();
26 }
27
28 void Profiler::disable()
29 {
30         enabled = false;
31 }
32
33 int Profiler::decode(const char *data, unsigned len)
34 {
35         if(enabled)
36                 return gldecoder_decode(decoder, data, len);
37         else
38                 return 0;
39 }
40
41 void Profiler::glDrawArrays(void *user_data, GLenum mode, int, int count)
42 {
43         glDrawElements(user_data, mode, count, 0, 0);
44 }
45
46 void Profiler::glDrawElements(void *user_data, GLenum mode, int count, GLenum, const void *)
47 {
48         Profiler *self = reinterpret_cast<Profiler *>(user_data);
49
50         ++self->draw_calls;
51         self->vertices += count;
52
53         switch(mode)
54         {
55         case GL_TRIANGLES:
56                 self->triangles += count/3;
57                 break;
58         case GL_TRIANGLE_STRIP:
59         case GL_TRIANGLE_FAN:
60                 if(count>2)
61                         self->triangles += count-2;
62                 break;
63         case GL_QUADS:
64                 self->triangles += count/4;
65                 break;
66         case GL_QUAD_STRIP:
67                 if(count>3)
68                         self->triangles += count/2-1;
69                 break;
70         }
71 }
72
73 void Profiler::glDrawRangeElements(void *user_data, GLenum mode, unsigned, unsigned, int count, GLenum type, const void *data)
74 {
75         glDrawElements(user_data, mode, count, type, data);
76 }
77
78 void Profiler::glXSwapBuffers(void *user_data, Display *, GLXDrawable)
79 {
80         Profiler *self = reinterpret_cast<Profiler *>(user_data);
81
82         IO::print("%d draw calls, %d vertices, %d triangles\n", self->draw_calls, self->vertices, self->triangles);
83         self->draw_calls = 0;
84         self->vertices = 0;
85         self->triangles = 0;
86
87         ++self->frames;
88         Msp::Time::TimeStamp t = Msp::Time::now();
89         Msp::Time::TimeDelta dt = t-self->start;
90         if(dt>Msp::Time::sec)
91         {
92                 Msp::IO::print("%d frames in %s seconds\n", self->frames, dt);
93                 self->start = t;
94                 self->frames = 0;
95         }
96 }