- Renamed FPScounter to PerfGraph - dump avg times at exitshared-context
@@ -50,7 +50,7 @@ int main() | |||||
GLFWwindow* window; | GLFWwindow* window; | ||||
struct DemoData data; | struct DemoData data; | ||||
struct NVGcontext* vg = NULL; | struct NVGcontext* vg = NULL; | ||||
struct FPScounter fps; | |||||
struct PerfGraph fps; | |||||
double prevt = 0; | double prevt = 0; | ||||
if (!glfwInit()) { | if (!glfwInit()) { | ||||
@@ -58,7 +58,7 @@ int main() | |||||
return -1; | return -1; | ||||
} | } | ||||
initFPS(&fps, FPS_RENDER_FPS, "Frame Time"); | |||||
initGraph(&fps, GRAPH_RENDER_FPS, "Frame Time"); | |||||
glfwSetErrorCallback(errorcb); | glfwSetErrorCallback(errorcb); | ||||
@@ -113,7 +113,7 @@ int main() | |||||
t = glfwGetTime(); | t = glfwGetTime(); | ||||
dt = t - prevt; | dt = t - prevt; | ||||
prevt = t; | prevt = t; | ||||
updateFPS(&fps, dt); | |||||
updateGraph(&fps, dt); | |||||
glfwGetCursorPos(window, &mx, &my); | glfwGetCursorPos(window, &mx, &my); | ||||
glfwGetWindowSize(window, &winWidth, &winHeight); | glfwGetWindowSize(window, &winWidth, &winHeight); | ||||
@@ -135,7 +135,7 @@ int main() | |||||
nvgBeginFrame(vg, winWidth, winHeight, pxRatio); | nvgBeginFrame(vg, winWidth, winHeight, pxRatio); | ||||
renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | ||||
renderFPS(vg, 5,5, &fps); | |||||
renderGraph(vg, 5,5, &fps); | |||||
nvgEndFrame(vg); | nvgEndFrame(vg); | ||||
@@ -55,7 +55,7 @@ int main() | |||||
struct DemoData data; | struct DemoData data; | ||||
struct NVGcontext* vg = NULL; | struct NVGcontext* vg = NULL; | ||||
struct GPUtimer gpuTimer; | struct GPUtimer gpuTimer; | ||||
struct FPScounter fps, cpuGraph, gpuGraph; | |||||
struct PerfGraph fps, cpuGraph, gpuGraph; | |||||
double prevt = 0, cpuTime = 0; | double prevt = 0, cpuTime = 0; | ||||
if (!glfwInit()) { | if (!glfwInit()) { | ||||
@@ -63,9 +63,9 @@ int main() | |||||
return -1; | return -1; | ||||
} | } | ||||
initFPS(&fps, FPS_RENDER_FPS, "Frame Time"); | |||||
initFPS(&cpuGraph, FPS_RENDER_MS, "CPU Time"); | |||||
initFPS(&gpuGraph, FPS_RENDER_MS, "GPU Time"); | |||||
initGraph(&fps, GRAPH_RENDER_FPS, "Frame Time"); | |||||
initGraph(&cpuGraph, GRAPH_RENDER_MS, "CPU Time"); | |||||
initGraph(&gpuGraph, GRAPH_RENDER_MS, "GPU Time"); | |||||
glfwSetErrorCallback(errorcb); | glfwSetErrorCallback(errorcb); | ||||
#ifndef _WIN32 // don't require this on win32, and works with more cards | #ifndef _WIN32 // don't require this on win32, and works with more cards | ||||
@@ -151,10 +151,10 @@ int main() | |||||
renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | ||||
renderFPS(vg, 5,5, &fps); | |||||
renderFPS(vg, 5+200+5,5, &cpuGraph); | |||||
renderGraph(vg, 5,5, &fps); | |||||
renderGraph(vg, 5+200+5,5, &cpuGraph); | |||||
if (gpuTimer.supported) | if (gpuTimer.supported) | ||||
renderFPS(vg, 5+200+5+200+5,5, &gpuGraph); | |||||
renderGraph(vg, 5+200+5+200+5,5, &gpuGraph); | |||||
nvgEndFrame(vg); | nvgEndFrame(vg); | ||||
@@ -163,13 +163,13 @@ int main() | |||||
// Measure the CPU time taken excluding swap buffers (as the swap may wait for GPU) | // Measure the CPU time taken excluding swap buffers (as the swap may wait for GPU) | ||||
cpuTime = glfwGetTime() - t; | cpuTime = glfwGetTime() - t; | ||||
updateFPS(&fps, dt); | |||||
updateFPS(&cpuGraph, cpuTime); | |||||
updateGraph(&fps, dt); | |||||
updateGraph(&cpuGraph, cpuTime); | |||||
// We may get multiple results. | // We may get multiple results. | ||||
n = stopGPUTimer(&gpuTimer, gpuTimes, 3); | n = stopGPUTimer(&gpuTimer, gpuTimes, 3); | ||||
for (i = 0; i < n; i++) | for (i = 0; i < n; i++) | ||||
updateFPS(&gpuGraph, gpuTimes[i]); | |||||
updateGraph(&gpuGraph, gpuTimes[i]); | |||||
glfwSwapBuffers(window); | glfwSwapBuffers(window); | ||||
glfwPollEvents(); | glfwPollEvents(); | ||||
@@ -179,6 +179,10 @@ int main() | |||||
nvgDeleteGL3(vg); | nvgDeleteGL3(vg); | ||||
printf("Average Frame Time: %.2f ms\n", getGraphAverage(&fps) * 1000.0f); | |||||
printf(" CPU Time: %.2f ms\n", getGraphAverage(&cpuGraph) * 1000.0f); | |||||
printf(" GPU Time: %.2f ms\n", getGraphAverage(&gpuGraph) * 1000.0f); | |||||
glfwTerminate(); | glfwTerminate(); | ||||
return 0; | return 0; | ||||
} | } |
@@ -48,7 +48,7 @@ int main() | |||||
GLFWwindow* window; | GLFWwindow* window; | ||||
struct DemoData data; | struct DemoData data; | ||||
struct NVGcontext* vg = NULL; | struct NVGcontext* vg = NULL; | ||||
struct FPScounter fps; | |||||
struct PerfGraph fps; | |||||
double prevt = 0; | double prevt = 0; | ||||
if (!glfwInit()) { | if (!glfwInit()) { | ||||
@@ -56,7 +56,7 @@ int main() | |||||
return -1; | return -1; | ||||
} | } | ||||
initFPS(&fps, FPS_RENDER_FPS, "Frame Time"); | |||||
initGraph(&fps, GRAPH_RENDER_FPS, "Frame Time"); | |||||
glfwSetErrorCallback(errorcb); | glfwSetErrorCallback(errorcb); | ||||
@@ -99,7 +99,7 @@ int main() | |||||
t = glfwGetTime(); | t = glfwGetTime(); | ||||
dt = t - prevt; | dt = t - prevt; | ||||
prevt = t; | prevt = t; | ||||
updateFPS(&fps, dt); | |||||
updateGraph(&fps, dt); | |||||
glfwGetCursorPos(window, &mx, &my); | glfwGetCursorPos(window, &mx, &my); | ||||
glfwGetWindowSize(window, &winWidth, &winHeight); | glfwGetWindowSize(window, &winWidth, &winHeight); | ||||
@@ -120,7 +120,7 @@ int main() | |||||
nvgBeginFrame(vg, winWidth, winHeight, pxRatio); | nvgBeginFrame(vg, winWidth, winHeight, pxRatio); | ||||
renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | ||||
renderFPS(vg, 5,5, &fps); | |||||
renderGraph(vg, 5,5, &fps); | |||||
nvgEndFrame(vg); | nvgEndFrame(vg); | ||||
@@ -48,7 +48,7 @@ int main() | |||||
GLFWwindow* window; | GLFWwindow* window; | ||||
struct DemoData data; | struct DemoData data; | ||||
struct NVGcontext* vg = NULL; | struct NVGcontext* vg = NULL; | ||||
struct FPScounter fps; | |||||
struct PerfGraph fps; | |||||
double prevt = 0; | double prevt = 0; | ||||
if (!glfwInit()) { | if (!glfwInit()) { | ||||
@@ -56,7 +56,7 @@ int main() | |||||
return -1; | return -1; | ||||
} | } | ||||
initFPS(&fps, FPS_RENDER_FPS, "Frame Time"); | |||||
initGraph(&fps, GRAPH_RENDER_FPS, "Frame Time"); | |||||
glfwSetErrorCallback(errorcb); | glfwSetErrorCallback(errorcb); | ||||
@@ -99,7 +99,7 @@ int main() | |||||
t = glfwGetTime(); | t = glfwGetTime(); | ||||
dt = t - prevt; | dt = t - prevt; | ||||
prevt = t; | prevt = t; | ||||
updateFPS(&fps, dt); | |||||
updateGraph(&fps, dt); | |||||
glfwGetCursorPos(window, &mx, &my); | glfwGetCursorPos(window, &mx, &my); | ||||
glfwGetWindowSize(window, &winWidth, &winHeight); | glfwGetWindowSize(window, &winWidth, &winHeight); | ||||
@@ -120,7 +120,7 @@ int main() | |||||
nvgBeginFrame(vg, winWidth, winHeight, pxRatio); | nvgBeginFrame(vg, winWidth, winHeight, pxRatio); | ||||
renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | ||||
renderFPS(vg, 5,5, &fps); | |||||
renderGraph(vg, 5,5, &fps); | |||||
nvgEndFrame(vg); | nvgEndFrame(vg); | ||||
@@ -71,40 +71,37 @@ int stopGPUTimer(struct GPUtimer* timer, float* times, int maxTimes) | |||||
} | } | ||||
void initFPS(struct FPScounter* fps, int style, const char* name) | |||||
void initGraph(struct PerfGraph* fps, int style, const char* name) | |||||
{ | { | ||||
memset(fps, 0, sizeof(struct FPScounter)); | |||||
memset(fps, 0, sizeof(struct PerfGraph)); | |||||
fps->style = style; | fps->style = style; | ||||
strncpy(fps->name, name, sizeof(fps->name)); | strncpy(fps->name, name, sizeof(fps->name)); | ||||
fps->name[sizeof(fps->name)-1] = '\0'; | fps->name[sizeof(fps->name)-1] = '\0'; | ||||
} | } | ||||
void updateFPS(struct FPScounter* fps, float frameTime) | |||||
void updateGraph(struct PerfGraph* fps, float frameTime) | |||||
{ | { | ||||
fps->head = (fps->head+1) % FPS_HISTORY_COUNT; | |||||
fps->head = (fps->head+1) % GRAPH_HISTORY_COUNT; | |||||
fps->values[fps->head] = frameTime; | fps->values[fps->head] = frameTime; | ||||
} | } | ||||
#define AVG_SIZE 20 | |||||
static float getAvg(struct FPScounter* fps) | |||||
float getGraphAverage(struct PerfGraph* fps) | |||||
{ | { | ||||
int i, head = fps->head; | |||||
int i; | |||||
float avg = 0; | float avg = 0; | ||||
for (i = 0; i < AVG_SIZE; i++) { | |||||
avg += fps->values[head]; | |||||
head = (head+FPS_HISTORY_COUNT-1) % FPS_HISTORY_COUNT; | |||||
for (i = 0; i < GRAPH_HISTORY_COUNT; i++) { | |||||
avg += fps->values[i]; | |||||
} | } | ||||
return avg / (float)AVG_SIZE; | |||||
return avg / (float)GRAPH_HISTORY_COUNT; | |||||
} | } | ||||
void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps) | |||||
void renderGraph(struct NVGcontext* vg, float x, float y, struct PerfGraph* fps) | |||||
{ | { | ||||
int i; | int i; | ||||
float avg, w, h; | float avg, w, h; | ||||
char str[64]; | char str[64]; | ||||
avg = getAvg(fps); | |||||
avg = getGraphAverage(fps); | |||||
w = 200; | w = 200; | ||||
h = 35; | h = 35; | ||||
@@ -116,19 +113,19 @@ void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps) | |||||
nvgBeginPath(vg); | nvgBeginPath(vg); | ||||
nvgMoveTo(vg, x, y+h); | nvgMoveTo(vg, x, y+h); | ||||
if (fps->style == FPS_RENDER_FPS) { | |||||
for (i = 0; i < FPS_HISTORY_COUNT; i++) { | |||||
float v = 1.0f / (0.00001f + fps->values[(fps->head+i) % FPS_HISTORY_COUNT]); | |||||
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]); | |||||
if (v > 80.0f) v = 80.0f; | if (v > 80.0f) v = 80.0f; | ||||
float vx = x + ((float)i/(FPS_HISTORY_COUNT-1)) * w; | |||||
float vx = x + ((float)i/(GRAPH_HISTORY_COUNT-1)) * w; | |||||
float vy = y + h - ((v / 80.0f) * h); | float vy = y + h - ((v / 80.0f) * h); | ||||
nvgLineTo(vg, vx, vy); | nvgLineTo(vg, vx, vy); | ||||
} | } | ||||
} else { | } else { | ||||
for (i = 0; i < FPS_HISTORY_COUNT; i++) { | |||||
float v = fps->values[(fps->head+i) % FPS_HISTORY_COUNT] * 1000.0f; | |||||
for (i = 0; i < GRAPH_HISTORY_COUNT; i++) { | |||||
float v = fps->values[(fps->head+i) % GRAPH_HISTORY_COUNT] * 1000.0f; | |||||
if (v > 20.0f) v = 20.0f; | if (v > 20.0f) v = 20.0f; | ||||
float vx = x + ((float)i/(FPS_HISTORY_COUNT-1)) * w; | |||||
float vx = x + ((float)i/(GRAPH_HISTORY_COUNT-1)) * w; | |||||
float vy = y + h - ((v / 20.0f) * h); | float vy = y + h - ((v / 20.0f) * h); | ||||
nvgLineTo(vg, vx, vy); | nvgLineTo(vg, vx, vy); | ||||
} | } | ||||
@@ -146,7 +143,7 @@ void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps) | |||||
nvgText(vg, x+3,y+1, fps->name, NULL); | nvgText(vg, x+3,y+1, fps->name, NULL); | ||||
} | } | ||||
if (fps->style == FPS_RENDER_FPS) { | |||||
if (fps->style == GRAPH_RENDER_FPS) { | |||||
nvgFontSize(vg, 18.0f); | nvgFontSize(vg, 18.0f); | ||||
nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_TOP); | nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_TOP); | ||||
nvgFillColor(vg, nvgRGBA(240,240,240,255)); | nvgFillColor(vg, nvgRGBA(240,240,240,255)); | ||||
@@ -7,22 +7,23 @@ | |||||
extern "C" { | extern "C" { | ||||
#endif | #endif | ||||
enum FPSrenderStyle { | |||||
FPS_RENDER_FPS, | |||||
FPS_RENDER_MS, | |||||
enum GraphrenderStyle { | |||||
GRAPH_RENDER_FPS, | |||||
GRAPH_RENDER_MS, | |||||
}; | }; | ||||
#define FPS_HISTORY_COUNT 100 | |||||
struct FPScounter { | |||||
#define GRAPH_HISTORY_COUNT 100 | |||||
struct PerfGraph { | |||||
int style; | int style; | ||||
char name[32]; | char name[32]; | ||||
float values[FPS_HISTORY_COUNT]; | |||||
float values[GRAPH_HISTORY_COUNT]; | |||||
int head; | int head; | ||||
}; | }; | ||||
void initFPS(struct FPScounter* fps, int style, const char* name); | |||||
void updateFPS(struct FPScounter* fps, float frameTime); | |||||
void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps); | |||||
void initGraph(struct PerfGraph* fps, int style, const char* name); | |||||
void updateGraph(struct PerfGraph* fps, float frameTime); | |||||
void renderGraph(struct NVGcontext* vg, float x, float y, struct PerfGraph* fps); | |||||
float getGraphAverage(struct PerfGraph* fps); | |||||
#define GPU_QUERY_COUNT 5 | #define GPU_QUERY_COUNT 5 | ||||
struct GPUtimer { | struct GPUtimer { | ||||