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.

250 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/d_string.hpp"
  22. // ------------------------------------------------------
  23. // use namespace
  24. using DGL::IdleCallback;
  25. using DGL::NanoVG;
  26. using DGL::NanoWidget;
  27. using DGL::Widget;
  28. using DGL::Window;
  29. // ------------------------------------------------------
  30. // get time
  31. #include <sys/time.h>
  32. #include <time.h>
  33. #ifdef DISTRHO_OS_WINDOWS
  34. #else
  35. struct TimePOSIX {
  36. bool monotonic;
  37. double resolution;
  38. uint64_t base;
  39. TimePOSIX()
  40. : monotonic(false),
  41. resolution(1e-6),
  42. base(0)
  43. {
  44. #if defined(CLOCK_MONOTONIC)
  45. struct timespec ts;
  46. if (::clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
  47. {
  48. monotonic = true;
  49. resolution = 1e-9;
  50. }
  51. #endif
  52. base = getRawTime();
  53. }
  54. uint64_t getRawTime()
  55. {
  56. #if defined(CLOCK_MONOTONIC)
  57. if (monotonic)
  58. {
  59. struct timespec ts;
  60. ::clock_gettime(CLOCK_MONOTONIC, &ts);
  61. return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec;
  62. }
  63. else
  64. #endif
  65. {
  66. struct timeval tv;
  67. ::gettimeofday(&tv, NULL);
  68. return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec;
  69. }
  70. }
  71. double getTime()
  72. {
  73. return (double)(getRawTime() - base) * resolution;
  74. }
  75. };
  76. static TimePOSIX gTime;
  77. #endif
  78. // ------------------------------------------------------
  79. // our widget
  80. class NanoPerfWidget : public NanoWidget,
  81. public IdleCallback
  82. {
  83. public:
  84. static const int kHistoryCount = 100;
  85. enum RenderStyle {
  86. RENDER_FPS,
  87. RENDER_MS,
  88. };
  89. NanoPerfWidget(Window& parent, RenderStyle style, const char* name)
  90. : NanoWidget(parent),
  91. fHead(0),
  92. fStyle(style),
  93. fName(name)
  94. {
  95. parent.addIdleCallback(this);
  96. setSize(200, 35);
  97. std::memset(fValues, 0, sizeof(float)*kHistoryCount);
  98. createFont("sans", "./nanovg_res/Roboto-Regular.ttf");
  99. prevt = gTime.getTime();
  100. }
  101. protected:
  102. void idleCallback() override
  103. {
  104. repaint();
  105. }
  106. void onNanoDisplay() override
  107. {
  108. double t, dt;
  109. t = gTime.getTime();
  110. dt = t - prevt;
  111. prevt = t;
  112. update(dt);
  113. const int w = 200; //getWidth();
  114. const int h = 35; //getHeight();
  115. int i;
  116. float avg;
  117. char str[64];
  118. avg = getAverage();
  119. beginPath();
  120. rect(0, 0, w, h);
  121. fillColor(RGBA(0,0,0,128));
  122. fill();
  123. beginPath();
  124. moveTo(0, h);
  125. if (fStyle == RENDER_FPS)
  126. {
  127. for (i = 0; i < kHistoryCount; ++i)
  128. {
  129. float v = 1.0f / (0.00001f + fValues[(fHead+i) % kHistoryCount]);
  130. float vx, vy;
  131. if (v > 80.0f) v = 80.0f;
  132. vx = ((float)i/(kHistoryCount-1)) * w;
  133. vy = h - ((v / 80.0f) * h);
  134. lineTo(vx, vy);
  135. }
  136. }
  137. else
  138. {
  139. for (i = 0; i < kHistoryCount; ++i)
  140. {
  141. float v = fValues[(fHead+i) % kHistoryCount] * 1000.0f;
  142. float vx, vy;
  143. if (v > 20.0f) v = 20.0f;
  144. vx = ((float)i/(kHistoryCount-1)) * w;
  145. vy = h - ((v / 20.0f) * h);
  146. lineTo(vx, vy);
  147. }
  148. }
  149. lineTo(w, h);
  150. fillColor(RGBA(255,192,0,128));
  151. fill();
  152. fontFace("sans");
  153. if (fName.isNotEmpty())
  154. {
  155. fontSize(14.0f);
  156. textAlign(ALIGN_LEFT|ALIGN_TOP);
  157. fillColor(RGBA(240,240,240,192));
  158. text(3, 1, fName, nullptr);
  159. }
  160. if (fStyle == RENDER_FPS)
  161. {
  162. fontSize(18.0f);
  163. textAlign(ALIGN_RIGHT|ALIGN_TOP);
  164. fillColor(RGBA(240,240,240,255));
  165. std::sprintf(str, "%.2f FPS", 1.0f / avg);
  166. text(w-3, 1, str, nullptr);
  167. fontSize(15.0f);
  168. textAlign(ALIGN_RIGHT|ALIGN_BOTTOM);
  169. fillColor(RGBA(240,240,240,160));
  170. std::sprintf(str, "%.2f ms", avg * 1000.0f);
  171. text(w-3, h-1, str, nullptr);
  172. }
  173. else
  174. {
  175. fontSize(18.0f);
  176. textAlign(ALIGN_RIGHT|ALIGN_TOP);
  177. fillColor(RGBA(240,240,240,255));
  178. std::sprintf(str, "%.2f ms", avg * 1000.0f);
  179. text(w-3, 1, str, nullptr);
  180. }
  181. }
  182. private:
  183. int fHead;
  184. float fValues[kHistoryCount];
  185. const int fStyle;
  186. const d_string fName;
  187. double prevt;
  188. void update(float frameTime) noexcept
  189. {
  190. fHead = (fHead+1) % kHistoryCount;
  191. fValues[fHead] = frameTime;
  192. }
  193. float getAverage() const noexcept
  194. {
  195. int i;
  196. float avg = 0;
  197. for (i = 0; i < kHistoryCount; ++i)
  198. avg += fValues[i];
  199. return avg / (float)kHistoryCount;
  200. }
  201. };
  202. // ------------------------------------------------------
  203. #endif // NANO_PERF_WIDGET_HPP_INCLUDED