perf.c 5.0 KB

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