[compositor stall] ~60% of session time stuck in frame-delivery stall (KWin Portal/PipeWire) #15

Closed
opened 2026-06-13 23:02:23 +08:00 by dailz · 1 comment
Owner

现象

会话日志 wl-webrtc.log(119.4s Portal/PipeWire 会话)中:

  • 124 次 WARN wl_webrtc::state_portal: compositor frame delivery stalled
  • 累计停滞时间 ~72.1s(占会话 60.5%)
  • 仅 88 次 resumed——36 次停滞在会话结束前从未恢复
  • 停顿时长分布:36 次 ≥ 600ms,11 次 400–600ms,8 次 200–400ms
  • capture_fps0.3 ~ 55.8 之间剧烈抖动(目标 60)

触发位置

src/state_portal.rs:357

let stall_threshold = Duration::from_millis(100).max(frame_interval * 3);

@60fps 阈值 = 100ms。

根因分析

KWin(以及大多数 Wayland 合成器)采用损伤驱动(damage-driven)的帧提交——画面静态时不送新帧。这是 Wayland 的正确行为,但当前实现把它当作异常,触发 filler 帧硬怼(见 #4),导致下游一连串浪费。

影响

  • 真实视频流 fps 远低于 60
  • filler 帧策略触发 3209 次重复帧去重(见 #4)
  • encoded_fps 被人工维持(见 #6),无法反映真实质量
  • 用户体验:画面"卡—放—卡—放"

期望方案(择一/组合)

  1. 接受静态画面:合成器不送帧是正常的,停止把 100ms 阈值当 stall 报警;依赖 WebRTC 层 PLI/FIR 主导(见 #2)
  2. 缩短 filler 上限:当前 2s 上限(state_portal.rs:387)在 60% 停滞率下无意义;改为基于"自上次真实捕获"的时间衰减
  3. 协商 PipeWire CursorFromCache / 损伤提示:让 KWin 在光标/小损伤时仍以低频送帧

复现

wl-webrtc --port 56666 -v  # KWin / KDE Wayland session, connect a viewer, leave screen mostly static

观察 1 分钟内 compositor frame delivery stalled 出现次数与 resumed after Xms 累计。

## 现象 会话日志 `wl-webrtc.log`(119.4s Portal/PipeWire 会话)中: - **124 次** `WARN wl_webrtc::state_portal: compositor frame delivery stalled` - 累计停滞时间 **~72.1s(占会话 60.5%)** - 仅 88 次 `resumed`——**36 次停滞在会话结束前从未恢复** - 停顿时长分布:36 次 ≥ 600ms,11 次 400–600ms,8 次 200–400ms - `capture_fps` 在 **0.3 ~ 55.8** 之间剧烈抖动(目标 60) ## 触发位置 `src/state_portal.rs:357` ```rust let stall_threshold = Duration::from_millis(100).max(frame_interval * 3); ``` @60fps 阈值 = 100ms。 ## 根因分析 KWin(以及大多数 Wayland 合成器)采用**损伤驱动**(damage-driven)的帧提交——画面静态时不送新帧。这是 Wayland 的正确行为,但当前实现把它当作异常,触发 filler 帧硬怼(见 #4),导致下游一连串浪费。 ## 影响 - 真实视频流 fps 远低于 60 - filler 帧策略触发 3209 次重复帧去重(见 #4) - `encoded_fps` 被人工维持(见 #6),无法反映真实质量 - 用户体验:画面"卡—放—卡—放" ## 期望方案(择一/组合) 1. **接受静态画面**:合成器不送帧是正常的,停止把 100ms 阈值当 stall 报警;依赖 WebRTC 层 PLI/FIR 主导(见 #2) 2. **缩短 filler 上限**:当前 2s 上限(`state_portal.rs:387`)在 60% 停滞率下无意义;改为基于"自上次真实捕获"的时间衰减 3. **协商 PipeWire `CursorFromCache` / 损伤提示**:让 KWin 在光标/小损伤时仍以低频送帧 ## 复现 ```bash wl-webrtc --port 56666 -v # KWin / KDE Wayland session, connect a viewer, leave screen mostly static ``` 观察 1 分钟内 `compositor frame delivery stalled` 出现次数与 `resumed after Xms` 累计。
dailz added the priority/criticaltype/bugarea/pipeline labels 2026-06-13 23:02:23 +08:00
Author
Owner

Dependencies

Blocked by:

  • #17 — stall 诊断和验证需要真实 stats 数据(output_bps / frame_bytes_max / sws_*
  • #18 — stall 缓解依赖 filler 策略改进(filler 是 stall 的应对措施)

修复顺序:先 #17 拿到数据,再 #18 改 filler,最后修本 issue。

## Dependencies **Blocked by:** - #17 — stall 诊断和验证需要真实 stats 数据(`output_bps` / `frame_bytes_max` / `sws_*`) - #18 — stall 缓解依赖 filler 策略改进(filler 是 stall 的应对措施) 修复顺序:先 #17 拿到数据,再 #18 改 filler,最后修本 issue。
dailz closed this issue 2026-06-20 20:56:49 +08:00
Sign in to join this conversation.