Merge branch 'add_a_performance_overlay_ui_element'
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
#include "Scene/Material.hpp"
|
#include "Scene/Material.hpp"
|
||||||
#include "Scene/Vertex.hpp"
|
#include "Scene/Vertex.hpp"
|
||||||
#include "Scene/SimpleDrawable.hpp"
|
#include "Scene/SimpleDrawable.hpp"
|
||||||
|
#include "Scene/UI/PerformanceInfo.hpp"
|
||||||
#include "Input/InputManager.hpp"
|
#include "Input/InputManager.hpp"
|
||||||
#include "Host/GraphicsAppManager.hpp"
|
#include "Host/GraphicsAppManager.hpp"
|
||||||
#include "Math/Math.hpp"
|
#include "Math/Math.hpp"
|
||||||
@@ -42,6 +43,9 @@ namespace OpenVulkano
|
|||||||
std::vector<Node> nodesPool;
|
std::vector<Node> nodesPool;
|
||||||
Vector3f_SIMD position = {0, 0, -10};
|
Vector3f_SIMD position = {0, 0, -10};
|
||||||
|
|
||||||
|
OpenVulkano::Scene::UI::SimpleUi m_ui;
|
||||||
|
std::shared_ptr<OpenVulkano::Scene::UI::PerformanceInfo> m_perfInfo;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Init() override
|
void Init() override
|
||||||
{
|
{
|
||||||
@@ -78,6 +82,10 @@ namespace OpenVulkano
|
|||||||
|
|
||||||
camController.Init(&cam);
|
camController.Init(&cam);
|
||||||
camController.SetDefaultKeybindings();
|
camController.SetDefaultKeybindings();
|
||||||
|
|
||||||
|
std::shared_ptr<OpenVulkano::Scene::UI::PerformanceInfo> m_perfInfo = std::make_shared<OpenVulkano::Scene::UI::PerformanceInfo>();
|
||||||
|
m_ui.AddElement(m_perfInfo);
|
||||||
|
GetGraphicsAppManager()->GetRenderer()->SetActiveUi(&m_ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tick() override
|
void Tick() override
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "Scene/Camera.hpp"
|
#include "Scene/Camera.hpp"
|
||||||
#include "Scene/SimpleAnimationController.hpp"
|
#include "Scene/SimpleAnimationController.hpp"
|
||||||
#include "Scene/SequenceAnimationController.hpp"
|
#include "Scene/SequenceAnimationController.hpp"
|
||||||
|
#include "Scene/UI/PerformanceInfo.hpp"
|
||||||
#include "Input/InputManager.hpp"
|
#include "Input/InputManager.hpp"
|
||||||
#include "Host/GraphicsAppManager.hpp"
|
#include "Host/GraphicsAppManager.hpp"
|
||||||
#include "Base/EngineConfiguration.hpp"
|
#include "Base/EngineConfiguration.hpp"
|
||||||
@@ -44,6 +45,9 @@ namespace OpenVulkano
|
|||||||
Scene::SimpleAnimationController m_simpleAnimationController;
|
Scene::SimpleAnimationController m_simpleAnimationController;
|
||||||
Scene::SequenceAnimationController m_sequenceAnimationController;
|
Scene::SequenceAnimationController m_sequenceAnimationController;
|
||||||
|
|
||||||
|
Scene::UI::SimpleUi m_ui;
|
||||||
|
std::shared_ptr<Scene::UI::PerformanceInfo> m_perfInfo;
|
||||||
|
|
||||||
SceneElement m_whiteBox;
|
SceneElement m_whiteBox;
|
||||||
SceneElement m_redBox;
|
SceneElement m_redBox;
|
||||||
|
|
||||||
@@ -161,6 +165,10 @@ namespace OpenVulkano
|
|||||||
|
|
||||||
CreatePyramid(&m_pyramid, Math::Vector4f(0.9, 0.9, 0.6, 1.0));
|
CreatePyramid(&m_pyramid, Math::Vector4f(0.9, 0.9, 0.6, 1.0));
|
||||||
m_pyramid.m_node.worldMat = Math::Utils::translate(Math::Vector3f(13, 0, 0));
|
m_pyramid.m_node.worldMat = Math::Utils::translate(Math::Vector3f(13, 0, 0));
|
||||||
|
|
||||||
|
std::shared_ptr<Scene::UI::PerformanceInfo> m_perfInfo = std::make_shared<Scene::UI::PerformanceInfo>();
|
||||||
|
m_ui.AddElement(m_perfInfo);
|
||||||
|
GetGraphicsAppManager()->GetRenderer()->SetActiveUi(&m_ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnSimpleAnimationCompleted(Scene::SimpleAnimationController *anim)
|
void OnSimpleAnimationCompleted(Scene::SimpleAnimationController *anim)
|
||||||
|
|||||||
@@ -48,13 +48,25 @@ namespace OpenVulkano
|
|||||||
{
|
{
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case APP_MEM_TYPE::VM_MAX: return counters.PeakWorkingSetSize;
|
case APP_MEM_TYPE::VM_MAX: return counters.PeakPagefileUsage;
|
||||||
case APP_MEM_TYPE::USED: return counters.PrivateUsage;
|
case APP_MEM_TYPE::USED: return counters.PrivateUsage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Logger::PERF->error("Failed to get process memory info");
|
Logger::PERF->error("Failed to get process memory info");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t GetCommitLimit()
|
||||||
|
{
|
||||||
|
MEMORYSTATUSEX status;
|
||||||
|
status.dwLength = sizeof(status);
|
||||||
|
if(GlobalMemoryStatusEx(&status))
|
||||||
|
{
|
||||||
|
return status.ullTotalPageFile;
|
||||||
|
}
|
||||||
|
Logger::PERF->error("Failed to get system commit limit");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SystemInfo::GetSystemRam()
|
size_t SystemInfo::GetSystemRam()
|
||||||
@@ -69,12 +81,12 @@ namespace OpenVulkano
|
|||||||
|
|
||||||
size_t SystemInfo::GetAppRamMax()
|
size_t SystemInfo::GetAppRamMax()
|
||||||
{
|
{
|
||||||
return std::min(GetSystemRam(), GetAppVirtualMemoryMax());
|
return std::min(GetSystemRam(), GetCommitLimit());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SystemInfo::GetAppRamAvailable()
|
size_t SystemInfo::GetAppRamAvailable()
|
||||||
{
|
{
|
||||||
return std::min(GetSystemRamAvailable(), GetAppVirtualMemoryMax() - GetAppRamUsed());
|
return std::min(GetSystemRamAvailable(), GetCommitLimit() - GetAppRamUsed());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SystemInfo::GetAppRamUsed()
|
size_t SystemInfo::GetAppRamUsed()
|
||||||
|
|||||||
114
openVulkanoCpp/Scene/UI/ImGuiExtensions/ImGuiPlotTwoLines.cpp
Normal file
114
openVulkanoCpp/Scene/UI/ImGuiExtensions/ImGuiPlotTwoLines.cpp
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ImGuiPlotTwoLines.hpp"
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <imgui_internal.h>
|
||||||
|
|
||||||
|
namespace ImGui
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void RenderLine(ImDrawList* drawList, float (*getter)(void* data, int idx), void* data, int valuesCount, float scaleMin, float scaleMax, ImRect innerBb, ImColor color, int resW)
|
||||||
|
{
|
||||||
|
const float tStep = 1.0f / (float)resW;
|
||||||
|
const float invScale = (scaleMin == scaleMax) ? 0.0f : (1.0f / (scaleMax - scaleMin));
|
||||||
|
|
||||||
|
float v0 = getter(data, 0);
|
||||||
|
float t0 = 0.0f;
|
||||||
|
ImVec2 tp0 = ImVec2(t0, 1.0f - ImSaturate((v0 - scaleMin) * invScale));
|
||||||
|
|
||||||
|
for (int n = 0; n < resW; n++)
|
||||||
|
{
|
||||||
|
const float t1 = t0 + tStep;
|
||||||
|
const int v1Idx = (int)(t0 * (valuesCount - 1) + 0.5f);
|
||||||
|
IM_ASSERT(v1Idx >= 0 && v1Idx < valuesCount);
|
||||||
|
const float v1 = getter(data, ImMin(v1Idx + 1, valuesCount - 1));
|
||||||
|
const ImVec2 tp1 = ImVec2( t1, 1.0f - ImSaturate((v1 - scaleMin) * invScale) );
|
||||||
|
|
||||||
|
ImVec2 pos0 = ImLerp(innerBb.Min, innerBb.Max, tp0);
|
||||||
|
ImVec2 pos1 = ImLerp(innerBb.Min, innerBb.Max, tp1);
|
||||||
|
|
||||||
|
drawList->AddLine(pos0, pos1, color);
|
||||||
|
|
||||||
|
t0 = t1;
|
||||||
|
tp0 = tp1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlotTwoLines(const char* label,
|
||||||
|
float (*getter1)(void* data, int idx), void* data1, const char *tooltip1,
|
||||||
|
float (*getter2)(void* data, int idx), void* data2, const char *tooltip2,
|
||||||
|
int valuesCount, float scaleMin, float scaleMax, ImVec2 graphSize, ImColor color1, ImColor color2)
|
||||||
|
{
|
||||||
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
|
if (window->SkipItems)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ImGuiStyle& style = ImGui::GetCurrentContext()->Style;
|
||||||
|
const ImGuiID id = window->GetID(label);
|
||||||
|
|
||||||
|
const ImVec2 labelSize = CalcTextSize(label, NULL, true);
|
||||||
|
const ImVec2 frameSize = CalcItemSize(graphSize, CalcItemWidth(), labelSize.y + style.FramePadding.y * 2.0f);
|
||||||
|
|
||||||
|
const ImRect frameBb(window->DC.CursorPos, ImVec2(window->DC.CursorPos.x + frameSize.x, window->DC.CursorPos.y + frameSize.y));
|
||||||
|
const ImRect innerBb(ImVec2(frameBb.Min.x + style.FramePadding.x, frameBb.Min.y + style.FramePadding.y), ImVec2(frameBb.Max.x - style.FramePadding.x, frameBb.Max.y - style.FramePadding.y));
|
||||||
|
const ImRect totalBb(frameBb.Min, ImVec2(frameBb.Max.x + (labelSize.x > 0.0f ? (style.ItemInnerSpacing.x + labelSize.x) : 0.0f), frameBb.Max.y));
|
||||||
|
|
||||||
|
ItemSize(totalBb, style.FramePadding.y);
|
||||||
|
if (!ItemAdd(totalBb, 0, &frameBb))
|
||||||
|
return;
|
||||||
|
const bool hovered = ItemHoverable(frameBb, id, ImGui::GetCurrentContext()->LastItemData.InFlags);
|
||||||
|
|
||||||
|
// Determine scale from values if not specified
|
||||||
|
if(scaleMin == FLT_MAX || scaleMax == FLT_MAX)
|
||||||
|
{
|
||||||
|
float vMin = FLT_MAX;
|
||||||
|
float vMax = -FLT_MAX;
|
||||||
|
for(int i = 0; i < valuesCount; i++)
|
||||||
|
{
|
||||||
|
const float v1 = getter1(data1, i);
|
||||||
|
const float v2 = getter2(data2, i);
|
||||||
|
if(v1 != v1 || v2 != v2) // Ignore NaN values
|
||||||
|
continue;
|
||||||
|
vMin = ImMin(ImMin(vMin, v1), v2);
|
||||||
|
vMax = ImMax(ImMax(vMax, v1), v2);
|
||||||
|
}
|
||||||
|
if(scaleMin == FLT_MAX)
|
||||||
|
scaleMin = vMin;
|
||||||
|
if(scaleMax == FLT_MAX)
|
||||||
|
scaleMax = vMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderFrame(frameBb.Min, frameBb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
||||||
|
|
||||||
|
if(valuesCount >= 2)
|
||||||
|
{
|
||||||
|
int resW = ImMin((int)frameSize.x, valuesCount) - 1;
|
||||||
|
int itemCount = valuesCount - 1;
|
||||||
|
|
||||||
|
// Tooltip on hover
|
||||||
|
if(hovered && innerBb.Contains(ImGui::GetCurrentContext()->IO.MousePos))
|
||||||
|
{
|
||||||
|
const float t = ImClamp((ImGui::GetCurrentContext()->IO.MousePos.x - innerBb.Min.x) / (innerBb.Max.x - innerBb.Min.x), 0.0f, 0.9999f);
|
||||||
|
const int vIdx = (int)(t * itemCount);
|
||||||
|
IM_ASSERT(vIdx >= 0 && vIdx < valuesCount);
|
||||||
|
|
||||||
|
const float v0 = getter1(data1, vIdx % valuesCount);
|
||||||
|
const float v1 = getter2(data2, (vIdx + 1) % valuesCount);
|
||||||
|
SetTooltip("%s: %8.4g\n%s: %8.4g", tooltip1, v0, tooltip2, v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderLine(window->DrawList, getter1, data1, valuesCount, scaleMin, scaleMax, innerBb, color1, resW);
|
||||||
|
RenderLine(window->DrawList, getter2, data2, valuesCount, scaleMin, scaleMax, innerBb, color2, resW);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(labelSize.x > 0.0f)
|
||||||
|
RenderText(ImVec2(frameBb.Max.x + style.ItemInnerSpacing.x, innerBb.Min.y), label);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace ImGui
|
||||||
|
{
|
||||||
|
void PlotTwoLines(const char* label,
|
||||||
|
float (*getter1)(void* data, int idx), void* data1, const char *tooltipPrefix1,
|
||||||
|
float (*getter2)(void* data, int idx), void* data2, const char *tooltipPrefix2,
|
||||||
|
int values_count, float scale_min = FLT_MAX, float scale_max = FLT_MAX,
|
||||||
|
ImVec2 graph_size = ImVec2(0, 0), ImColor color1 = ImColor(255, 100, 100), ImColor color2 = ImColor(100, 255, 100));
|
||||||
|
}
|
||||||
@@ -22,6 +22,6 @@ namespace ImGui
|
|||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
IMGUI_API void TextFmt(T&& fmt, const Args &... args) {
|
IMGUI_API void TextFmt(T&& fmt, const Args &... args) {
|
||||||
std::string str = fmt::format(std::forward<T>(fmt), args...);
|
std::string str = fmt::format(std::forward<T>(fmt), args...);
|
||||||
ImGui::TextUnformatted(&*str.begin(), &*str.end());
|
ImGui::TextUnformatted(str.data(), str.data() + str.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
92
openVulkanoCpp/Scene/UI/PerformanceInfo.cpp
Normal file
92
openVulkanoCpp/Scene/UI/PerformanceInfo.cpp
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PerformanceInfo.hpp"
|
||||||
|
#include "Base/FrameMetadata.hpp"
|
||||||
|
#include "Base/Utils.hpp"
|
||||||
|
#include "Host/SystemInfo.hpp"
|
||||||
|
#include "Math/ByteSize.hpp"
|
||||||
|
#include "ImGuiExtensions/ImGuiTextFmt.hpp"
|
||||||
|
#include "ImGuiExtensions/ImGuiPlotTwoLines.hpp"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
namespace OpenVulkano::Scene::UI
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
float FloatCollectionValuesGetter(void *data, int index)
|
||||||
|
{
|
||||||
|
auto collection = static_cast<FloatCollection *>(data);
|
||||||
|
float value = collection->m_values[index];
|
||||||
|
float result = value / collection->m_maxValue * 100;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerformanceInfo::UpdateQueues()
|
||||||
|
{
|
||||||
|
float newFrameTime = static_cast<float>(CURRENT_FRAME.frameTime);
|
||||||
|
if(newFrameTime > m_frames.m_maxValue)
|
||||||
|
m_frames.m_maxValue = newFrameTime;
|
||||||
|
|
||||||
|
m_frames.m_values.push_back(newFrameTime);
|
||||||
|
|
||||||
|
while(m_frames.m_values.size() > m_windowSize)
|
||||||
|
{
|
||||||
|
float poppedFrameTime = m_frames.m_values.front();
|
||||||
|
m_frames.m_values.pop_front();
|
||||||
|
if(m_frames.m_maxValue == poppedFrameTime)
|
||||||
|
{
|
||||||
|
m_frames.m_maxValue = FLT_MIN;
|
||||||
|
for(auto value : m_frames.m_values)
|
||||||
|
{
|
||||||
|
if(value > m_frames.m_maxValue)
|
||||||
|
m_frames.m_maxValue = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ramUsed.m_values.push_back(static_cast<float>(SystemInfo::GetAppRamUsed()));
|
||||||
|
while(m_ramUsed.m_values.size() > m_windowSize)
|
||||||
|
m_ramUsed.m_values.pop_front();
|
||||||
|
|
||||||
|
m_ramUsed.m_maxValue = SystemInfo::GetAppRamMax();
|
||||||
|
|
||||||
|
assert(m_ramUsed.m_values.size() <= m_windowSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerformanceInfo::BeginDraw()
|
||||||
|
{
|
||||||
|
bool alwaysShow = true;
|
||||||
|
ImGui::Begin("Performance Info", &alwaysShow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerformanceInfo::Draw()
|
||||||
|
{
|
||||||
|
UpdateQueues();
|
||||||
|
assert(m_frames.m_values.size() == m_ramUsed.m_values.size());
|
||||||
|
|
||||||
|
ImGui::Text("Last Frame Time: %f s, max: %f s", m_frames.m_values.back(), m_frames.m_maxValue);
|
||||||
|
ImGui::Text("Last FPS: %f", 1 / m_frames.m_values.back());
|
||||||
|
ImGui::TextFmt("RAM: {} / {}, Free: {}", ByteSize(m_ramUsed.m_values.back()), ByteSize(SystemInfo::GetAppRamMax()), ByteSize(SystemInfo::GetAppRamAvailable()));
|
||||||
|
ImGui::SliderInt("Window Size", &m_windowSize, 10, 1000);
|
||||||
|
|
||||||
|
ImVec2 availableSize = ImGui::GetContentRegionAvail();
|
||||||
|
float scaleMin = 0.01;
|
||||||
|
float scaleMax = 100;
|
||||||
|
ImGui::PlotTwoLines("",
|
||||||
|
&FloatCollectionValuesGetter, &m_frames, "Frame Time(wrt max)",
|
||||||
|
&FloatCollectionValuesGetter, &m_ramUsed, "RAM",
|
||||||
|
(int)m_ramUsed.m_values.size(),
|
||||||
|
scaleMin, scaleMax, availableSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerformanceInfo::EndDraw()
|
||||||
|
{
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
34
openVulkanoCpp/Scene/UI/PerformanceInfo.hpp
Normal file
34
openVulkanoCpp/Scene/UI/PerformanceInfo.hpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "UI.hpp"
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
|
namespace OpenVulkano::Scene::UI
|
||||||
|
{
|
||||||
|
struct FloatCollection
|
||||||
|
{
|
||||||
|
std::deque<float> m_values;
|
||||||
|
float m_maxValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PerformanceInfo : public UiElement
|
||||||
|
{
|
||||||
|
int m_windowSize = 200;
|
||||||
|
FloatCollection m_ramUsed;
|
||||||
|
FloatCollection m_frames;
|
||||||
|
|
||||||
|
void UpdateQueues();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void BeginDraw() override;
|
||||||
|
void Draw() override;
|
||||||
|
void EndDraw() override;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -50,4 +50,15 @@ namespace OpenVulkano::Scene::UI
|
|||||||
|
|
||||||
void Draw() override {}
|
void Draw() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SimpleUi : public Ui
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Init() override {}
|
||||||
|
|
||||||
|
void AddElement(const std::shared_ptr<UiElement>& element)
|
||||||
|
{
|
||||||
|
children.push_back(element);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user