Skip to content

fix: re-enable output on backend mode request, force frame on fresh scene output - #5

Merged
mirkobrombin merged 1 commit into
singularityos-lab:singularityfrom
perlowja:fix/dp-hdmi-replug-black-screen
Sep 18, 2026
Merged

mirkobrombin merged 1 commit into
singularityos-lab:singularityfrom
perlowja:fix/dp-hdmi-replug-black-screen

Conversation

@perlowja

@perlowja perlowja commented Sep 6, 2026 •

Copy link
Copy Markdown

Summary

A DP/HDMI replug leaves the compositor black on CIX Sky1 (trilin-dptx-cix,
kernel 7.2.3-sky1-ncz). On this driver an unplug destroys the wlr_output, so
the replug arrives as a new one through configure_new_output(). A
freshly-created wlr_scene_output has needs_frame unset, so
lab_wlr_scene_output_commit() short-circuits on
wlr_scene_output_needs_frame() and the atomic commit that binds a CRTC to the
connector never reaches the kernel. Scheduling a frame first makes the commit
run; the idle source it registers is a no-op once the commit sets
frame_pending, so there is no double commit.

Scope

Rescoped per review to the single hardware-confirmed change: two lines in
configure_new_output(). The earlier mode-only re-enable path and the
mode-test retry timer are both gone, since neither was verified on the affected
hardware. The retry is not being filed as a separate PR yet - it stays out of
tree until it has a hardware reproduction behind it.

Test plan

  • Repeated unplug/replug of DP-3 on MS-R1 (4 outputs)
  • Repeated unplug/replug on Radxa Orion O6N (1 output)
  • Screen recovers without a compositor restart on both

AI assistance: disclosed

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 6, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-06T00:27:00.194813Z 2426867 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 242686761a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/output.c
~(WLR_OUTPUT_STATE_ENABLED | WLR_OUTPUT_STATE_MODE);
}
}
wlr_output_schedule_frame(output->wlr_output);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Commit the staged enable instead of scheduling a frame

When this branch handles a MODE-only request for a disabled output, enabled=true is only staged in output->pending; scheduling a frame cannot apply it. Any resulting callback reaches handle_output_frame(), which returns while the output is disabled because output_is_usable() requires wlr_output->enabled, so lab_wlr_scene_output_commit() is never called and the connector remains disabled. This path needs to commit the staged state directly, or otherwise permit the enabling frame callback to perform that commit.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Confirmed — verified against actual source (output_is_usable() at src/output.c:1240 checks the live wlr_output->enabled, not output->pending). Fixed in 122b5d4: commits the pending state directly on the success path instead of relying on the frame callback to apply it. Hardware-retested on MS-R1 after the fix, still resolves the replug black screen.

@mirkobrombin mirkobrombin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please split out the hardware-tested fresh-output frame fix and remove the unverified backend mode and power-state path.

@perlowja

Copy link
Copy Markdown
Author

Split as requested in aba03df.

Removed entirely: the MODE-only re-enable fallback in handle_output_request_state() (src/output.c) that staged enabled=true and called wlr_output_commit_state() on a backend mode request, plus the power_off bookkeeping it depended on (the field in include/output.h and the two assignments in handle_output_power_manager_set_mode()). That path was the one the PR description itself flagged as reasoned-not-reverified -- wlroots' nested x11/wayland backends appear to be the only callers of wlr_output_send_request_state() in 0.20, not drm, so it was never confirmed to actually run on this hardware.

Kept: only the wlr_output_schedule_frame() call in configure_new_output() right before lab_wlr_scene_output_commit(). That's the hardware-confirmed fix (O6N + MS-R1, repeated unplug/replug) -- it forces wlr_scene_output_needs_frame() past its early-return on a freshly-created wlr_scene_output, which is what actually gets the replugged connector re-committed.

Rebuilt clean (meson + ninja pulling wlroots-0.20 via the subproject wrap) and meson test is 130/130 green, so the split didn't break anything else.

@mirkobrombin mirkobrombin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The fix is now correctly scoped, but please reduce the 27-line explanation around the single schedule call to a concise cause-and-effect comment.

@perlowja
perlowja force-pushed the fix/dp-hdmi-replug-black-screen branch from b0ba70a to be9a38b Compare September 12, 2026 21:18
@perlowja

perlowja commented Sep 12, 2026 •

Copy link
Copy Markdown
Author

Trimmed in 133f910.

