From a63854859e30c9e4d24a6bad468d8a1397e42cc3 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Tue, 18 Feb 2014 11:38:55 +0100 Subject: [PATCH 1/5] Added an inner frame CPU timer. Needs names for the UI components to distinguish them, and probably stacking vertically for easier comparison. --- example/demo.c | 61 ++++++++++++++++++++++++++++++------------- example/demo.h | 6 ++++- example/example_gl3.c | 10 ++++--- 3 files changed, 55 insertions(+), 22 deletions(-) diff --git a/example/demo.c b/example/demo.c index a98eccc..41f5882 100644 --- a/example/demo.c +++ b/example/demo.c @@ -862,7 +862,7 @@ void updateFPS(struct FPScounter* fps, float frameTime) #define AVG_SIZE 20 -void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps) +void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, enum FPSRenderStyle style) { int i, head; float avg, w, h; @@ -886,29 +886,54 @@ void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps) nvgBeginPath(vg); nvgMoveTo(vg, x, y+h); - for (i = 0; i < FPS_HISTORY_COUNT; i++) { - float v = 1.0f / (0.00001f + fps->values[(fps->head+i) % FPS_HISTORY_COUNT]); - if (v > 80.0f) v = 80.0f; - float vx = x + ((float)i/(FPS_HISTORY_COUNT-1)) * w; - float vy = y + h - ((v / 80.0f) * h); - nvgLineTo(vg, vx, vy); - } + if( RENDER_FPS == style ) + { + for (i = 0; i < FPS_HISTORY_COUNT; i++) { + float v = 1.0f / (0.00001f + fps->values[(fps->head+i) % FPS_HISTORY_COUNT]); + if (v > 80.0f) v = 80.0f; + float vx = x + ((float)i/(FPS_HISTORY_COUNT-1)) * w; + float vy = y + h - ((v / 80.0f) * h); + nvgLineTo(vg, vx, vy); + } + } + else + { + for (i = 0; i < FPS_HISTORY_COUNT; i++) { + float v = fps->values[(fps->head+i) % FPS_HISTORY_COUNT] * 1000.0f; + if (v > 20.0f) v = 20.0f; + float vx = x + ((float)i/(FPS_HISTORY_COUNT-1)) * w; + float 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"); - nvgFontSize(vg, 18.0f); - nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); - nvgFillColor(vg, nvgRGBA(240,240,240,255)); - sprintf(str, "%.2f FPS", 1.0f / avg); - nvgText(vg, x+w-5,y+h/2, str, NULL); + if( RENDER_FPS == style ) + { + nvgFontSize(vg, 18.0f); + nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); + nvgFillColor(vg, nvgRGBA(240,240,240,255)); + sprintf(str, "%.2f FPS", 1.0f / avg); + nvgText(vg, x+w-5,y+h/2, str, NULL); + + nvgFontSize(vg, 15.0f); + nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); + nvgFillColor(vg, nvgRGBA(240,240,240,160)); + sprintf(str, "%.2f ms", avg * 1000.0f); + nvgText(vg, x+5,y+h/2, str, NULL); + } + else + { + nvgFontSize(vg, 18.0f); + nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); + nvgFillColor(vg, nvgRGBA(240,240,240,255)); + sprintf(str, "%.2f ms", avg * 1000.0f); + nvgText(vg, x+w-5,y+h/2, str, NULL); + } - nvgFontSize(vg, 15.0f); - nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); - nvgFillColor(vg, nvgRGBA(240,240,240,160)); - sprintf(str, "%.2f ms", avg * 1000.0f); - nvgText(vg, x+5,y+h/2, str, NULL); } diff --git a/example/demo.h b/example/demo.h index 38a0a58..4689afd 100644 --- a/example/demo.h +++ b/example/demo.h @@ -17,6 +17,10 @@ void freeDemoData(struct NVGcontext* vg, struct DemoData* data); void renderDemo(struct NVGcontext* vg, float mx, float my, float width, float height, float t, int blowup, struct DemoData* data); #define FPS_HISTORY_COUNT 100 +enum FPSRenderStyle { + RENDER_FPS, + RENDER_MS, +}; struct FPScounter { float values[FPS_HISTORY_COUNT]; @@ -25,7 +29,7 @@ struct FPScounter void initFPS(struct FPScounter* fps); void updateFPS(struct FPScounter* fps, float frameTime); -void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps); +void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, enum FPSRenderStyle style ); #ifdef __cplusplus } diff --git a/example/example_gl3.c b/example/example_gl3.c index 460d10e..6b9d192 100644 --- a/example/example_gl3.c +++ b/example/example_gl3.c @@ -55,7 +55,8 @@ int main() struct DemoData data; struct NVGcontext* vg = NULL; struct FPScounter fps; - double prevt = 0; + struct FPScounter cpuTimes; + double prevt = 0, cpuTime = 0; if (!glfwInit()) { printf("Failed to init GLFW."); @@ -63,6 +64,7 @@ int main() } initFPS(&fps); + initFPS(&cpuTimes); glfwSetErrorCallback(errorcb); #ifndef _WIN32 // don't require this on win32, and works with more cards @@ -122,6 +124,7 @@ int main() dt = t - prevt; prevt = t; updateFPS(&fps, dt); + updateFPS(&cpuTimes, cpuTime); glfwGetCursorPos(window, &mx, &my); glfwGetWindowSize(window, &winWidth, &winHeight); @@ -142,12 +145,13 @@ int main() nvgBeginFrame(vg, winWidth, winHeight, pxRatio); renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); - renderFPS(vg, 5,5, &fps); + renderFPS(vg, 5,5, &fps, RENDER_FPS); + renderFPS(vg, 310,5, &cpuTimes, RENDER_MS); nvgEndFrame(vg); glEnable(GL_DEPTH_TEST); - + cpuTime = glfwGetTime() - t; glfwSwapBuffers(window); glfwPollEvents(); } From bb6b19c4100067d369a7bd984a78ec08fdb35db2 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Tue, 18 Feb 2014 12:26:41 +0100 Subject: [PATCH 2/5] Added GPU timer and fixed up formatting. --- example/demo.c | 42 ++++++++++++++++++++---------------------- example/example_gl3.c | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/example/demo.c b/example/demo.c index 41f5882..9c8b40e 100644 --- a/example/demo.c +++ b/example/demo.c @@ -911,28 +911,26 @@ void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, nvgFill(vg); nvgFontFace(vg, "sans"); - if( RENDER_FPS == style ) - { - nvgFontSize(vg, 18.0f); - nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); - nvgFillColor(vg, nvgRGBA(240,240,240,255)); - sprintf(str, "%.2f FPS", 1.0f / avg); - nvgText(vg, x+w-5,y+h/2, str, NULL); - - nvgFontSize(vg, 15.0f); - nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); - nvgFillColor(vg, nvgRGBA(240,240,240,160)); - sprintf(str, "%.2f ms", avg * 1000.0f); - nvgText(vg, x+5,y+h/2, str, NULL); - } - else - { - nvgFontSize(vg, 18.0f); - nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); - nvgFillColor(vg, nvgRGBA(240,240,240,255)); - sprintf(str, "%.2f ms", avg * 1000.0f); - nvgText(vg, x+w-5,y+h/2, str, NULL); - } + if( RENDER_FPS == style ) { + nvgFontSize(vg, 18.0f); + nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); + nvgFillColor(vg, nvgRGBA(240,240,240,255)); + sprintf(str, "%.2f FPS", 1.0f / avg); + nvgText(vg, x+w-5,y+h/2, str, NULL); + + nvgFontSize(vg, 15.0f); + nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); + nvgFillColor(vg, nvgRGBA(240,240,240,160)); + sprintf(str, "%.2f ms", avg * 1000.0f); + nvgText(vg, x+5,y+h/2, str, NULL); + } + else { + nvgFontSize(vg, 18.0f); + nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); + nvgFillColor(vg, nvgRGBA(240,240,240,255)); + sprintf(str, "%.2f ms", avg * 1000.0f); + nvgText(vg, x+w-5,y+h/2, str, NULL); + } } diff --git a/example/example_gl3.c b/example/example_gl3.c index 6b9d192..f1f69e4 100644 --- a/example/example_gl3.c +++ b/example/example_gl3.c @@ -31,7 +31,6 @@ #include "nanovg_gl3buf.h" #include "demo.h" - void errorcb(int error, const char* desc) { printf("GLFW error %d: %s\n", error, desc); @@ -49,14 +48,19 @@ static void key(GLFWwindow* window, int key, int scancode, int action, int mods) blowup = !blowup; } +enum numqueries { + NUM_QUERIES = 5 +}; + int main() { GLFWwindow* window; struct DemoData data; struct NVGcontext* vg = NULL; - struct FPScounter fps; - struct FPScounter cpuTimes; + struct FPScounter fps, cpuTimes, gpuTimes; double prevt = 0, cpuTime = 0; + int timerquery = GL_FALSE, currquery = 0, retquery = 0; + GLuint timerqueryid[NUM_QUERIES]; if (!glfwInit()) { printf("Failed to init GLFW."); @@ -65,6 +69,7 @@ int main() initFPS(&fps); initFPS(&cpuTimes); + initFPS(&gpuTimes); glfwSetErrorCallback(errorcb); #ifndef _WIN32 // don't require this on win32, and works with more cards @@ -110,6 +115,11 @@ int main() glfwSwapInterval(0); + timerquery = glfwExtensionSupported("GL_ARB_timer_query"); + if( timerquery ) { + glGenQueries(NUM_QUERIES, timerqueryid); + } + glfwSetTime(0); prevt = glfwGetTime(); @@ -125,6 +135,10 @@ int main() prevt = t; updateFPS(&fps, dt); updateFPS(&cpuTimes, cpuTime); + if( timerquery ) { + glBeginQuery(GL_TIME_ELAPSED, timerqueryid[currquery % NUM_QUERIES] ); + currquery = ++currquery; + } glfwGetCursorPos(window, &mx, &my); glfwGetWindowSize(window, &winWidth, &winHeight); @@ -147,11 +161,32 @@ int main() renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); renderFPS(vg, 5,5, &fps, RENDER_FPS); renderFPS(vg, 310,5, &cpuTimes, RENDER_MS); + renderFPS(vg, 615,5, &gpuTimes, RENDER_MS); nvgEndFrame(vg); glEnable(GL_DEPTH_TEST); + + // Measure the CPU time taken excluding swap buffers (as the swap may wait for GPU) cpuTime = glfwGetTime() - t; + + if( timerquery ) { + GLint available = 1; + glEndQuery(GL_TIME_ELAPSED); + while( available && retquery <= currquery ) { + // check for results if there are any + glGetQueryObjectiv(timerqueryid[retquery], GL_QUERY_RESULT_AVAILABLE, &available); + if( available ) { + GLuint64 timeElapsed = 0; + double gpuTime; + glGetQueryObjectui64v(timerqueryid[retquery % NUM_QUERIES], GL_QUERY_RESULT, &timeElapsed); + retquery = ++retquery ; + gpuTime = (double)timeElapsed * 1e-9; + updateFPS(&gpuTimes, (float)gpuTime); + } + } + + } glfwSwapBuffers(window); glfwPollEvents(); } From a1e99ea940198b63dd360e8fce8bd5adb44b7f6c Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Tue, 18 Feb 2014 13:32:55 +0100 Subject: [PATCH 3/5] Bug fix for index into queries. --- example/example_gl3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/example_gl3.c b/example/example_gl3.c index f1f69e4..a69679a 100644 --- a/example/example_gl3.c +++ b/example/example_gl3.c @@ -175,7 +175,7 @@ int main() glEndQuery(GL_TIME_ELAPSED); while( available && retquery <= currquery ) { // check for results if there are any - glGetQueryObjectiv(timerqueryid[retquery], GL_QUERY_RESULT_AVAILABLE, &available); + glGetQueryObjectiv(timerqueryid[retquery % NUM_QUERIES], GL_QUERY_RESULT_AVAILABLE, &available); if( available ) { GLuint64 timeElapsed = 0; double gpuTime; From e21683f14e84eb9a382bc2e8c2f7634fc27f97c6 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Tue, 18 Feb 2014 15:32:04 +0100 Subject: [PATCH 4/5] Added name to timer render. --- example/demo.c | 10 +++++++++- example/demo.h | 2 +- example/example_gl3.c | 6 +++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/example/demo.c b/example/demo.c index 9c8b40e..e952428 100644 --- a/example/demo.c +++ b/example/demo.c @@ -862,7 +862,7 @@ void updateFPS(struct FPScounter* fps, float frameTime) #define AVG_SIZE 20 -void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, enum FPSRenderStyle style) +void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, enum FPSRenderStyle style, const char* name) { int i, head; float avg, w, h; @@ -930,6 +930,14 @@ void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, nvgFillColor(vg, nvgRGBA(240,240,240,255)); sprintf(str, "%.2f ms", avg * 1000.0f); nvgText(vg, x+w-5,y+h/2, str, NULL); + + if( name ) + { + nvgFontSize(vg, 20.0f); + nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); + nvgFillColor(vg, nvgRGBA(240,240,240,160)); + nvgText(vg, x+5,y+h/2, name, NULL); + } } diff --git a/example/demo.h b/example/demo.h index 4689afd..271cc9f 100644 --- a/example/demo.h +++ b/example/demo.h @@ -29,7 +29,7 @@ struct FPScounter void initFPS(struct FPScounter* fps); void updateFPS(struct FPScounter* fps, float frameTime); -void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, enum FPSRenderStyle style ); +void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, enum FPSRenderStyle style, const char* name ); #ifdef __cplusplus } diff --git a/example/example_gl3.c b/example/example_gl3.c index a69679a..83a7411 100644 --- a/example/example_gl3.c +++ b/example/example_gl3.c @@ -159,9 +159,9 @@ int main() nvgBeginFrame(vg, winWidth, winHeight, pxRatio); renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); - renderFPS(vg, 5,5, &fps, RENDER_FPS); - renderFPS(vg, 310,5, &cpuTimes, RENDER_MS); - renderFPS(vg, 615,5, &gpuTimes, RENDER_MS); + renderFPS(vg, 5,5, &fps, RENDER_FPS, NULL ); + renderFPS(vg, 310,5, &cpuTimes, RENDER_MS, "CPU Time"); + renderFPS(vg, 615,5, &gpuTimes, RENDER_MS, "GPU Time"); nvgEndFrame(vg); From 7d6058c57267c681afec2b4216e325d9ee2d3239 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Tue, 18 Feb 2014 15:45:41 +0100 Subject: [PATCH 5/5] Changed name of new functionality to keep other examples compiling. --- example/demo.c | 7 ++++++- example/demo.h | 3 ++- example/example_gl3.c | 6 +++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/example/demo.c b/example/demo.c index e952428..145165c 100644 --- a/example/demo.c +++ b/example/demo.c @@ -862,7 +862,12 @@ void updateFPS(struct FPScounter* fps, float frameTime) #define AVG_SIZE 20 -void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, enum FPSRenderStyle style, const char* name) +void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps) +{ + renderFPSEx(vg,x,y,fps,RENDER_FPS,NULL); +} + +void renderFPSEx(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, enum FPSRenderStyle style, const char* name) { int i, head; float avg, w, h; diff --git a/example/demo.h b/example/demo.h index 271cc9f..0134e12 100644 --- a/example/demo.h +++ b/example/demo.h @@ -29,7 +29,8 @@ struct FPScounter void initFPS(struct FPScounter* fps); void updateFPS(struct FPScounter* fps, float frameTime); -void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, enum FPSRenderStyle style, const char* name ); +void renderFPSEx(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, enum FPSRenderStyle style, const char* name ); +void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps); #ifdef __cplusplus } diff --git a/example/example_gl3.c b/example/example_gl3.c index 83a7411..b0b4b73 100644 --- a/example/example_gl3.c +++ b/example/example_gl3.c @@ -159,9 +159,9 @@ int main() nvgBeginFrame(vg, winWidth, winHeight, pxRatio); renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); - renderFPS(vg, 5,5, &fps, RENDER_FPS, NULL ); - renderFPS(vg, 310,5, &cpuTimes, RENDER_MS, "CPU Time"); - renderFPS(vg, 615,5, &gpuTimes, RENDER_MS, "GPU Time"); + renderFPS(vg, 5,5, &fps); + renderFPSEx(vg, 310,5, &cpuTimes, RENDER_MS, "CPU Time"); + renderFPSEx(vg, 615,5, &gpuTimes, RENDER_MS, "GPU Time"); nvgEndFrame(vg);