perf.c (5051B)
1 #include "perf.h" 2 #include <stdio.h> 3 #include <string.h> 4 #include <math.h> 5 #ifdef NANOVG_GLEW 6 # include <GL/glew.h> 7 #endif 8 #include <GLFW/glfw3.h> 9 #include "nanovg/nanovg.h" 10 11 #ifdef _MSC_VER 12 #define snprintf _snprintf 13 #elif !defined(__MINGW32__) 14 #include <iconv.h> 15 #endif 16 17 // timer query support 18 #ifndef GL_ARB_timer_query 19 #define GL_TIME_ELAPSED 0x88BF 20 //typedef void (APIENTRY *pfnGLGETQUERYOBJECTUI64V)(GLuint id, GLenum pname, GLuint64* params); 21 //pfnGLGETQUERYOBJECTUI64V glGetQueryObjectui64v = 0; 22 #endif 23 24 void initGPUTimer(GPUtimer* timer) 25 { 26 memset(timer, 0, sizeof(*timer)); 27 28 /* timer->supported = glfwExtensionSupported("GL_ARB_timer_query"); 29 if (timer->supported) { 30 #ifndef GL_ARB_timer_query 31 glGetQueryObjectui64v = (pfnGLGETQUERYOBJECTUI64V)glfwGetProcAddress("glGetQueryObjectui64v"); 32 printf("glGetQueryObjectui64v=%p\n", glGetQueryObjectui64v); 33 if (!glGetQueryObjectui64v) { 34 timer->supported = GL_FALSE; 35 return; 36 } 37 #endif 38 glGenQueries(GPU_QUERY_COUNT, timer->queries); 39 }*/ 40 } 41 42 43 void glBeginQuery(GLenum target, GLuint id); 44 45 void startGPUTimer(GPUtimer* timer) 46 { 47 if (!timer->supported) 48 return; 49 glBeginQuery(GL_TIME_ELAPSED, timer->queries[timer->cur % GPU_QUERY_COUNT] ); 50 timer->cur++; 51 } 52 53 54 void glEndQuery(GLenum target); 55 56 57 void glGetQueryObjectiv( GLuint id, 58 GLenum pname, 59 GLint * params); 60 61 int stopGPUTimer(GPUtimer* timer, float* times, int maxTimes) 62 { 63 NVG_NOTUSED(times); 64 NVG_NOTUSED(maxTimes); 65 GLint available = 1; 66 int n = 0; 67 if (!timer->supported) 68 return 0; 69 70 glEndQuery(GL_TIME_ELAPSED); 71 while (available && timer->ret <= timer->cur) { 72 // check for results if there are any 73 glGetQueryObjectiv(timer->queries[timer->ret % GPU_QUERY_COUNT], GL_QUERY_RESULT_AVAILABLE, &available); 74 if (available) { 75 /* GLuint64 timeElapsed = 0; 76 glGetQueryObjectui64v(timer->queries[timer->ret % GPU_QUERY_COUNT], GL_QUERY_RESULT, &timeElapsed); 77 timer->ret++; 78 if (n < maxTimes) { 79 times[n] = (float)((double)timeElapsed * 1e-9); 80 n++; 81 }*/ 82 } 83 } 84 return n; 85 } 86 87 88 void initGraph(PerfGraph* fps, int style, const char* name) 89 { 90 memset(fps, 0, sizeof(PerfGraph)); 91 fps->style = style; 92 strncpy(fps->name, name, sizeof(fps->name)); 93 fps->name[sizeof(fps->name)-1] = '\0'; 94 } 95 96 void updateGraph(PerfGraph* fps, float frameTime) 97 { 98 fps->head = (fps->head+1) % GRAPH_HISTORY_COUNT; 99 fps->values[fps->head] = frameTime; 100 } 101 102 float getGraphAverage(PerfGraph* fps) 103 { 104 int i; 105 float avg = 0; 106 for (i = 0; i < GRAPH_HISTORY_COUNT; i++) { 107 avg += fps->values[i]; 108 } 109 return avg / (float)GRAPH_HISTORY_COUNT; 110 } 111 112 void renderGraph(NVGcontext* vg, float x, float y, PerfGraph* fps) 113 { 114 int i; 115 float avg, w, h; 116 char str[64]; 117 118 avg = getGraphAverage(fps); 119 120 w = 200; 121 h = 35; 122 123 nvgBeginPath(vg); 124 nvgRect(vg, x,y, w,h); 125 nvgFillColor(vg, nvgRGBA(0,0,0,128)); 126 nvgFill(vg); 127 128 nvgBeginPath(vg); 129 nvgMoveTo(vg, x, y+h); 130 if (fps->style == GRAPH_RENDER_FPS) { 131 for (i = 0; i < GRAPH_HISTORY_COUNT; i++) { 132 float v = 1.0f / (0.00001f + fps->values[(fps->head+i) % GRAPH_HISTORY_COUNT]); 133 float vx, vy; 134 if (v > 80.0f) v = 80.0f; 135 vx = x + ((float)i/(GRAPH_HISTORY_COUNT-1)) * w; 136 vy = y + h - ((v / 80.0f) * h); 137 nvgLineTo(vg, vx, vy); 138 } 139 } else if (fps->style == GRAPH_RENDER_PERCENT) { 140 for (i = 0; i < GRAPH_HISTORY_COUNT; i++) { 141 float v = fps->values[(fps->head+i) % GRAPH_HISTORY_COUNT] * 1.0f; 142 float vx, vy; 143 if (v > 100.0f) v = 100.0f; 144 vx = x + ((float)i/(GRAPH_HISTORY_COUNT-1)) * w; 145 vy = y + h - ((v / 100.0f) * h); 146 nvgLineTo(vg, vx, vy); 147 } 148 } else { 149 for (i = 0; i < GRAPH_HISTORY_COUNT; i++) { 150 float v = fps->values[(fps->head+i) % GRAPH_HISTORY_COUNT] * 1000.0f; 151 float vx, vy; 152 if (v > 20.0f) v = 20.0f; 153 vx = x + ((float)i/(GRAPH_HISTORY_COUNT-1)) * w; 154 vy = y + h - ((v / 20.0f) * h); 155 nvgLineTo(vg, vx, vy); 156 } 157 } 158 nvgLineTo(vg, x+w, y+h); 159 nvgFillColor(vg, nvgRGBA(255,192,0,128)); 160 nvgFill(vg); 161 162 nvgFontFace(vg, "sans"); 163 164 if (fps->name[0] != '\0') { 165 nvgFontSize(vg, 14.0f); 166 nvgTextAlign(vg, NVG_ALIGN_LEFT|NVG_ALIGN_TOP); 167 nvgFillColor(vg, nvgRGBA(240,240,240,192)); 168 nvgText(vg, x+3,y+1, fps->name, NULL); 169 } 170 171 if (fps->style == GRAPH_RENDER_FPS) { 172 nvgFontSize(vg, 18.0f); 173 nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_TOP); 174 nvgFillColor(vg, nvgRGBA(240,240,240,255)); 175 sprintf(str, "%.2f FPS", 1.0f / avg); 176 nvgText(vg, x+w-3,y+1, str, NULL); 177 178 nvgFontSize(vg, 15.0f); 179 nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_BOTTOM); 180 nvgFillColor(vg, nvgRGBA(240,240,240,160)); 181 sprintf(str, "%.2f ms", avg * 1000.0f); 182 nvgText(vg, x+w-3,y+h-1, str, NULL); 183 } 184 else if (fps->style == GRAPH_RENDER_PERCENT) { 185 nvgFontSize(vg, 18.0f); 186 nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_TOP); 187 nvgFillColor(vg, nvgRGBA(240,240,240,255)); 188 sprintf(str, "%.1f %%", avg * 1.0f); 189 nvgText(vg, x+w-3,y+1, str, NULL); 190 } else { 191 nvgFontSize(vg, 18.0f); 192 nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_TOP); 193 nvgFillColor(vg, nvgRGBA(240,240,240,255)); 194 sprintf(str, "%.2f ms", avg * 1000.0f); 195 nvgText(vg, x+w-3,y+1, str, NULL); 196 } 197 }