From ea431882a75b6b99868e5d57d4c8436ccf79b50a Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Mon, 31 May 2021 14:17:59 -0400 Subject: [PATCH] Add Engine meter to menu bar. --- include/engine/Engine.hpp | 4 ++++ src/app/MenuBar.cpp | 23 +++++++++++++++++++- src/engine/Engine.cpp | 46 ++++++++++++++++++++++++++++++++++----- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/include/engine/Engine.hpp b/include/engine/Engine.hpp index 990e7d77..a919d9fd 100644 --- a/include/engine/Engine.hpp +++ b/include/engine/Engine.hpp @@ -85,6 +85,10 @@ struct Engine { Calculated by `stepFrames / sampleRate`. */ double getBlockDuration(); + /** Returns the average block processing time divided by block time in the last T seconds. + */ + double getMeterAverage(); + double getMeterMax(); // Modules size_t getNumModules(); diff --git a/src/app/MenuBar.cpp b/src/app/MenuBar.cpp index f96ee694..01a71f83 100644 --- a/src/app/MenuBar.cpp +++ b/src/app/MenuBar.cpp @@ -1057,14 +1057,25 @@ struct HelpButton : MenuButton { // MenuBar //////////////////// +struct MeterLabel : widget::OpaqueWidget { + void draw(const DrawArgs& args) override { + double meterAverage = APP->engine->getMeterAverage(); + double meterMax = APP->engine->getMeterMax(); + std::string text = string::f("%.1f%% avg / %.1f%% max", meterAverage * 100, meterMax * 100); + bndMenuLabel(args.vg, 0.0, 0.0, box.size.x, box.size.y, -1, text.c_str()); + } +}; + struct MenuBar : widget::OpaqueWidget { + MeterLabel* meterLabel; + MenuBar() { const float margin = 5; box.size.y = BND_WIDGET_HEIGHT + 2 * margin; ui::SequentialLayout* layout = new ui::SequentialLayout; - layout->box.pos = math::Vec(margin, margin); + layout->margin = math::Vec(margin, margin); layout->spacing = math::Vec(0, 0); addChild(layout); @@ -1095,6 +1106,11 @@ struct MenuBar : widget::OpaqueWidget { MenuButton* alphaButton = new MenuButton; alphaButton->text = "Pre-alpha build. Not for release."; layout->addChild(alphaButton); + + meterLabel = new MeterLabel; + meterLabel->box.pos.y = margin; + meterLabel->box.size.x = 160; + addChild(meterLabel); } void draw(const DrawArgs& args) override { @@ -1103,6 +1119,11 @@ struct MenuBar : widget::OpaqueWidget { Widget::draw(args); } + + void step() override { + meterLabel->box.pos.x = box.size.x - meterLabel->box.size.x; + Widget::step(); + } }; diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index b789bba4..915d9339 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -201,6 +201,7 @@ struct Engine::Internal { std::vector modules; std::vector cables; std::set paramHandles; + Module* primaryModule = NULL; // moduleId std::map modulesCache; @@ -216,7 +217,14 @@ struct Engine::Internal { int64_t blockFrame = 0; double blockTime = 0.0; int blockFrames = 0; - Module* primaryModule = NULL; + + // Meter + int meterCount = 0; + double meterTotal = 0.0; + double meterMax = 0.0; + double meterLastTime = -INFINITY; + double meterLastAverage = 0.0; + double meterLastMax = 0.0; // Parameter smoothing Module* smoothModule = NULL; @@ -516,6 +524,9 @@ void Engine::clear_NoLock() { void Engine::stepBlock(int frames) { + // Start timer before locking + double startTime = system::getTime(); + std::lock_guard stepLock(internal->blockMutex); ReadLock lock(internal->mutex); // Configure thread @@ -542,12 +553,25 @@ void Engine::stepBlock(int frames) { yieldWorkers(); - double endTime = system::getTime(); - float duration = endTime - internal->blockTime; - float blockDuration = internal->blockFrames * internal->sampleTime; - // DEBUG("%d %f / %f = %f%%", internal->blockFrames, duration, blockDuration, duration / blockDuration * 100.f); - internal->block++; + + // Stop timer + double endTime = system::getTime(); + double meter = (endTime - startTime) / (frames * internal->sampleTime); + internal->meterTotal += meter; + internal->meterMax = std::fmax(internal->meterMax, meter); + internal->meterCount++; + + // Update meter values + const double meterUpdateDuration = 1.0; + if (startTime - internal->meterLastTime >= meterUpdateDuration) { + internal->meterLastAverage = internal->meterTotal / internal->meterCount; + internal->meterLastMax = internal->meterMax; + internal->meterLastTime = startTime; + internal->meterCount = 0; + internal->meterTotal = 0.0; + internal->meterMax = 0.0; + } } @@ -643,6 +667,16 @@ double Engine::getBlockDuration() { } +double Engine::getMeterAverage() { + return internal->meterLastAverage; +} + + +double Engine::getMeterMax() { + return internal->meterLastMax; +} + + size_t Engine::getNumModules() { return internal->modules.size(); }