Skip to content

fix(waylib): preserve output identity in frame callbacks - #1391

Merged
zccrs merged 1 commit into
linuxdeepin:masterfrom
zccrs:fix/output-frame-source
Sep 10, 2026
Merged

fix(waylib): preserve output identity in frame callbacks#1391
zccrs merged 1 commit into
linuxdeepin:masterfrom
zccrs:fix/output-frame-source

Conversation

@zccrs

@zccrs zccrs commented Sep 10, 2026

Copy link
Copy Markdown
Member

问题 / Problem

移除 qwlroots 的提交 9582881dd 将 frame 回调改为调用无参 WOutputRenderWindow::render(),并将此前从 sender() 获取的输出替换为 nullptr。这使 needsFrameOutput 的过滤分支失效:任意输出的 frame 事件都可能渲染、提交其他就绪且有更新的输出。

Commit 9582881dd removed qwlroots and replaced the frame callback's output identity with nullptr. Native frame events consequently scanned every output instead of limiting rendering and commits to the output whose frame event fired.

修改 / Changes

  • 在现有、受生命周期管理的 frame listener 中捕获所属 wlr_output,直接传给 doRender()

  • 保持显式无参 render() 遍历全部输出的行为,不改动 needs_frame 调度和 listener 清理方式。

  • 添加使用真实 headless 输出和 software renderer 的回归测试,覆盖 A/B 各自的 frame 事件以及显式全输出渲染。

  • Capture the originating wlr_output in the existing lifetime-managed frame listener and pass it directly to doRender().

  • Preserve explicit all-output render() calls, needs_frame scheduling, and listener teardown.

  • Add a regression test using real headless outputs and the software renderer, covering each output's native frame event and explicit all-output rendering.

基于最新 master2f5bb78f3)创建的独立提交;不包含 WSG batch renderer 或 damage tracker 改动。

One isolated commit based on master (2f5bb78f3), without WSG batch renderer or damage tracker changes.

验证 / Verification

  • 独立 worktree 中成功构建 waylibserver 及相关测试。
  • 临时双输出 smoke 在恢复旧 nullptr 行为时失败:A/B 任一 frame 都提交两个输出。修复后仅提交对应输出,显式 render() 仍提交两个输出。
  • 保留的回归测试配置两个 headless 输出为 60 Hz / 144 Hz,直接发送原生 frame 事件,不依赖计时器时序。
  • 以下三个测试全部通过:test_output_frametest_wscoplistenertest_wobject_listeners
cmake --build --preset default -j$(nproc) \
  --target waylibserver test_output_frame test_wscoplistener test_wobject_listeners
/usr/bin/ctest --test-dir build \
  -R '^(test_output_frame|test_wscoplistener|test_wobject_listeners)$' \
  --output-on-failure

The two-output smoke failed with the old nullptr behavior (both outputs committed for either native frame), and passed with this fix (only the originating output committed; explicit rendering still committed both). All three focused tests passed. The retained test uses 60 Hz / 144 Hz headless outputs with explicitly delivered native frame events.

验证范围为 headless/software 渲染和 listener 单元测试;未进行真实 DRM 多显示器或热拔插验证。

Validation covers headless/software rendering and listener unit tests; physical DRM multi-monitor and hot-unplug testing was not performed.

Summary by Sourcery

Preserve output identity in frame callbacks while retaining explicit all-output rendering behavior.

Bug Fixes:

  • Restrict native frame callbacks to rendering and committing only the output that emitted the frame event, preventing unrelated outputs from being rendered.
  • Preserve explicit render() behavior that processes all outputs.

Tests:

  • Add a headless/software regression test covering per-output native frame events and explicit all-output rendering.

1. Pass the emitting output to doRender from the native frame listener.
2. Preserve all-output rendering for explicit render() calls.
3. Add a headless regression covering output-local and explicit rendering.

Log: Restore output-local frame scheduling on multi-monitor setups

Influence:
1. Verify that a frame event only commits its originating output.
2. Verify that explicit render() still commits all ready, dirty outputs.
3. Verify output listener teardown during hot-unplug and window destruction.

fix: 恢复帧回调中的输出身份

1. 在原生 frame 监听回调中将事件所属输出传入 doRender。
2. 保持显式 render() 调用遍历全部输出的行为。
3. 添加 headless 回归用例,覆盖单输出帧事件和显式渲染。

Log: 恢复多显示器环境下按输出独立调度帧的行为

Influence:
1. 验证 frame 事件只提交其所属输出。
2. 验证显式 render() 仍提交全部就绪且有更新的输出。
3. 验证热拔插及渲染窗口销毁时正确移除输出监听。
@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: zccrs

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai

sourcery-ai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR restores frame-event output identity by passing the originating wlr_output directly into doRender(), preventing one output’s native frame event from rendering other outputs while preserving explicit all-output rendering; a headless/software regression test covers both behaviors.

Sequence diagram for output-specific native frame rendering

sequenceDiagram
    participant WlrOutputA as wlr_output_A
    participant Listener as FrameListener
    participant RenderWindow as WOutputRenderWindow
    participant Renderer as doRender

    WlrOutputA->>Listener: frame event
    Listener->>RenderWindow: doRender(wlrOutput_A, outputs, false, true)
    RenderWindow->>Renderer: doRender(wlrOutput_A, outputs, false, true)
    Renderer-->>WlrOutputA: render and commit only output A
Loading

Sequence diagram for explicit all-output rendering

sequenceDiagram
    participant Caller
    participant RenderWindow as WOutputRenderWindow
    participant Renderer as doRender

    Caller->>RenderWindow: render()
    RenderWindow->>Renderer: doRender(nullptr, outputs, false, true)
    Renderer-->>Caller: render and commit all outputs
Loading

File-Level Changes

Change Details Files
Restore output-specific rendering for native frame callbacks while retaining explicit all-output rendering.
  • Capture the originating wlr_output in the lifetime-managed frame listener.
  • Invoke doRender() with that output so needsFrameOutput filtering applies.
  • Keep explicit render(), needs_frame scheduling, and listener teardown unchanged.
waylib/src/server/qtquick/woutputrenderwindow.cpp
Add a regression test that distinguishes native per-output frame handling from explicit full rendering.
  • Configure two real headless outputs with different refresh rates and the software renderer.
  • Trigger each native frame event directly and verify only its originating output is committed.
  • Verify explicit render() commits both outputs without relying on refresh-timer ordering.
waylib/tests/unit_tests/test_output_frame/main.cpp
waylib/tests/unit_tests/test_output_frame/CMakeLists.txt
waylib/tests/unit_tests/CMakeLists.txt

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@zccrs
zccrs merged commit b9759c0 into linuxdeepin:master Sep 10, 2026
10 checks passed
@zccrs
zccrs deleted the fix/output-frame-source branch September 10, 2026 11:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants