aboutsummaryrefslogtreecommitdiff
path: root/example/perf.c
diff options
context:
space:
mode:
Diffstat (limited to 'example/perf.c')
-rw-r--r--example/perf.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/example/perf.c b/example/perf.c
new file mode 100644
index 0000000..a74dc3c
--- /dev/null
+++ b/example/perf.c
@@ -0,0 +1,186 @@
+#include "perf.h"
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#ifdef NANOVG_GLEW
+# include <GL/glew.h>
+#endif
+#include <GLFW/glfw3.h>
+#include "nanovg.h"
+
+#ifdef _MSC_VER
+#define snprintf _snprintf
+#elif !defined(__MINGW32__)
+#include <iconv.h>
+#endif
+
+// timer query support
+#ifndef GL_ARB_timer_query
+#define GL_TIME_ELAPSED 0x88BF
+//typedef void (APIENTRY *pfnGLGETQUERYOBJECTUI64V)(GLuint id, GLenum pname, GLuint64* params);
+//pfnGLGETQUERYOBJECTUI64V glGetQueryObjectui64v = 0;
+#endif
+
+void initGPUTimer(GPUtimer* timer)
+{
+ memset(timer, 0, sizeof(*timer));
+
+/* timer->supported = glfwExtensionSupported("GL_ARB_timer_query");
+ if (timer->supported) {
+#ifndef GL_ARB_timer_query
+ glGetQueryObjectui64v = (pfnGLGETQUERYOBJECTUI64V)glfwGetProcAddress("glGetQueryObjectui64v");
+ printf("glGetQueryObjectui64v=%p\n", glGetQueryObjectui64v);
+ if (!glGetQueryObjectui64v) {
+ timer->supported = GL_FALSE;
+ return;
+ }
+#endif
+ glGenQueries(GPU_QUERY_COUNT, timer->queries);
+ }*/
+}
+
+void startGPUTimer(GPUtimer* timer)
+{
+ if (!timer->supported)
+ return;
+ glBeginQuery(GL_TIME_ELAPSED, timer->queries[timer->cur % GPU_QUERY_COUNT] );
+ timer->cur++;
+}
+
+int stopGPUTimer(GPUtimer* timer, float* times, int maxTimes)
+{
+ NVG_NOTUSED(times);
+ NVG_NOTUSED(maxTimes);
+ GLint available = 1;
+ int n = 0;
+ if (!timer->supported)
+ return 0;
+
+ glEndQuery(GL_TIME_ELAPSED);
+ while (available && timer->ret <= timer->cur) {
+ // check for results if there are any
+ glGetQueryObjectiv(timer->queries[timer->ret % GPU_QUERY_COUNT], GL_QUERY_RESULT_AVAILABLE, &available);
+ if (available) {
+/* GLuint64 timeElapsed = 0;
+ glGetQueryObjectui64v(timer->queries[timer->ret % GPU_QUERY_COUNT], GL_QUERY_RESULT, &timeElapsed);
+ timer->ret++;
+ if (n < maxTimes) {
+ times[n] = (float)((double)timeElapsed * 1e-9);
+ n++;
+ }*/
+ }
+ }
+ return n;
+}
+
+
+void initGraph(PerfGraph* fps, int style, const char* name)
+{
+ memset(fps, 0, sizeof(PerfGraph));
+ fps->style = style;
+ strncpy(fps->name, name, sizeof(fps->name));
+ fps->name[sizeof(fps->name)-1] = '\0';
+}
+
+void updateGraph(PerfGraph* fps, float frameTime)
+{
+ fps->head = (fps->head+1) % GRAPH_HISTORY_COUNT;
+ fps->values[fps->head] = frameTime;
+}
+
+float getGraphAverage(PerfGraph* fps)
+{
+ int i;
+ float avg = 0;
+ for (i = 0; i < GRAPH_HISTORY_COUNT; i++) {
+ avg += fps->values[i];
+ }
+ return avg / (float)GRAPH_HISTORY_COUNT;
+}
+
+void renderGraph(NVGcontext* vg, float x, float y, PerfGraph* fps)
+{
+ int i;
+ float avg, w, h;
+ char str[64];
+
+ avg = getGraphAverage(fps);
+
+ w = 200;
+ h = 35;
+
+ nvgBeginPath(vg);
+ nvgRect(vg, x,y, w,h);
+ nvgFillColor(vg, nvgRGBA(0,0,0,128));
+ nvgFill(vg);
+
+ nvgBeginPath(vg);
+ nvgMoveTo(vg, x, y+h);
+ if (fps->style == GRAPH_RENDER_FPS) {
+ for (i = 0; i < GRAPH_HISTORY_COUNT; i++) {
+ float v = 1.0f / (0.00001f + fps->values[(fps->head+i) % GRAPH_HISTORY_COUNT]);
+ float vx, vy;
+ if (v > 80.0f) v = 80.0f;
+ vx = x + ((float)i/(GRAPH_HISTORY_COUNT-1)) * w;
+ vy = y + h - ((v / 80.0f) * h);
+ nvgLineTo(vg, vx, vy);
+ }
+ } else if (fps->style == GRAPH_RENDER_PERCENT) {
+ for (i = 0; i < GRAPH_HISTORY_COUNT; i++) {
+ float v = fps->values[(fps->head+i) % GRAPH_HISTORY_COUNT] * 1.0f;
+ float vx, vy;
+ if (v > 100.0f) v = 100.0f;
+ vx = x + ((float)i/(GRAPH_HISTORY_COUNT-1)) * w;
+ vy = y + h - ((v / 100.0f) * h);
+ nvgLineTo(vg, vx, vy);
+ }
+ } else {
+ for (i = 0; i < GRAPH_HISTORY_COUNT; i++) {
+ float v = fps->values[(fps->head+i) % GRAPH_HISTORY_COUNT] * 1000.0f;
+ float vx, vy;
+ if (v > 20.0f) v = 20.0f;
+ vx = x + ((float)i/(GRAPH_HISTORY_COUNT-1)) * w;
+ vy = y + h - ((v / 20.0f) * h);
+ nvgLineTo(vg, vx, vy);
+ }
+ }
+ nvgLineTo(vg, x+w, y+h);
+ nvgFillColor(vg, nvgRGBA(255,192,0,128));
+ nvgFill(vg);
+
+ nvgFontFace(vg, "sans");
+
+ if (fps->name[0] != '\0') {
+ nvgFontSize(vg, 14.0f);
+ nvgTextAlign(vg, NVG_ALIGN_LEFT|NVG_ALIGN_TOP);
+ nvgFillColor(vg, nvgRGBA(240,240,240,192));
+ nvgText(vg, x+3,y+1, fps->name, NULL);
+ }
+
+ if (fps->style == GRAPH_RENDER_FPS) {
+ nvgFontSize(vg, 18.0f);
+ nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_TOP);
+ nvgFillColor(vg, nvgRGBA(240,240,240,255));
+ sprintf(str, "%.2f FPS", 1.0f / avg);
+ nvgText(vg, x+w-3,y+1, str, NULL);
+
+ nvgFontSize(vg, 15.0f);
+ nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_BOTTOM);
+ nvgFillColor(vg, nvgRGBA(240,240,240,160));
+ sprintf(str, "%.2f ms", avg * 1000.0f);
+ nvgText(vg, x+w-3,y+h-1, str, NULL);
+ }
+ else if (fps->style == GRAPH_RENDER_PERCENT) {
+ nvgFontSize(vg, 18.0f);
+ nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_TOP);
+ nvgFillColor(vg, nvgRGBA(240,240,240,255));
+ sprintf(str, "%.1f %%", avg * 1.0f);
+ nvgText(vg, x+w-3,y+1, str, NULL);
+ } else {
+ nvgFontSize(vg, 18.0f);
+ nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_TOP);
+ nvgFillColor(vg, nvgRGBA(240,240,240,255));
+ sprintf(str, "%.2f ms", avg * 1000.0f);
+ nvgText(vg, x+w-3,y+1, str, NULL);
+ }
+}