From e951359a46b92dcd93a3254606ba14668d6028b0 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Wed, 20 Dec 2023 13:42:42 +0100 Subject: [PATCH] feat: Add frame time graph to FPS display --- lib/libimhex/include/hex/api/imhex_api.hpp | 3 +++ lib/libimhex/source/api/imhex_api.cpp | 12 +++++++++- main/gui/source/init/splash_window.cpp | 12 ++++++---- main/gui/source/window/window.cpp | 2 ++ plugins/builtin/source/content/ui_items.cpp | 26 +++++++++++++++++++++ 5 files changed, 49 insertions(+), 6 deletions(-) diff --git a/lib/libimhex/include/hex/api/imhex_api.hpp b/lib/libimhex/include/hex/api/imhex_api.hpp index 26f2357cd..16d2f800d 100644 --- a/lib/libimhex/include/hex/api/imhex_api.hpp +++ b/lib/libimhex/include/hex/api/imhex_api.hpp @@ -366,6 +366,7 @@ namespace hex { void addInitArgument(const std::string &key, const std::string &value = { }); + void setLastFrameTime(double time); } struct ProgramArguments { @@ -557,6 +558,8 @@ namespace hex { bool updateImHex(UpdateType updateType); void addStartupTask(const std::string &name, bool async, const std::function &function); + + double getLastFrameTime(); } /** diff --git a/lib/libimhex/source/api/imhex_api.cpp b/lib/libimhex/source/api/imhex_api.cpp index 31097e10f..6539bd797 100644 --- a/lib/libimhex/source/api/imhex_api.cpp +++ b/lib/libimhex/source/api/imhex_api.cpp @@ -381,7 +381,6 @@ namespace hex { // Default to true means we forward to ourselves by default static bool s_isMainInstance = true; - void setMainInstanceStatus(bool status) { s_isMainInstance = status; } @@ -436,6 +435,12 @@ namespace hex { getInitArguments()[key] = value; } + static double s_lastFrameTime; + void setLastFrameTime(double time) { + s_lastFrameTime = time; + } + + } bool isMainInstance() { @@ -687,6 +692,11 @@ namespace hex { RequestAddInitTask::post(name, async, function); } + double getLastFrameTime() { + return impl::s_lastFrameTime; + } + + } namespace ImHexApi::Messaging { diff --git a/main/gui/source/init/splash_window.cpp b/main/gui/source/init/splash_window.cpp index 1a260bb65..80d3458c0 100644 --- a/main/gui/source/init/splash_window.cpp +++ b/main/gui/source/init/splash_window.cpp @@ -82,6 +82,9 @@ namespace hex::init { static ImColor getHighlightColor(u32 index) { static auto highlightConfig = nlohmann::json::parse(romfs::get("splash_colors.json").string()); static std::list selectedConfigs; + static nlohmann::json selectedConfig; + + static std::mt19937 random(std::random_device{}()); if (selectedConfigs.empty()) { const auto now = []{ @@ -110,15 +113,14 @@ namespace hex::init { // Remove the default color theme if there's another one available if (selectedConfigs.size() != 1) selectedConfigs.erase(selectedConfigs.begin()); + + selectedConfig = *std::next(selectedConfigs.begin(), random() % selectedConfigs.size()); + + log::debug("Using '{}' highlight color theme", selectedConfig["name"].get()); } - std::mt19937 random(std::random_device{}()); - - static const auto &selectedConfig = *std::next(selectedConfigs.begin(), random() % selectedConfigs.size()); - const auto colorString = selectedConfig["colors"][index % selectedConfig["colors"].size()].get(); - log::debug("Using '{}' highlight color theme", selectedConfig["name"].get()); if (colorString == "random") { float r, g, b; ImGui::ColorConvertHSVtoRGB( diff --git a/main/gui/source/window/window.cpp b/main/gui/source/window/window.cpp index 6060624a9..907170067 100644 --- a/main/gui/source/window/window.cpp +++ b/main/gui/source/window/window.cpp @@ -211,6 +211,8 @@ namespace hex { this->fullFrame(); frameCount += 1; + ImHexApi::System::impl::setLastFrameTime(glfwGetTime() - m_lastStartFrameTime); + // Limit frame rate // If the target FPS are below 15, use the monitor refresh rate, if it's above 200, don't limit the frame rate const auto targetFPS = ImHexApi::System::getTargetFPS(); diff --git a/plugins/builtin/source/content/ui_items.cpp b/plugins/builtin/source/content/ui_items.cpp index 7bd7fa9e8..8e6263bf2 100644 --- a/plugins/builtin/source/content/ui_items.cpp +++ b/plugins/builtin/source/content/ui_items.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -73,6 +74,31 @@ namespace hex::plugin::builtin { } ImGuiExt::TextFormatted("FPS {0:3}.{1:02}", u32(framerate), u32(framerate * 100) % 100); + + if (ImGui::IsItemHovered()) { + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2()); + if (ImGui::BeginTooltip()) { + if (ImPlot::BeginPlot("##frame_time_graph", scaled({ 200, 100 }), ImPlotFlags_CanvasOnly | ImPlotFlags_NoFrame | ImPlotFlags_NoInputs)) { + ImPlot::SetupAxes("", "", ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_NoTickLabels, ImPlotAxisFlags_NoLabel | ImPlotAxisFlags_LockMin | ImPlotAxisFlags_AutoFit); + ImPlot::SetupAxisLimits(ImAxis_Y1, 0, 0.01, ImPlotCond_Always); + ImPlot::SetupAxisFormat(ImAxis_Y1, [](double value, char* buff, int size, void*) -> int { + return snprintf(buff, size, "%dms", int(value * 1000.0)); + }, nullptr); + ImPlot::SetupAxisTicks(ImAxis_Y1, 0, 0.01, 3); + + static std::vector values(100); + + values.push_back(ImHexApi::System::getLastFrameTime()); + if (values.size() > 100) + values.erase(values.begin()); + + ImPlot::PlotLine("FPS", values.data(), values.size()); + ImPlot::EndPlot(); + } + ImGui::EndTooltip(); + } + ImGui::PopStyleVar(); + } }); #endif