diff --git a/DDrawCompat/Config/Settings/StatsColumns.h b/DDrawCompat/Config/Settings/StatsColumns.h index f407c7f..66ba9b6 100644 --- a/DDrawCompat/Config/Settings/StatsColumns.h +++ b/DDrawCompat/Config/Settings/StatsColumns.h @@ -9,7 +9,7 @@ namespace Config class StatsColumns : public EnumListSetting { public: - enum Values { CUR, AVG, MIN, MAX, LABEL }; + enum Values { CUR, AVG, MIN, MAX, LABEL, VALUE_COUNT }; StatsColumns() : EnumListSetting("StatsColumns", "label, cur, avg, min, max", { "cur", "avg", "min", "max", "label" }) diff --git a/DDrawCompat/Config/Settings/StatsRows.h b/DDrawCompat/Config/Settings/StatsRows.h index 3bb0c5a..d64268d 100644 --- a/DDrawCompat/Config/Settings/StatsRows.h +++ b/DDrawCompat/Config/Settings/StatsRows.h @@ -25,7 +25,8 @@ namespace Config LOCKTIME, DDIUSAGE, GDIOBJECTS, - DEBUG + DEBUG, + VALUE_COUNT }; StatsRows() diff --git a/DDrawCompat/Gdi/GuiThread.cpp b/DDrawCompat/Gdi/GuiThread.cpp index ae6eace..14b81f5 100644 --- a/DDrawCompat/Gdi/GuiThread.cpp +++ b/DDrawCompat/Gdi/GuiThread.cpp @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include #include @@ -79,11 +81,17 @@ namespace return 0; } - Overlay::StatsWindow statsWindow; - g_statsWindow = &statsWindow; + if (0 != Config::statsHotKey.get().vk) + { + static Overlay::StatsWindow statsWindow; + g_statsWindow = &statsWindow; + } - Overlay::ConfigWindow configWindow; - g_configWindow = &configWindow; + if (0 != Config::configHotKey.get().vk) + { + static Overlay::ConfigWindow configWindow; + g_configWindow = &configWindow; + } { D3dDdi::ScopedCriticalSection lock; diff --git a/DDrawCompat/Overlay/StatsEventCount.cpp b/DDrawCompat/Overlay/StatsEventCount.cpp index 9cf8e7f..5ec3454 100644 --- a/DDrawCompat/Overlay/StatsEventCount.cpp +++ b/DDrawCompat/Overlay/StatsEventCount.cpp @@ -9,12 +9,6 @@ StatsEventCount::StatsEventCount() { } -void StatsEventCount::add(TickCount tickCount) -{ - setTickCount(tickCount); - m_sampleCount++; -} - void StatsEventCount::finalize(SampleCount& sampleCount, Stat& sum, Stat& min, Stat& max) { const uint32_t index = getCurrentTickCount() % s_update_rate; diff --git a/DDrawCompat/Overlay/StatsEventCount.h b/DDrawCompat/Overlay/StatsEventCount.h index d901937..27ab358 100644 --- a/DDrawCompat/Overlay/StatsEventCount.h +++ b/DDrawCompat/Overlay/StatsEventCount.h @@ -7,7 +7,14 @@ class StatsEventCount : public StatsQueue public: StatsEventCount(); - void add(TickCount tickCount); + void add(TickCount tickCount) + { + if (isEnabled()) + { + setTickCount(tickCount); + m_sampleCount++; + } + } private: virtual void finalize(SampleCount& sampleCount, Stat& sum, Stat& min, Stat& max) override; diff --git a/DDrawCompat/Overlay/StatsEventGroup.cpp b/DDrawCompat/Overlay/StatsEventGroup.cpp index 57a37a8..185b627 100644 --- a/DDrawCompat/Overlay/StatsEventGroup.cpp +++ b/DDrawCompat/Overlay/StatsEventGroup.cpp @@ -2,10 +2,11 @@ StatsEventGroup::StatsEventGroup() : m_rate(m_time) + , m_isEnabled(false) { } -void StatsEventGroup::add() +void StatsEventGroup::addImpl() { auto qpcNow = Time::queryPerformanceCounter(); auto tickCount = StatsQueue::getTickCount(qpcNow); @@ -13,3 +14,13 @@ void StatsEventGroup::add() m_count.add(tickCount); m_time.add(tickCount, qpcNow); } + +void StatsEventGroup::enable() +{ + if (m_rate.isEnabled()) + { + m_time.enable(); + } + + m_isEnabled = m_count.isEnabled() || m_time.isEnabled() || m_rate.isEnabled(); +} diff --git a/DDrawCompat/Overlay/StatsEventGroup.h b/DDrawCompat/Overlay/StatsEventGroup.h index 3283bcc..c86f486 100644 --- a/DDrawCompat/Overlay/StatsEventGroup.h +++ b/DDrawCompat/Overlay/StatsEventGroup.h @@ -9,9 +9,15 @@ class StatsEventGroup public: StatsEventGroup(); - void add(); + void add() { if (m_isEnabled) { addImpl(); } } + void enable(); StatsEventCount m_count; StatsEventTime m_time; StatsEventRate m_rate; + +private: + void addImpl(); + + bool m_isEnabled; }; diff --git a/DDrawCompat/Overlay/StatsEventTime.cpp b/DDrawCompat/Overlay/StatsEventTime.cpp index 24edc96..115b7b5 100644 --- a/DDrawCompat/Overlay/StatsEventTime.cpp +++ b/DDrawCompat/Overlay/StatsEventTime.cpp @@ -7,7 +7,7 @@ StatsEventTime::StatsEventTime() { } -void StatsEventTime::add(TickCount tickCount, long long qpcNow) +void StatsEventTime::addImpl(TickCount tickCount, long long qpcNow) { if (0 != m_qpcLast && qpcNow - m_qpcLast < s_history_time * Time::g_qpcFrequency) { diff --git a/DDrawCompat/Overlay/StatsEventTime.h b/DDrawCompat/Overlay/StatsEventTime.h index 53a92d3..e2fc243 100644 --- a/DDrawCompat/Overlay/StatsEventTime.h +++ b/DDrawCompat/Overlay/StatsEventTime.h @@ -7,11 +7,13 @@ class StatsEventTime : public StatsQueue public: StatsEventTime(); - void add(TickCount tickCount, long long qpcNow); + void add(TickCount tickCount, long long qpcNow) { if (isEnabled()) { addImpl(tickCount, qpcNow); } } private: friend class StatsEventRate; + void addImpl(TickCount tickCount, long long qpcNow); + virtual double convert(double stat) override; long long m_qpcLast; diff --git a/DDrawCompat/Overlay/StatsQueue.cpp b/DDrawCompat/Overlay/StatsQueue.cpp index dca215d..9f96381 100644 --- a/DDrawCompat/Overlay/StatsQueue.cpp +++ b/DDrawCompat/Overlay/StatsQueue.cpp @@ -1,9 +1,14 @@ +#include + #include +#include #include #include namespace { + std::array g_isColumnEnabled = {}; + bool greaterEqual(StatsQueue::Stat a, StatsQueue::Stat b) { return a >= b; @@ -17,9 +22,23 @@ namespace StatsQueueInitializer::StatsQueueInitializer() { + for (auto statsColumnIndex : Config::statsColumns.get()) + { + g_isColumnEnabled[statsColumnIndex] = true; + } + s_update_rate = Config::statsUpdateRate.get(); s_history_time = Config::statsAggregateTime.get(); - s_history_size = s_history_time * s_update_rate; + if (g_isColumnEnabled[Config::Settings::StatsColumns::AVG] || + g_isColumnEnabled[Config::Settings::StatsColumns::MIN] || + g_isColumnEnabled[Config::Settings::StatsColumns::MAX]) + { + s_history_size = s_history_time * s_update_rate; + } + else + { + s_history_size = 1; + } } uint32_t StatsQueueInitializer::s_history_size = 0; @@ -36,6 +55,7 @@ StatsQueue::StatsQueue() , m_max(0) , m_totalSampleCount(0) , m_totalSum(0) + , m_isEnabled(false) { } @@ -71,8 +91,14 @@ StatsQueue::Stats StatsQueue::getRawStats(TickCount tickCount) setTickCount(tickCount); Stats stats = {}; const uint32_t index = (m_currentTickCount - 1) % s_history_size; - stats.cur = getAvg(m_sums[index], m_sampleCounts[index]); - stats.avg = getAvg(m_totalSum, m_totalSampleCount); + if (g_isColumnEnabled[Config::Settings::StatsColumns::CUR]) + { + stats.cur = getAvg(m_sums[index], m_sampleCounts[index]); + } + if (g_isColumnEnabled[Config::Settings::StatsColumns::AVG]) + { + stats.avg = getAvg(m_totalSum, m_totalSampleCount); + } stats.min = m_minQueue.empty() ? NAN : m_minQueue.front().stat; stats.max = m_maxQueue.empty() ? NAN : m_maxQueue.front().stat; return stats; @@ -86,10 +112,22 @@ StatsQueue::SampleCount StatsQueue::getSampleCount(TickCount tickCount) const StatsQueue::Stats StatsQueue::getStats(TickCount tickCount) { Stats stats = getRawStats(tickCount); - stats.cur = convert(stats.cur); - stats.avg = convert(stats.avg); - stats.min = convert(stats.min); - stats.max = convert(stats.max); + if (g_isColumnEnabled[Config::Settings::StatsColumns::CUR]) + { + stats.cur = convert(stats.cur); + } + if (g_isColumnEnabled[Config::Settings::StatsColumns::AVG]) + { + stats.avg = convert(stats.avg); + } + if (g_isColumnEnabled[Config::Settings::StatsColumns::MIN]) + { + stats.min = convert(stats.min); + } + if (g_isColumnEnabled[Config::Settings::StatsColumns::MAX]) + { + stats.max = convert(stats.max); + } return stats; } @@ -105,8 +143,14 @@ void StatsQueue::push() m_sampleCounts[index] = m_sampleCount; m_sums[index] = m_sum; - pushToMinMaxQueue(m_minQueue, m_min, lessEqual); - pushToMinMaxQueue(m_maxQueue, m_max, greaterEqual); + if (g_isColumnEnabled[Config::Settings::StatsColumns::MIN]) + { + pushToMinMaxQueue(m_minQueue, m_min, lessEqual); + } + if (g_isColumnEnabled[Config::Settings::StatsColumns::MAX]) + { + pushToMinMaxQueue(m_maxQueue, m_max, greaterEqual); + } m_sampleCount = 0; m_sum = 0; diff --git a/DDrawCompat/Overlay/StatsQueue.h b/DDrawCompat/Overlay/StatsQueue.h index 9441ea5..589fea7 100644 --- a/DDrawCompat/Overlay/StatsQueue.h +++ b/DDrawCompat/Overlay/StatsQueue.h @@ -35,7 +35,9 @@ public: void addSample(TickCount tickCount, Stat stat); Stats getStats(TickCount tickCount); + void enable() { m_isEnabled = true; } TickCount getCurrentTickCount() const { return m_currentTickCount; } + bool isEnabled() const { return m_isEnabled; } static long long getQpc(TickCount tickCount) { @@ -79,4 +81,5 @@ private: Stat m_max; SampleCount m_totalSampleCount; Stat m_totalSum; + bool m_isEnabled; }; diff --git a/DDrawCompat/Overlay/StatsTimer.cpp b/DDrawCompat/Overlay/StatsTimer.cpp index 11a32c6..8640152 100644 --- a/DDrawCompat/Overlay/StatsTimer.cpp +++ b/DDrawCompat/Overlay/StatsTimer.cpp @@ -36,14 +36,14 @@ void StatsTimer::resetTickCount() m_qpcSum = 0; } -void StatsTimer::start() +void StatsTimer::startImpl() { auto qpcStart = Time::queryPerformanceCounter(); setTickCount(getTickCount(qpcStart)); m_qpcStart = qpcStart; } -void StatsTimer::stop() +void StatsTimer::stopImpl() { auto qpcEnd = Time::queryPerformanceCounter(); setTickCount(getTickCount(qpcEnd)); diff --git a/DDrawCompat/Overlay/StatsTimer.h b/DDrawCompat/Overlay/StatsTimer.h index 9889525..3cc0b34 100644 --- a/DDrawCompat/Overlay/StatsTimer.h +++ b/DDrawCompat/Overlay/StatsTimer.h @@ -7,14 +7,17 @@ class StatsTimer : public StatsQueue public: StatsTimer(); - void start(); - void stop(); + void start() { if (isEnabled()) { startImpl(); } } + void stop() { if (isEnabled()) { stopImpl(); } } private: virtual double convert(double stat) override; virtual void finalize(SampleCount& sampleCount, Stat& sum, Stat& min, Stat& max) override; virtual void resetTickCount() override; + void startImpl(); + void stopImpl(); + long long m_qpcStart; long long m_qpcSum; }; diff --git a/DDrawCompat/Overlay/StatsWindow.cpp b/DDrawCompat/Overlay/StatsWindow.cpp index b5a20a0..8efa7bd 100644 --- a/DDrawCompat/Overlay/StatsWindow.cpp +++ b/DDrawCompat/Overlay/StatsWindow.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -94,34 +93,48 @@ namespace Overlay { 0, 0, getWidth(), static_cast(Config::statsRows.get().size()) * ROW_HEIGHT + BORDER }, 0, Config::statsTransparency.get(), Config::statsHotKey.get()) , m_presentCount(0) + , m_isRowEnabled{} + , m_tickCount(0) { m_statsRows.push_back({ "", [](auto) { return std::array{ "cur", "avg", "min", "max" }; }, - WS_VISIBLE | WS_DISABLED }); - m_statsRows.push_back({ "Present count", UpdateStats(m_present.m_count) }); - m_statsRows.push_back({ "Present rate", UpdateStats(m_present.m_rate) }); - m_statsRows.push_back({ "Present time", UpdateStats(m_present.m_time) }); - m_statsRows.push_back({ "Flip count", UpdateStats(m_flip.m_count) }); - m_statsRows.push_back({ "Flip rate", UpdateStats(m_flip.m_rate) }); - m_statsRows.push_back({ "Flip time", UpdateStats(m_flip.m_time) }); - m_statsRows.push_back({ "Blit count", UpdateStats(m_blit.m_count) }); - m_statsRows.push_back({ "Blit rate", UpdateStats(m_blit.m_rate) }); - m_statsRows.push_back({ "Blit time", UpdateStats(m_blit.m_time) }); - m_statsRows.push_back({ "Lock count", UpdateStats(m_lock.m_count) }); - m_statsRows.push_back({ "Lock rate", UpdateStats(m_lock.m_rate) }); - m_statsRows.push_back({ "Lock time", UpdateStats(m_lock.m_time) }); - m_statsRows.push_back({ "DDI usage", UpdateStats(m_ddiUsage) }); - m_statsRows.push_back({ "GDI objects", UpdateStats(m_gdiObjects) }); - m_statsRows.push_back({ "", &getDebugInfo, WS_VISIBLE | WS_GROUP }); + nullptr, WS_VISIBLE | WS_DISABLED }); + m_statsRows.push_back({ "Present count", UpdateStats(m_present.m_count), &m_present.m_count }); + m_statsRows.push_back({ "Present rate", UpdateStats(m_present.m_rate), &m_present.m_rate }); + m_statsRows.push_back({ "Present time", UpdateStats(m_present.m_time), &m_present.m_time }); + m_statsRows.push_back({ "Flip count", UpdateStats(m_flip.m_count), &m_flip.m_count }); + m_statsRows.push_back({ "Flip rate", UpdateStats(m_flip.m_rate), &m_flip.m_rate }); + m_statsRows.push_back({ "Flip time", UpdateStats(m_flip.m_time), &m_flip.m_time }); + m_statsRows.push_back({ "Blit count", UpdateStats(m_blit.m_count), &m_blit.m_count }); + m_statsRows.push_back({ "Blit rate", UpdateStats(m_blit.m_rate), &m_blit.m_rate }); + m_statsRows.push_back({ "Blit time", UpdateStats(m_blit.m_time), &m_blit.m_time }); + m_statsRows.push_back({ "Lock count", UpdateStats(m_lock.m_count), &m_lock.m_count }); + m_statsRows.push_back({ "Lock rate", UpdateStats(m_lock.m_rate), &m_lock.m_rate }); + m_statsRows.push_back({ "Lock time", UpdateStats(m_lock.m_time), &m_lock.m_time }); + m_statsRows.push_back({ "DDI usage", UpdateStats(m_ddiUsage), &m_ddiUsage }); + m_statsRows.push_back({ "GDI objects", UpdateStats(m_gdiObjects), &m_gdiObjects }); + m_statsRows.push_back({ "", &getDebugInfo, nullptr, WS_VISIBLE | WS_GROUP }); for (auto statsRowIndex : Config::statsRows.get()) { auto& statsRow = m_statsRows[statsRowIndex]; auto& statsControl = addControl(statsRow.name, statsRow.updateFunc, statsRow.style); + + m_isRowEnabled[statsRowIndex] = true; + if (statsRow.statsQueue) + { + statsRow.statsQueue->enable(); + } + if (statsRow.style & WS_DISABLED) { statsControl.update(0); } } + + m_present.enable(); + m_flip.enable(); + m_blit.enable(); + m_lock.enable(); } StatsControl& StatsWindow::addControl(const std::string& name, StatsControl::UpdateFunc updateFunc, DWORD style) @@ -163,17 +176,24 @@ namespace Overlay m_tickCount = StatsQueue::getTickCount(); if (m_tickCount == prevTickCount) { - for (auto& statsControl : m_statsControls) + if (isRowEnabled(Config::Settings::StatsRows::DEBUG)) { - if (statsControl.getStyle() & WS_GROUP) + for (auto& statsControl : m_statsControls) { - statsControl.update(m_tickCount); + if (statsControl.getStyle() & WS_GROUP) + { + statsControl.update(m_tickCount); + } } } return; } - m_gdiObjects.addSample(m_tickCount, GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS)); + if (isRowEnabled(Config::Settings::StatsRows::GDIOBJECTS)) + { + m_gdiObjects.addSample(m_tickCount, GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS)); + } + for (auto& statsControl : m_statsControls) { if (statsControl.isEnabled()) diff --git a/DDrawCompat/Overlay/StatsWindow.h b/DDrawCompat/Overlay/StatsWindow.h index 12c88cf..ec17817 100644 --- a/DDrawCompat/Overlay/StatsWindow.h +++ b/DDrawCompat/Overlay/StatsWindow.h @@ -1,10 +1,12 @@ #pragma once +#include #include #include #include #include +#include #include #include #include @@ -18,6 +20,7 @@ namespace Overlay public: StatsWindow(); + bool isRowEnabled(Config::Settings::StatsRows::Values row) const { return m_isRowEnabled[row]; } void updateStats(); uint32_t m_presentCount; @@ -33,6 +36,7 @@ namespace Overlay { const char* name; StatsControl::UpdateFunc updateFunc; + StatsQueue* statsQueue; DWORD style; }; @@ -43,6 +47,7 @@ namespace Overlay static LONG getWidth(); + std::array m_isRowEnabled; std::list m_statsControls; std::vector m_statsRows; uint64_t m_tickCount;