docs: 更新README和设计文档
- README: 移除已废弃的D-Bus接口和依赖,更新为当前实际功能 - README: 添加数据采集方式对比表、QML属性接口文档、安装方式 - 新增 docs/GPU_SWITCH_AND_DRIVER_INSTALL.md: 显卡切换和驱动安装设计方案
This commit is contained in:
@@ -1,53 +1,100 @@
|
||||
# 显卡切换任务栏插件
|
||||
# GPU 显卡驱动管理任务栏插件
|
||||
|
||||
Deepin显卡驱动管理任务栏插件,集成到DDE Shell任务栏中,提供显卡设备检测、驱动安装和切换功能。
|
||||
Deepin V25 DDE Shell 任务栏插件,实时检测 GPU 设备、显示驱动信息和温度/使用率监控。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- 自动检测系统显卡设备
|
||||
- 显示当前安装的驱动版本
|
||||
- 列出可用的驱动版本
|
||||
- 一键切换显卡驱动
|
||||
- 实时显示安装进度
|
||||
- 安装完成后提示重启
|
||||
- **GPU 设备检测** - 通过 `lspci` + `sysfs` 检测所有显卡(NVIDIA/AMD/Intel)
|
||||
- **驱动信息显示** - 驱动模块名 + 版本号(NVIDIA 用 nvidia-smi/proc,AMD 用内核版本)
|
||||
- **实时温度监控** - NVIDIA 用 `nvidia-smi`,AMD 用 `hwmon`,2 秒自动刷新
|
||||
- **GPU 使用率** - 进度条显示,NVIDIA 用 `nvidia-smi`,AMD 用 `gpu_busy_percent`
|
||||
- **显存使用** - 已用/总量 (MB),带使用率百分比
|
||||
- **主副显标识** - 通过 `boot_vga` 区分主显卡(绿色"主显"标签)
|
||||
- **GPU 切换模式检测** - 自动识别 PRIME / Bumblebee / Solo / Hybrid 模式
|
||||
- **国际化** - 支持简体中文、繁体中文、英文
|
||||
|
||||
## 截图
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ GPU 显卡驱动管理 │
|
||||
│─────────────────────────────────────│
|
||||
│ 当前驱动: nvidia, amdgpu [PRIME] │
|
||||
│─────────────────────────────────────│
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ NV NVIDIA GeForce RTX 3060 主显│ │
|
||||
│ │ nvidia 580.119.02 │ │
|
||||
│ │ 54°C 108/6144 MB │ │
|
||||
│ │ GPU ████░░░░░░ 36% │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ AMD AMD Radeon Vega │ │
|
||||
│ │ amdgpu Linux 6.18.36 │ │
|
||||
│ │ 90°C 471/512 MB │ │
|
||||
│ │ GPU ████████░░ 71% │ │
|
||||
│ └─────────────────────────────────┘ │
|
||||
│ [ 刷新 ] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 依赖项
|
||||
|
||||
- Qt6 >= 6.0
|
||||
- Dtk6 Core
|
||||
- deepin-graphics-driver-manager(运行时依赖)
|
||||
### 构建依赖
|
||||
|
||||
```
|
||||
cmake (>= 3.16)
|
||||
g++
|
||||
qt6-base-dev
|
||||
qt6-l10n-tools # lrelease 翻译编译
|
||||
libdde-shell-dev # DDE Shell 插件头文件
|
||||
libdtk6core-dev # DTK6 Core
|
||||
```
|
||||
|
||||
### 运行时依赖
|
||||
|
||||
```
|
||||
dde-shell # 任务栏宿主
|
||||
lspci # GPU 检测(pciutils 包)
|
||||
nvidia-smi # NVIDIA 监控(可选,nvidia-driver 包自带)
|
||||
```
|
||||
|
||||
## 构建
|
||||
|
||||
```bash
|
||||
# 安装构建依赖
|
||||
sudo apt install -y cmake g++ qt6-base-dev qt6-tools-dev libdtk6core-dev
|
||||
sudo apt install -y cmake g++ qt6-base-dev qt6-l10n-tools libdde-shell-dev libdtk6core-dev
|
||||
|
||||
# 构建项目
|
||||
# 构建
|
||||
cmake -Bbuild
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
# 安装插件到系统(deepin v25需关闭磐石)
|
||||
sudo cmake --install build
|
||||
### 方式一:一键脚本
|
||||
|
||||
# 重启任务栏加载插件
|
||||
```bash
|
||||
bash install.sh
|
||||
```
|
||||
|
||||
### 方式二:手动安装
|
||||
|
||||
```bash
|
||||
sudo cmake --install build
|
||||
systemctl --user restart dde-shell@DDE
|
||||
```
|
||||
|
||||
或者注销并重新登录。
|
||||
### 方式三:deb 包
|
||||
|
||||
```bash
|
||||
bash build-deb.sh --install
|
||||
```
|
||||
|
||||
## 卸载
|
||||
|
||||
```bash
|
||||
# 卸载插件
|
||||
sudo rm -f /usr/lib/x86_64-linux-gnu/dde-shell/libdde-graphics-driver.so
|
||||
sudo rm -rf /usr/lib/x86_64-linux-gnu/dde-shell/org.deepin.ds.graphics-driver
|
||||
|
||||
# 重启任务栏
|
||||
sudo rm -f /usr/lib/x86_64-linux-gnu/dde-shell/org.deepin.ds.graphics-driver.so
|
||||
sudo rm -rf /usr/share/dde-shell/org.deepin.ds.graphics-driver
|
||||
systemctl --user restart dde-shell@DDE
|
||||
```
|
||||
|
||||
@@ -55,73 +102,90 @@ systemctl --user restart dde-shell@DDE
|
||||
|
||||
```
|
||||
├── package/
|
||||
│ ├── metadata.json # 插件元数据
|
||||
│ └── driverview.qml # QML界面
|
||||
├── graphicsdriverapplet.h # 主插件类头文件
|
||||
├── graphicsdriverapplet.cpp # 主插件类实现
|
||||
├── gpuindicator.h # GPU指示器类头文件
|
||||
├── gpuindicator.cpp # GPU指示器类实现
|
||||
├── debian/ # Debian打包文件
|
||||
├── CMakeLists.txt # 构建配置
|
||||
└── README.md # 项目说明
|
||||
│ ├── metadata.json # 插件元数据(ID、父插件、dockOrder)
|
||||
│ └── driverview.qml # QML 界面(弹窗、卡片、tooltip)
|
||||
├── translations/
|
||||
│ ├── *_zh_CN.ts # 简体中文翻译
|
||||
│ └── *_zh_TW.ts # 繁体中文翻译
|
||||
├── graphicsdriverapplet.h # C++ 插件类头文件
|
||||
├── graphicsdriverapplet.cpp # C++ 插件类实现
|
||||
├── debian/ # Debian 打包配置
|
||||
├── docs/ # 设计文档
|
||||
│ └── GPU_SWITCH_AND_DRIVER_INSTALL.md
|
||||
├── CMakeLists.txt # 构建配置
|
||||
├── install.sh # 一键构建安装脚本
|
||||
├── build-deb.sh # 一键 deb 打包脚本
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## 技术实现
|
||||
|
||||
### 架构设计
|
||||
### 架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ DDE Shell Taskbar │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ dde-graphics-driver-applet │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ GPU检测模块 │ │ 驱动管理 │ │ UI界面 │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ D-Bus Interface │
|
||||
│ com.deepin.daemon.GraphicsDriver │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ deepin-graphics-driver-manager │
|
||||
│ (现有的驱动管理服务,无需修改) │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
┌──────────────────────────────────────────────┐
|
||||
│ DDE Shell Taskbar │
|
||||
├──────────────────────────────────────────────┤
|
||||
│ org.deepin.ds.graphics-driver │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
|
||||
│ │ GPU 检测 │ │ 实时监控 │ │ QML UI │ │
|
||||
│ │ lspci │ │ nvidia-smi│ │ 卡片 │ │
|
||||
│ │ sysfs │ │ hwmon │ │ tooltip │ │
|
||||
│ │ boot_vga │ │ drm │ │ 进度条 │ │
|
||||
│ └──────────┘ └──────────┘ └───────────┘ │
|
||||
└──────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### D-Bus接口
|
||||
### 数据采集方式
|
||||
|
||||
插件通过D-Bus与deepin-graphics-driver-manager服务通信:
|
||||
| 数据 | NVIDIA | AMD/Intel |
|
||||
|------|--------|-----------|
|
||||
| GPU 检测 | `lspci -mm` | `lspci -mm` |
|
||||
| 驱动名 | `/sys/bus/pci/.../driver` symlink | 同左 |
|
||||
| 驱动版本 | `/proc/driver/nvidia/version` | `/proc/sys/kernel/osrelease` |
|
||||
| 温度 | `nvidia-smi` | `/sys/class/hwmon/hwmonN/temp1_input` |
|
||||
| GPU 使用率 | `nvidia-smi` | `/sys/class/drm/cardN/device/gpu_busy_percent` |
|
||||
| 显存 | `nvidia-smi` | `/sys/class/drm/cardN/device/mem_info_vram_*` |
|
||||
| 主副显 | `/sys/bus/pci/.../boot_vga` | 同左 |
|
||||
| 切换模式 | `nvidia-drm-outputclass.conf` 检测 | - |
|
||||
|
||||
- `GetDevice()` - 获取显卡设备信息
|
||||
- `GetCurrDriverName()` - 获取当前驱动名称
|
||||
- `GetNewDriverName()` - 获取推荐驱动名称
|
||||
- `PrepareInstall(name, language)` - 准备安装驱动
|
||||
- `TestInstall()` - 测试安装
|
||||
- `RealInstall()` - 实际安装
|
||||
- `CancelInstall()` - 取消安装
|
||||
### QML 属性接口
|
||||
|
||||
### 信号
|
||||
|
||||
- `ReportProgress(ratio)` - 安装进度报告
|
||||
- `Cancel()` - 安装取消通知
|
||||
| 属性 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `applet.ready` | bool | GPU 检测完成 |
|
||||
| `applet.deviceInfo` | QString | GPU 信息(每行一个) |
|
||||
| `applet.currentDriver` | QString | 当前驱动列表 |
|
||||
| `applet.gpuSummary` | QString | GPU 摘要 |
|
||||
| `applet.gpuStats` | QStringList | 实时统计(temp\|gpu\|mem\|used\|total) |
|
||||
| `applet.gpuMode` | QString | 切换模式(PRIME/Bumblebee/Solo/Hybrid) |
|
||||
| `applet.gpuPrimary` | QStringList | 主副显标识(true/false) |
|
||||
| `applet.refreshStats()` | void | 刷新实时统计 |
|
||||
| `applet.refreshDeviceInfo()` | void | 重新检测 GPU |
|
||||
|
||||
## 使用说明
|
||||
|
||||
1. 插件安装后会自动加载到任务栏
|
||||
2. 点击任务栏图标打开驱动管理界面
|
||||
3. 查看当前显卡设备和驱动信息
|
||||
4. 选择要切换的驱动版本
|
||||
5. 确认后开始安装过程
|
||||
6. 安装完成后选择重启系统
|
||||
1. 插件安装后自动加载到任务栏右侧
|
||||
2. **悬停**任务栏图标 - 显示 GPU 温度和使用率摘要
|
||||
3. **点击**图标 - 打开弹窗,查看详细 GPU 信息
|
||||
4. 弹窗内数据每 2 秒自动刷新
|
||||
5. **悬停**卡片 - 显示该 GPU 的驱动详情 tooltip
|
||||
6. **点击刷新** - 重新检测 GPU 设备
|
||||
|
||||
## 开发计划
|
||||
|
||||
- [x] GPU 检测与驱动信息显示
|
||||
- [x] 温度/使用率/显存实时监控
|
||||
- [x] 主副显标识与 GPU 模式检测
|
||||
- [ ] PRIME 显卡切换(全局开关)
|
||||
- [ ] 驱动安装(pkexec + apt)
|
||||
|
||||
详见 [设计方案文档](docs/GPU_SWITCH_AND_DRIVER_INSTALL.md)
|
||||
|
||||
## 许可证
|
||||
|
||||
GPL-3.0-or-later
|
||||
|
||||
## 贡献
|
||||
|
||||
欢迎提交Issue和Pull Request。
|
||||
|
||||
## 相关项目
|
||||
|
||||
- [dde-shell](https://github.com/linuxdeepin/dde-shell) - Deepin Shell插件系统
|
||||
- [deepin-graphics-driver-manager](https://github.com/linuxdeepin/deepin-graphics-driver-manager) - 显卡驱动管理器
|
||||
- [dde-shell](https://github.com/linuxdeepin/dde-shell) - Deepin Shell 插件系统
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
# 显卡切换与驱动安装设计方案
|
||||
|
||||
## 背景
|
||||
|
||||
当前插件已实现 GPU 检测、温度/使用率监控、主副显标识和 GPU 模式检测。
|
||||
本文档描述后续两个功能的架构方案:**显卡切换** 和 **驱动安装**。
|
||||
|
||||
---
|
||||
|
||||
## 一、显卡切换(PRIME Render Offload)
|
||||
|
||||
### 1.1 原理
|
||||
|
||||
Linux 双 GPU 笔记本(核显+独显)通过 PRIME Render Offload 实现按需渲染:
|
||||
|
||||
- 核显(AMD/Intel)负责日常显示输出
|
||||
- 独显(NVIDIA)按需渲染 3D 应用
|
||||
- 通过环境变量控制渲染 GPU:
|
||||
- `__NV_PRIME_RENDER_OFFLOAD=1` - 启用 NVIDIA offload
|
||||
- `__GLX_VENDOR_LIBRARY_NAME=nvidia` - 指定 OpenGL 实现为 NVIDIA
|
||||
|
||||
### 1.2 系统现状
|
||||
|
||||
| 检测项 | 当前状态 |
|
||||
|--------|---------|
|
||||
| PRIME 配置文件 | `/usr/share/X11/xorg.conf.d/nvidia-drm-outputclass.conf` 存在 |
|
||||
| prime-select 工具 | 不存在 |
|
||||
| nvidia-prime 包 | 未安装 |
|
||||
| boot_vga | AMD=1(主显),NVIDIA=0(副显) |
|
||||
| 当前渲染器 | AMD Radeon(核显主渲染) |
|
||||
|
||||
### 1.3 方案设计
|
||||
|
||||
#### 方案 A:全局开关(推荐先实现)
|
||||
|
||||
**原理**:通过 `~/.config/environment.d/` 设置全局环境变量,重新登录后生效。
|
||||
|
||||
**实现**:
|
||||
- 插件弹窗中添加 PRIME 开关按钮
|
||||
- 开启时写入 `~/.config/environment.d/nvidia-prime.conf`:
|
||||
```ini
|
||||
__NV_PRIME_RENDER_OFFLOAD=1
|
||||
__GLX_VENDOR_LIBRARY_NAME=nvidia
|
||||
```
|
||||
- 关闭时删除该文件
|
||||
- 不需要 root 权限
|
||||
- 需要重新登录生效,UI 上提示用户
|
||||
|
||||
**优点**:不需要 root,实现简单,全局生效
|
||||
**缺点**:需要重新登录
|
||||
|
||||
#### 方案 B:按应用启动
|
||||
|
||||
**原理**:提供快捷方式,设置环境变量后启动指定应用。
|
||||
|
||||
**实现**:
|
||||
- 任务栏右键菜单添加"用独显启动"选项
|
||||
- 弹出应用选择器或输入命令
|
||||
- 执行 `__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia <command>`
|
||||
- 即时生效,不影响全局
|
||||
|
||||
**优点**:即时生效,不影响全局
|
||||
**缺点**:需要手动选择应用
|
||||
|
||||
#### 方案 C:两者结合(最终目标)
|
||||
|
||||
同时提供全局开关和按应用启动,用户可选择使用方式。
|
||||
|
||||
### 1.4 实现计划
|
||||
|
||||
1. C++ 后端新增 `primeEnabled` 属性和 `togglePrime(bool)` 方法
|
||||
2. C++ 后端读写 `~/.config/environment.d/nvidia-prime.conf`
|
||||
3. QML 弹窗中添加 PRIME 开关控件
|
||||
4. 开关状态变更后提示"需要重新登录生效"
|
||||
5. (后续)右键菜单添加"用独显启动应用"
|
||||
|
||||
### 1.5 数据接口
|
||||
|
||||
```cpp
|
||||
// 新增属性
|
||||
Q_PROPERTY(bool primeEnabled READ primeEnabled NOTIFY primeEnabledChanged)
|
||||
|
||||
// 新增方法
|
||||
Q_INVOKABLE void togglePrime(bool enabled);
|
||||
|
||||
// primeEnabled 获取逻辑
|
||||
// 1. 检查 ~/.config/environment.d/nvidia-prime.conf 是否存在
|
||||
// 2. 检查文件内容是否包含 __NV_PRIME_RENDER_OFFLOAD=1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、驱动安装
|
||||
|
||||
### 2.1 原理
|
||||
|
||||
驱动安装需要 root 权限执行 `apt install/remove`,核心问题是如何从任务栏插件(普通用户)安全地获取特权。
|
||||
|
||||
### 2.2 系统现状
|
||||
|
||||
| 检测项 | 当前状态 |
|
||||
|--------|---------|
|
||||
| deepin-graphics-driver-manager | 未安装 |
|
||||
| D-Bus 驱动管理服务 | 不存在 |
|
||||
| pkexec | 可用 (`/usr/bin/pkexec`) |
|
||||
| polkit apt 策略 | `com.deepin.pkexec.aptInstallDepend.policy` 存在 |
|
||||
| nvidia-driver 包 | 已安装,版本 580.119.02 |
|
||||
|
||||
### 2.3 方案对比
|
||||
|
||||
| 方案 | 实现 | 优点 | 缺点 |
|
||||
|------|------|------|------|
|
||||
| **A. pkexec + apt(推荐)** | pkexec 弹授权框执行 apt | 简单直接,无需额外服务 | 每次操作需授权 |
|
||||
| **B. D-Bus 系统服务** | 创建 systemd 服务暴露接口 | 规范,可记住授权 | 工作量大,需额外包 |
|
||||
| **C. 复用 deepin-graphics-driver-manager** | 安装该包调用其接口 | 功能最全 | V25 兼容性未知 |
|
||||
|
||||
### 2.4 推荐方案:pkexec + apt
|
||||
|
||||
#### 流程
|
||||
|
||||
```
|
||||
用户点击"安装驱动"
|
||||
↓
|
||||
插件检测可安装的驱动包列表 (apt list nvidia-driver*)
|
||||
↓
|
||||
用户选择驱动版本
|
||||
↓
|
||||
pkexec apt install -y nvidia-driver-xxx
|
||||
↓
|
||||
polkit 弹出密码授权框
|
||||
↓
|
||||
用户输入密码
|
||||
↓
|
||||
apt 执行安装
|
||||
↓
|
||||
插件显示安装结果
|
||||
```
|
||||
|
||||
#### 实现细节
|
||||
|
||||
1. **驱动状态检测**:
|
||||
- 已安装:读取 `/sys/module/nvidia/version` 或 `/proc/driver/nvidia/version`
|
||||
- 可用版本:`apt list nvidia-driver* 2>/dev/null`
|
||||
- 加载状态:`lsmod | grep nvidia`
|
||||
|
||||
2. **安装/卸载**:
|
||||
- 创建 helper 脚本 `/usr/share/dde-shell/org.deepin.ds.graphics-driver/scripts/install-driver.sh`
|
||||
- 脚本接收包名参数,执行 apt install/remove
|
||||
- 插件通过 `pkexec` 调用该脚本
|
||||
- 利用系统已有的 `com.deepin.pkexec.aptInstallDepend.policy` polkit 策略
|
||||
|
||||
3. **进度显示**:
|
||||
- pkexec 执行期间显示"安装中..."状态
|
||||
- QProcess 监听 pkexec 进程退出码判断成功/失败
|
||||
|
||||
### 2.5 数据接口
|
||||
|
||||
```cpp
|
||||
// 新增属性
|
||||
Q_PROPERTY(QStringList availableDrivers READ availableDrivers NOTIFY availableDriversChanged)
|
||||
Q_PROPERTY(bool driverInstalling READ driverInstalling NOTIFY driverInstallingChanged)
|
||||
|
||||
// 新增方法
|
||||
Q_INVOKABLE void installDriver(const QString &packageName);
|
||||
Q_INVOKABLE void uninstallDriver(const QString &packageName);
|
||||
|
||||
// availableDrivers 获取逻辑
|
||||
// 执行 apt list nvidia-driver*,解析输出
|
||||
```
|
||||
|
||||
### 2.6 安全考虑
|
||||
|
||||
- helper 脚本放置在 `/usr/share/` 下,需要 root 权限修改
|
||||
- 脚本中硬编码允许的包名前缀(如 `nvidia-driver`),防止注入
|
||||
- 不直接传递用户输入给 apt,只传递预定义的包名
|
||||
- polkit 策略限制只有本插件可以调用
|
||||
|
||||
---
|
||||
|
||||
## 三、实现优先级
|
||||
|
||||
| 优先级 | 功能 | 难度 | 预计工作量 |
|
||||
|--------|------|------|-----------|
|
||||
| P0 | PRIME 全局开关(方案A) | 低 | 0.5 天 |
|
||||
| P1 | 驱动安装 pkexec 方案 | 中 | 1-2 天 |
|
||||
| P2 | 按应用启动独显(方案B) | 中 | 1 天 |
|
||||
| P3 | D-Bus 系统服务(可选) | 高 | 2-3 天 |
|
||||
|
||||
## 四、参考资源
|
||||
|
||||
- [NVIDIA PRIME Render Offload 官方文档](https://download.nvidia.com/XFree86/Linux-x86_64/580.119.02/README/primerenderoffload.html)
|
||||
- [deepin-graphics-driver-manager 源码](http://git.jokul.space/Jokul/deepin-graphics-driver-manager)
|
||||
- [Polkit 设计文档](https://www.freedesktop.org/software/polkit/docs/latest/)
|
||||
- [systemd environment.d 说明](https://systemd.io/ENVIRONMENT/)
|
||||
Reference in New Issue
Block a user