Show detailed CPU load information in a tool-tip (#5970)
* Profiler rework * Workaround for GCC bug * Rollback QFile removal * Use enum instead of a plain index to describe detailed stats * Use the GCC workaround code for all compilers to avoid redundancy * Update and fix comments * Implement suggestions from review * Split AudioEngine::renderNextBuffer() into separate functions, fix old formatting * Remove QFile include * Revert formatting changes * Apply suggestion from review (remove unnecessary template parameter) * Revert more formatting changes * Convert DetailType to enum class * DetailType enum class improvements suggested in review * Use std::atomic for m_detailLoad * RAII-style profiler probes * Apply suggestions from code review Co-authored-by: Dominic Clark <mrdomclark@gmail.com> * Fix namespace comment * Improve CPU load widget precision and use floats for load computations * Atomic m_cpuLoad * Add custom step size support for CPULoadWidget * Apply suggestions from review (convert the profiler probe into a nested class, other small changes) * Do not limit stored load averages to 100% --------- Co-authored-by: sakertooth <sakertooth@gmail.com> Co-authored-by: Dominic Clark <mrdomclark@gmail.com>
This commit is contained in:
@@ -275,6 +275,11 @@ public:
|
||||
return m_profiler.cpuLoad();
|
||||
}
|
||||
|
||||
int detailLoad(const AudioEngineProfiler::DetailType type) const
|
||||
{
|
||||
return m_profiler.detailLoad(type);
|
||||
}
|
||||
|
||||
const qualitySettings & currentQualitySettings() const
|
||||
{
|
||||
return m_qualitySettings;
|
||||
@@ -401,6 +406,10 @@ private:
|
||||
AudioDevice * tryAudioDevices();
|
||||
MidiClient * tryMidiClients();
|
||||
|
||||
void renderStageNoteSetup();
|
||||
void renderStageInstruments();
|
||||
void renderStageEffects();
|
||||
void renderStageMix();
|
||||
|
||||
const surroundSampleFrame * renderNextBuffer();
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#ifndef LMMS_AUDIO_ENGINE_PROFILER_H
|
||||
#define LMMS_AUDIO_ENGINE_PROFILER_H
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <QFile>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
@@ -53,11 +55,55 @@ public:
|
||||
|
||||
void setOutputFile( const QString& outputFile );
|
||||
|
||||
enum class DetailType {
|
||||
NoteSetup,
|
||||
Instruments,
|
||||
Effects,
|
||||
Mixing,
|
||||
Count
|
||||
};
|
||||
|
||||
constexpr static auto DetailCount = static_cast<std::size_t>(DetailType::Count);
|
||||
|
||||
int detailLoad(const DetailType type) const
|
||||
{
|
||||
return m_detailLoad[static_cast<std::size_t>(type)].load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
class Probe
|
||||
{
|
||||
public:
|
||||
Probe(AudioEngineProfiler& profiler, AudioEngineProfiler::DetailType type)
|
||||
: m_profiler(profiler)
|
||||
, m_type(type)
|
||||
{
|
||||
profiler.startDetail(type);
|
||||
}
|
||||
~Probe() { m_profiler.finishDetail(m_type); }
|
||||
Probe& operator=(const Probe&) = delete;
|
||||
Probe(const Probe&) = delete;
|
||||
Probe(Probe&&) = delete;
|
||||
|
||||
private:
|
||||
AudioEngineProfiler &m_profiler;
|
||||
const AudioEngineProfiler::DetailType m_type;
|
||||
};
|
||||
|
||||
private:
|
||||
void startDetail(const DetailType type) { m_detailTimer[static_cast<std::size_t>(type)].reset(); }
|
||||
void finishDetail(const DetailType type)
|
||||
{
|
||||
m_detailTime[static_cast<std::size_t>(type)] = m_detailTimer[static_cast<std::size_t>(type)].elapsed();
|
||||
}
|
||||
|
||||
MicroTimer m_periodTimer;
|
||||
int m_cpuLoad;
|
||||
std::atomic<float> m_cpuLoad;
|
||||
QFile m_outputFile;
|
||||
|
||||
// Use arrays to avoid dynamic allocations in realtime code
|
||||
std::array<MicroTimer, DetailCount> m_detailTimer;
|
||||
std::array<int, DetailCount> m_detailTime{0};
|
||||
std::array<std::atomic<float>, DetailCount> m_detailLoad{0};
|
||||
};
|
||||
|
||||
} // namespace lmms
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#ifndef LMMS_GUI_CPU_LOAD_WIDGET_H
|
||||
#define LMMS_GUI_CPU_LOAD_WIDGET_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <QTimer>
|
||||
#include <QPixmap>
|
||||
#include <QWidget>
|
||||
@@ -40,6 +41,7 @@ namespace lmms::gui
|
||||
class CPULoadWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int stepSize MEMBER m_stepSize)
|
||||
public:
|
||||
CPULoadWidget( QWidget * _parent );
|
||||
~CPULoadWidget() override = default;
|
||||
@@ -54,6 +56,8 @@ protected slots:
|
||||
|
||||
|
||||
private:
|
||||
int stepSize() const { return std::max(1, m_stepSize); }
|
||||
|
||||
int m_currentLoad;
|
||||
|
||||
QPixmap m_temp;
|
||||
@@ -64,6 +68,8 @@ private:
|
||||
|
||||
QTimer m_updateTimer;
|
||||
|
||||
int m_stepSize;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user