The 27-line block around the wlr_output_schedule_frame() call in configure_new_output() is now 7 lines: a fresh wlr_scene_output has needs_frame false, so lab_wlr_scene_output_commit() short-circuits and the atomic commit that binds a CRTC to the connector never reaches the kernel — black screen on replug; scheduling a frame sets needs_frame so the commit runs. Dropped the wlroots file/line trace, the field-by-field walk of wlr_scene_output_needs_frame(), and the double-commit aside.

Did the same to the four blocks around the mode-test retry (38 lines down to 8), keeping only the cause (some DP/HDMI transmitters report connected before link training settles, so the first mode test can fail for a display that is really there), the effect (without a retry the output stays disabled until a manual wlr-randr --on), the ~2s bound, and the one-line note on the use-after-free that the teardown in handle_output_destroy() guards against.

Comment-only, no functional change. Rebuilt clean on aarch64 and the full meson test suite is green at 130/130, unchanged.

@perlowja
perlowja force-pushed the fix/dp-hdmi-replug-black-screen branch from be9a38b to 133f910 Compare September 12, 2026 21:33

@mirkobrombin mirkobrombin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The new mode-test retry is explicitly unverified on the affected hardware, so please move it to a separate PR and keep this one limited to the hardware-confirmed frame scheduling fix.

@perlowja
perlowja force-pushed the fix/dp-hdmi-replug-black-screen branch from 133f910 to 7c6273a Compare September 17, 2026 14:41
A fresh wlr_scene_output has needs_frame false, so
lab_wlr_scene_output_commit() short-circuits and the atomic commit that
binds a CRTC never reaches the kernel: black screen after a DP/HDMI
replug. Scheduling a frame first makes the commit run.

Rescoped per review onto current singularity: the unverified mode-test
retry and its timer teardown are dropped entirely, leaving only the fix
confirmed on hardware (O6N and MS-R1, repeated unplug/replug).

Assisted-by: Claude Code:claude-opus-5
AI-Scope: Rescoped the branch to the single hardware-confirmed call, dropped the unverified retry machinery, and reduced the comment to one line.
Signed-off-by: Jason Perlow <jperlow@gmail.com>
@perlowja
perlowja force-pushed the fix/dp-hdmi-replug-black-screen branch from 37b5d5f to bd580a4 Compare September 17, 2026 14:42
@perlowja

Copy link
Copy Markdown
Author

Rescoped in bd580a4a. The branch is now one commit on current singularity, one file, +2 / -0.

Removed, per your review: the whole mode-test retry path - handle_output_enable_retry(), the OUTPUT_ENABLE_RETRY_MAX / _DELAY_MS bound, the enable_retry_timer and enable_retry_count fields in include/output.h, the timer teardown in handle_output_destroy(), and the configure_new_output() / finish_output_configuration() split it needed. You were right that it should not ride along: I had it on the branch with a reasoned argument and no hardware reproduction, which is not the same thing as a fix.

I have not filed it as a separate PR either. It stays out of tree until I can reproduce the mode-test failure on the affected board rather than infer it - it would be the same unverified change with a different number on it.

Kept: only wlr_output_schedule_frame(wlr_output) in configure_new_output(), immediately before lab_wlr_scene_output_commit(). That is the hardware-confirmed part - a fresh wlr_scene_output has needs_frame unset, so the commit short-circuits on wlr_scene_output_needs_frame() and the atomic commit that binds a CRTC never reaches the kernel.

Also trimmed the comment on it from 7 lines to 1, per your earlier aba03dfd note. The two lines this PR adds now are:

	/* A fresh scene_output has needs_frame false; the commit binds no CRTC. */
	wlr_output_schedule_frame(wlr_output);

I also had the branch based on main rather than singularity; it is on singularity now, which is why the file count dropped to one.

Still verified the same way: repeated unplug/replug of DP-3 on MS-R1 (4 outputs) and on Radxa Orion O6N (1 output), screen recovering without a compositor restart on both.

@mirkobrombin your 133f910f review is now stale - it asked for exactly the split that produced the new head, and gh api repos/singularityos-lab/labwc/compare/133f910f...bd580a4a reports status: diverged, ahead_by: 4, behind_by: 5. I cannot dismiss it from this account (403 on the dismissal endpoint), so flagging it here instead. Ready for re-review.

@mirkobrombin
mirkobrombin merged commit 025808d into singularityos-lab:singularity Sep 18, 2026
1 of 2 checks passed
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