Browse Source

UI: Update volume controls by callback

Gets rid of the time-critical timeSetEvent thread on Windows.
jpark37 4 năm trước cách đây
mục cha
commit
0a3cd8fbf6
2 tập tin đã thay đổi với 25 bổ sung8 xóa
  1. 19 3
      UI/volume-control.cpp
  2. 6 5
      UI/volume-control.hpp

+ 19 - 3
UI/volume-control.cpp

@@ -601,8 +601,6 @@ VolumeMeter::VolumeMeter(QWidget *parent, obs_volmeter_t *obs_volmeter,
 	updateTimerRef = updateTimer.toStrongRef();
 	if (!updateTimerRef) {
 		updateTimerRef = QSharedPointer<VolumeMeterTimer>::create();
-		updateTimerRef->setTimerType(Qt::PreciseTimer);
-		updateTimerRef->start(16);
 		updateTimer = updateTimerRef;
 	}
 
@@ -633,6 +631,8 @@ void VolumeMeter::setLevels(const float magnitude[MAX_AUDIO_CHANNELS],
 	// that the ballistics of peak and hold are recalculated.
 	locker.unlock();
 	calculateBallistics(ts);
+
+	updateTimerRef->SignalUpdate();
 }
 
 inline void VolumeMeter::resetLevels()
@@ -1141,7 +1141,23 @@ void VolumeMeterTimer::RemoveVolControl(VolumeMeter *meter)
 	volumeMeters.removeOne(meter);
 }
 
-void VolumeMeterTimer::timerEvent(QTimerEvent *)
+void VolumeMeterTimer::SignalUpdate()
+{
+	const uint64_t current = os_gettime_ns();
+	uint64_t previous = lastUpdate.load();
+	uint64_t next = previous + 16666666;
+	if (current > next) {
+		if (current - next > 100000000) {
+			next = current;
+		}
+
+		if (lastUpdate.compare_exchange_strong(previous, next)) {
+			QMetaObject::invokeMethod(this, "UpdateMeters");
+		}
+	}
+}
+
+void VolumeMeterTimer::UpdateMeters()
 {
 	for (VolumeMeter *meter : volumeMeters)
 		meter->update();

+ 6 - 5
UI/volume-control.hpp

@@ -4,7 +4,6 @@
 #include <QWidget>
 #include <QPaintEvent>
 #include <QSharedPointer>
-#include <QTimer>
 #include <QMutex>
 #include <QList>
 #include <QMenu>
@@ -186,18 +185,20 @@ protected:
 	void paintEvent(QPaintEvent *event) override;
 };
 
-class VolumeMeterTimer : public QTimer {
+class VolumeMeterTimer : public QObject {
 	Q_OBJECT
 
 public:
-	inline VolumeMeterTimer() : QTimer() {}
-
 	void AddVolControl(VolumeMeter *meter);
 	void RemoveVolControl(VolumeMeter *meter);
+	void SignalUpdate();
+
+protected slots:
+	void UpdateMeters();
 
 protected:
-	void timerEvent(QTimerEvent *event) override;
 	QList<VolumeMeter *> volumeMeters;
+	std::atomic<uint64_t> lastUpdate = 0;
 };
 
 class QLabel;