StatsUiNode.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Scene/StatsUiNode.h>
  6. #include <AnKi/Scene/Components/UiComponent.h>
  7. #include <AnKi/Core/StatsSet.h>
  8. #include <AnKi/Core/App.h>
  9. #include <AnKi/Ui/UiManager.h>
  10. #include <AnKi/Renderer/Renderer.h>
  11. namespace anki {
  12. static void labelBytes(PtrSize val, CString name)
  13. {
  14. PtrSize gb, mb, kb, b;
  15. gb = val / 1_GB;
  16. val -= gb * 1_GB;
  17. mb = val / 1_MB;
  18. val -= mb * 1_MB;
  19. kb = val / 1_KB;
  20. val -= kb * 1_KB;
  21. b = val;
  22. UiString timestamp;
  23. if(gb)
  24. {
  25. timestamp.sprintf("%s: %zu,%04zu,%04zu,%04zu", name.cstr(), gb, mb, kb, b);
  26. }
  27. else if(mb)
  28. {
  29. timestamp.sprintf("%s: %zu,%04zu,%04zu", name.cstr(), mb, kb, b);
  30. }
  31. else if(kb)
  32. {
  33. timestamp.sprintf("%s: %zu,%04zu", name.cstr(), kb, b);
  34. }
  35. else
  36. {
  37. timestamp.sprintf("%s: %zu", name.cstr(), b);
  38. }
  39. ImGui::TextUnformatted(timestamp.cstr());
  40. }
  41. class StatsUiNode::Value
  42. {
  43. public:
  44. F64 m_avg = 0.0;
  45. F64 m_rollingAvg = 0.0;
  46. void update(F64 x, Bool flush)
  47. {
  48. m_rollingAvg += x / F64(kBufferedFrames);
  49. if(flush)
  50. {
  51. m_avg = m_rollingAvg;
  52. m_rollingAvg = 0.0;
  53. }
  54. }
  55. };
  56. StatsUiNode::StatsUiNode(CString name)
  57. : SceneNode(name)
  58. {
  59. UiComponent* uic = newComponent<UiComponent>();
  60. uic->init(
  61. [](UiCanvas& canvas, void* ud) {
  62. static_cast<StatsUiNode*>(ud)->draw(canvas);
  63. },
  64. this);
  65. if(StatsSet::getSingleton().getCounterCount())
  66. {
  67. m_averageValues.resize(StatsSet::getSingleton().getCounterCount());
  68. }
  69. }
  70. StatsUiNode::~StatsUiNode()
  71. {
  72. }
  73. void StatsUiNode::draw(UiCanvas& canvas)
  74. {
  75. if(!m_font)
  76. {
  77. m_font = canvas.addFont("EngineAssets/UbuntuMonoRegular.ttf");
  78. }
  79. Bool flush = false;
  80. if(m_bufferedFrames == kBufferedFrames)
  81. {
  82. flush = true;
  83. m_bufferedFrames = 0;
  84. }
  85. ++m_bufferedFrames;
  86. ImGui::PushFont(m_font, 24.0f);
  87. const Vec4 oldWindowColor = ImGui::GetStyle().Colors[ImGuiCol_WindowBg];
  88. ImGui::GetStyle().Colors[ImGuiCol_WindowBg].w = 0.3f;
  89. if(ImGui::Begin("Stats", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysAutoResize))
  90. {
  91. ImGui::SetWindowPos(Vec2(5.0f, 5.0f));
  92. ImGui::SetWindowSize(Vec2(230.0f, 450.0f));
  93. if(!m_fpsOnly)
  94. {
  95. StatCategory category = StatCategory::kCount;
  96. U32 count = 0;
  97. StatsSet::getSingleton().iterateStats(
  98. [&](StatCategory c, const Char* name, U64 value, StatFlag flags) {
  99. if(category != c)
  100. {
  101. category = c;
  102. ImGui::Text("-- %s --", kStatCategoryTexts[c].cstr());
  103. // Hack
  104. if(c == StatCategory::kMisc)
  105. {
  106. ImGui::Text("Frame: %zu", GlobalFrameIndex::getSingleton().m_value);
  107. }
  108. }
  109. if(!!(flags & StatFlag::kBytes))
  110. {
  111. labelBytes(value, name);
  112. }
  113. else
  114. {
  115. ImGui::Text("%s: %zu", name, value);
  116. }
  117. ++count;
  118. },
  119. [&](StatCategory c, const Char* name, F64 value, StatFlag flags) {
  120. if(category != c)
  121. {
  122. category = c;
  123. ImGui::Text("-- %s --", kStatCategoryTexts[c].cstr());
  124. }
  125. if(!!(flags & StatFlag::kShowAverage))
  126. {
  127. m_averageValues[count].update(value, flush);
  128. value = m_averageValues[count].m_avg;
  129. }
  130. ImGui::Text("%s: %f", name, value);
  131. ++count;
  132. });
  133. }
  134. else
  135. {
  136. const Second maxTime = max(g_svarCpuTotalTime.getValue<F64>(), g_svarRendererGpuTime.getValue<F64>()) / 1000.0;
  137. const F32 fps = F32(1.0 / maxTime);
  138. const Bool cpuBound = g_svarCpuTotalTime.getValue<F64>() > g_svarRendererGpuTime.getValue<F64>();
  139. ImGui::TextColored((cpuBound) ? Vec4(1.0f, 0.5f, 0.5f, 1.0f) : Vec4(0.5f, 1.0f, 0.5f, 1.0f), "FPS %.1f", fps);
  140. }
  141. }
  142. ImGui::End();
  143. ImGui::GetStyle().Colors[ImGuiCol_WindowBg] = oldWindowColor;
  144. ImGui::PopFont();
  145. }
  146. } // end namespace anki