You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

187 lines
4.8KB

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