9e474de717
- switchGpu切换前写入备份文件(.gpu-switch-backup)记录之前模式 - init()检测未确认的切换,启动30秒自动回退计时器 - QML弹出'显示是否正常'确认覆盖层,支持手动确认/回退/超时自动回退 - confirmSwitchSuccess()用户确认正常后删除备份 - restoreFromBackup()自动恢复之前模式并发送通知 - primeOffloadEnabled属性检测当前PRIME offload状态 - switchGpu改用environment.d方式,不需要root/pkexec - 翻译更新:回退确认相关8条新增
133 lines
4.7 KiB
C++
133 lines
4.7 KiB
C++
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
|
||
//
|
||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||
|
||
#pragma once
|
||
|
||
#include <applet.h>
|
||
|
||
#include <QString>
|
||
#include <QStringList>
|
||
#include <QTimer>
|
||
#include <QVariantList>
|
||
|
||
DS_BEGIN_NAMESPACE
|
||
|
||
struct GpuInfo {
|
||
QString name; // 显卡名称,如 "NVIDIA GeForce RTX 3060"
|
||
QString driver; // 驱动模块名,如 "nvidia"
|
||
QString driverVersion; // 驱动版本
|
||
QString pciId; // PCI ID,如 "01:00.0"
|
||
int drmCard; // DRM 卡号,如 0, 1(-1 表示未找到)
|
||
bool isPrimary; // 是否为主显卡(boot_vga=1)
|
||
|
||
// 实时统计
|
||
int temperature; // 温度 (°C),-1 表示不可用
|
||
int gpuUsage; // GPU 使用率 (%),-1 表示不可用
|
||
int memUsage; // 显存使用率 (%),-1 表示不可用
|
||
int memTotal; // 显存总量 (MB),-1 表示不可用
|
||
int memUsed; // 显存已用 (MB),-1 表示不可用
|
||
int gpuClock; // GPU 频率 (MHz),-1 表示不可用
|
||
int memClock; // 显存频率 (MHz),-1 表示不可用
|
||
double powerDraw; // 功耗 (W),-1 表示不可用
|
||
int fanSpeed; // 风扇转速 (%),-1 表示不可用
|
||
};
|
||
|
||
class GraphicsDriverApplet : public DApplet
|
||
{
|
||
Q_OBJECT
|
||
|
||
Q_PROPERTY(QString deviceInfo READ deviceInfo NOTIFY deviceInfoChanged)
|
||
Q_PROPERTY(QString currentDriver READ currentDriver NOTIFY currentDriverChanged)
|
||
Q_PROPERTY(QString gpuSummary READ gpuSummary NOTIFY gpuSummaryChanged)
|
||
Q_PROPERTY(QStringList gpuStats READ gpuStats NOTIFY gpuStatsChanged)
|
||
Q_PROPERTY(QString gpuMode READ gpuMode NOTIFY gpuModeChanged)
|
||
Q_PROPERTY(QStringList gpuPrimary READ gpuPrimary NOTIFY gpuPrimaryChanged)
|
||
Q_PROPERTY(bool ready READ ready NOTIFY readyChanged)
|
||
Q_PROPERTY(QVariantList tempHistory READ tempHistory NOTIFY tempHistoryChanged)
|
||
Q_PROPERTY(QStringList gpuProcesses READ gpuProcesses NOTIFY gpuProcessesChanged)
|
||
Q_PROPERTY(bool tempAlertEnabled READ tempAlertEnabled WRITE setTempAlertEnabled NOTIFY tempAlertEnabledChanged)
|
||
Q_PROPERTY(bool primeOffloadEnabled READ primeOffloadEnabled NOTIFY primeOffloadEnabledChanged)
|
||
Q_PROPERTY(bool switchPending READ switchPending NOTIFY switchPendingChanged)
|
||
Q_PROPERTY(int restoreCountdown READ restoreCountdown NOTIFY restoreCountdownChanged)
|
||
|
||
public:
|
||
explicit GraphicsDriverApplet(QObject *parent = nullptr);
|
||
~GraphicsDriverApplet();
|
||
|
||
virtual bool load() override;
|
||
virtual bool init() override;
|
||
|
||
QString deviceInfo() const;
|
||
QString currentDriver() const;
|
||
QString gpuSummary() const;
|
||
QStringList gpuStats() const;
|
||
QString gpuMode() const;
|
||
QStringList gpuPrimary() const;
|
||
bool ready() const;
|
||
QVariantList tempHistory() const;
|
||
QStringList gpuProcesses() const;
|
||
bool tempAlertEnabled() const;
|
||
void setTempAlertEnabled(bool enabled);
|
||
bool primeOffloadEnabled() const;
|
||
bool switchPending() const;
|
||
int restoreCountdown() const;
|
||
|
||
Q_INVOKABLE void refreshDeviceInfo();
|
||
Q_INVOKABLE void refreshStats();
|
||
Q_INVOKABLE bool switchGpu(const QString &mode);
|
||
Q_INVOKABLE void confirmSwitchSuccess();
|
||
Q_INVOKABLE void restoreSwitch();
|
||
|
||
signals:
|
||
void deviceInfoChanged();
|
||
void currentDriverChanged();
|
||
void gpuSummaryChanged();
|
||
void gpuStatsChanged();
|
||
void gpuModeChanged();
|
||
void gpuPrimaryChanged();
|
||
void readyChanged();
|
||
void tempHistoryChanged();
|
||
void gpuProcessesChanged();
|
||
void tempAlertEnabledChanged();
|
||
void primeOffloadEnabledChanged();
|
||
void switchPendingChanged();
|
||
void restoreCountdownChanged();
|
||
|
||
private:
|
||
void detectGpus();
|
||
void readGpuStats();
|
||
void readGpuProcesses();
|
||
void detectGpuMode();
|
||
void checkTempAlert();
|
||
void sendNotification(const QString &summary, const QString &body);
|
||
void restoreFromBackup();
|
||
static QString primeConfigPath();
|
||
static QString backupFilePath();
|
||
static int findDrmCard(const QString &pciId);
|
||
static QStringList runCommand(const QString &cmd, const QStringList &args);
|
||
static QString parseGpuName(const QString &line);
|
||
static QString readDriverVersion(const QString &driverName);
|
||
|
||
QList<GpuInfo> m_gpus;
|
||
QString m_deviceInfo;
|
||
QString m_currentDriver;
|
||
QString m_gpuSummary;
|
||
QStringList m_gpuStats;
|
||
QString m_gpuMode;
|
||
QStringList m_gpuPrimary;
|
||
bool m_ready;
|
||
// 温度历史:每个 GPU 保留最近 60 个温度采样
|
||
QVector<QList<int>> m_tempHistory;
|
||
// NVIDIA 进程列表:每行 "pid|name|usedMemory"
|
||
QStringList m_gpuProcesses;
|
||
// 温度告警冷却时间戳
|
||
qint64 m_lastAlertTime;
|
||
bool m_tempAlertEnabled;
|
||
bool m_switchPending;
|
||
int m_restoreCountdown;
|
||
QTimer *m_restoreTimer;
|
||
};
|
||
|
||
DS_END_NAMESPACE
|