diff --git a/include/app/Scene.hpp b/include/app/Scene.hpp index d909df80..793cdf06 100644 --- a/include/app/Scene.hpp +++ b/include/app/Scene.hpp @@ -16,6 +16,7 @@ struct Scene : widget::OpaqueWidget { RackWidget* rack; MenuBar* menuBar; widget::Widget* moduleBrowser; + widget::Widget* frameRateWidget; double lastAutosaveTime = 0.0; diff --git a/include/window.hpp b/include/window.hpp index ad639b24..acb5b1ea 100644 --- a/include/window.hpp +++ b/include/window.hpp @@ -90,7 +90,8 @@ struct Window { void setFullScreen(bool fullScreen); bool isFullScreen(); bool isFrameOverdue(); - double getMonitorRefreshRate(); + float getMonitorRefreshRate(); + float getLastFrameRate(); std::shared_ptr loadFont(const std::string& filename); std::shared_ptr loadImage(const std::string& filename); diff --git a/src/app/MenuBar.cpp b/src/app/MenuBar.cpp index f351c989..05e6494c 100644 --- a/src/app/MenuBar.cpp +++ b/src/app/MenuBar.cpp @@ -339,11 +339,11 @@ struct FrameRateItem : ui::MenuItem { ui::Menu* menu = new ui::Menu; for (int i = 1; i <= 6; i++) { - double frameRate = APP->window->getMonitorRefreshRate() / i; + float frameRate = APP->window->getMonitorRefreshRate() / i; FrameRateValueItem* item = new FrameRateValueItem; item->frameSwapInterval = i; - item->text = string::f("%.0lf Hz", frameRate); + item->text = string::f("%.0f Hz", frameRate); item->rightText += CHECKMARK(settings::frameSwapInterval == i); menu->addChild(item); } diff --git a/src/app/Scene.cpp b/src/app/Scene.cpp index add47c34..2b9bb5a9 100644 --- a/src/app/Scene.cpp +++ b/src/app/Scene.cpp @@ -15,6 +15,14 @@ namespace rack { namespace app { +struct FrameRateWidget : widget::TransparentWidget { + void draw(const DrawArgs& args) override { + std::string text = string::f("%.2f Hz", APP->window->getLastFrameRate()); + bndLabel(args.vg, 0.0, 0.0, INFINITY, INFINITY, -1, text.c_str()); + } +}; + + Scene::Scene() { rackScroll = new RackScrollWidget; addChild(rackScroll); @@ -27,6 +35,11 @@ Scene::Scene() { moduleBrowser = moduleBrowserCreate(); moduleBrowser->hide(); addChild(moduleBrowser); + + frameRateWidget = new FrameRateWidget; + frameRateWidget->box.size = math::Vec(80.0, 30.0); + frameRateWidget->hide(); + addChild(frameRateWidget); } Scene::~Scene() { @@ -36,6 +49,7 @@ void Scene::step() { bool fullscreen = APP->window->isFullScreen(); menuBar->visible = !fullscreen; rackScroll->box.pos.y = menuBar->visible ? menuBar->box.size.y : 0; + frameRateWidget->box.pos.x = box.size.x - frameRateWidget->box.size.x; // Resize owned descendants menuBar->box.size.x = box.size.x; diff --git a/src/window.cpp b/src/window.cpp index 41b75ac9..1f6a62c6 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -96,7 +96,8 @@ struct Window::Internal { bool ignoreNextMouseDelta = false; int frameSwapInterval = -1; - double monitorRefreshRate = -1; + float monitorRefreshRate = 0.f; + float lastFrameRate = 0.f; }; @@ -329,8 +330,8 @@ void Window::run() { frame = 0; while (!glfwWindowShouldClose(win)) { double frameTime = glfwGetTime(); - // double frameRate = 1.0 / (frameTime - frameTimeStart); - // DEBUG("%g fps", frameRate); + internal->lastFrameRate = 1.f / float(frameTime - frameTimeStart); + // DEBUG("%.2f Hz", internal->lastFrameRate); frameTimeStart = frameTime; // Make event handlers and step() have a clean nanovg context @@ -529,10 +530,14 @@ bool Window::isFrameOverdue() { return frameDuration > frameDeadline; } -double Window::getMonitorRefreshRate() { +float Window::getMonitorRefreshRate() { return internal->monitorRefreshRate; } +float Window::getLastFrameRate() { + return internal->lastFrameRate; +} + std::shared_ptr Window::loadFont(const std::string& filename) { auto sp = fontCache[filename].lock(); if (!sp) {