DPF OpenGL examples
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.

251 lines
5.9KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any purpose with
  6. * or without fee is hereby granted, provided that the above copyright notice and this
  7. * permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  10. * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  11. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  13. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #ifndef NANO_PERF_WIDGET_HPP_INCLUDED
  17. #define NANO_PERF_WIDGET_HPP_INCLUDED
  18. // ------------------------------------------------------
  19. // DGL Stuff
  20. #include "NanoVG.hpp"
  21. #include "../../dpf/distrho/extra/String.hpp"
  22. // ------------------------------------------------------
  23. // use namespace
  24. using DISTRHO::String;
  25. using DGL::IdleCallback;
  26. using DGL::NanoVG;
  27. using DGL::NanoWidget;
  28. using DGL::Widget;
  29. using DGL::Window;
  30. // ------------------------------------------------------
  31. // get time
  32. #include <sys/time.h>
  33. #include <time.h>
  34. #ifdef DISTRHO_OS_WINDOWS
  35. #else
  36. struct TimePOSIX {
  37. bool monotonic;
  38. double resolution;
  39. uint64_t base;
  40. TimePOSIX()
  41. : monotonic(false),
  42. resolution(1e-6),
  43. base(0)
  44. {
  45. #if defined(CLOCK_MONOTONIC)
  46. struct timespec ts;
  47. if (::clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
  48. {
  49. monotonic = true;
  50. resolution = 1e-9;
  51. }
  52. #endif
  53. base = getRawTime();
  54. }
  55. uint64_t getRawTime()
  56. {
  57. #if defined(CLOCK_MONOTONIC)
  58. if (monotonic)
  59. {
  60. struct timespec ts;
  61. ::clock_gettime(CLOCK_MONOTONIC, &ts);
  62. return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec;
  63. }
  64. else
  65. #endif
  66. {
  67. struct timeval tv;
  68. ::gettimeofday(&tv, NULL);
  69. return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec;
  70. }
  71. }
  72. double getTime()
  73. {
  74. return (double)(getRawTime() - base) * resolution;
  75. }
  76. };
  77. static TimePOSIX gTime;
  78. #endif
  79. // ------------------------------------------------------
  80. // our widget
  81. class NanoPerfWidget : public NanoWidget,
  82. public IdleCallback
  83. {
  84. public:
  85. static const int kHistoryCount = 100;
  86. enum RenderStyle {
  87. RENDER_FPS,
  88. RENDER_MS,
  89. };
  90. NanoPerfWidget(Window& parent, RenderStyle style, const char* name)
  91. : NanoWidget(parent),
  92. fHead(0),
  93. fStyle(style),
  94. fName(name)
  95. {
  96. parent.addIdleCallback(this);
  97. setSize(200, 35);
  98. std::memset(fValues, 0, sizeof(float)*kHistoryCount);
  99. createFontFromFile("sans", "./nanovg_res/Roboto-Regular.ttf");
  100. prevt = gTime.getTime();
  101. }
  102. protected:
  103. void idleCallback() override
  104. {
  105. repaint();
  106. }
  107. void onNanoDisplay() override
  108. {
  109. double t, dt;
  110. t = gTime.getTime();
  111. dt = t - prevt;
  112. prevt = t;
  113. update(dt);
  114. const int w = 200; //getWidth();
  115. const int h = 35; //getHeight();
  116. int i;
  117. float avg;
  118. char str[64];
  119. avg = getAverage();
  120. beginPath();
  121. rect(0, 0, w, h);
  122. fillColor(0,0,0,128);
  123. fill();
  124. beginPath();
  125. moveTo(0, h);
  126. if (fStyle == RENDER_FPS)
  127. {
  128. for (i = 0; i < kHistoryCount; ++i)
  129. {
  130. float v = 1.0f / (0.00001f + fValues[(fHead+i) % kHistoryCount]);
  131. float vx, vy;
  132. if (v > 80.0f) v = 80.0f;
  133. vx = ((float)i/(kHistoryCount-1)) * w;
  134. vy = h - ((v / 80.0f) * h);
  135. lineTo(vx, vy);
  136. }
  137. }
  138. else
  139. {
  140. for (i = 0; i < kHistoryCount; ++i)
  141. {
  142. float v = fValues[(fHead+i) % kHistoryCount] * 1000.0f;
  143. float vx, vy;
  144. if (v > 20.0f) v = 20.0f;
  145. vx = ((float)i/(kHistoryCount-1)) * w;
  146. vy = h - ((v / 20.0f) * h);
  147. lineTo(vx, vy);
  148. }
  149. }
  150. lineTo(w, h);
  151. fillColor(255,192,0,128);
  152. fill();
  153. fontFace("sans");
  154. if (fName.isNotEmpty())
  155. {
  156. fontSize(14.0f);
  157. textAlign(ALIGN_LEFT|ALIGN_TOP);
  158. fillColor(240,240,240,192);
  159. text(3, 1, fName, nullptr);
  160. }
  161. if (fStyle == RENDER_FPS)
  162. {
  163. fontSize(18.0f);
  164. textAlign(ALIGN_RIGHT|ALIGN_TOP);
  165. fillColor(240,240,240,255);
  166. std::sprintf(str, "%.2f FPS", 1.0f / avg);
  167. text(w-3, 1, str, nullptr);
  168. fontSize(15.0f);
  169. textAlign(ALIGN_RIGHT|ALIGN_BOTTOM);
  170. fillColor(240,240,240,160);
  171. std::sprintf(str, "%.2f ms", avg * 1000.0f);
  172. text(w-3, h-1, str, nullptr);
  173. }
  174. else
  175. {
  176. fontSize(18.0f);
  177. textAlign(ALIGN_RIGHT|ALIGN_TOP);
  178. fillColor(240,240,240,255);
  179. std::sprintf(str, "%.2f ms", avg * 1000.0f);
  180. text(w-3, 1, str, nullptr);
  181. }
  182. }
  183. private:
  184. int fHead;
  185. float fValues[kHistoryCount];
  186. const int fStyle;
  187. const String fName;
  188. double prevt;
  189. void update(float frameTime) noexcept
  190. {
  191. fHead = (fHead+1) % kHistoryCount;
  192. fValues[fHead] = frameTime;
  193. }
  194. float getAverage() const noexcept
  195. {
  196. int i;
  197. float avg = 0;
  198. for (i = 0; i < kHistoryCount; ++i)
  199. avg += fValues[i];
  200. return avg / (float)kHistoryCount;
  201. }
  202. };
  203. // ------------------------------------------------------
  204. #endif // NANO_PERF_WIDGET_HPP_INCLUDED