tearing-control-v1: implement

Implement the wp-tearing-control-v1 protocol allowing window to hint
the compositor that they prefer async "tearing" page flips.

Add tearing/no-tearing rules to allow the user to manually
enabled/disable tearing for a window.

Use async "tearing" page flips when a window that should be allowed to
tear is fullscreen.

This still requires several kernel patches to work with the wlroots
atomic DRM backend. For now, either set WLR_DRM_NO_ATOMIC=1 or use a
custom kernel that includes the unmerged patches (such as CachyOS).

Closes: https://codeberg.org/river/river/issues/1094
(cherry picked from commit 066baa5753)
This commit is contained in:
Violet Purcell
2024-08-07 22:21:23 -04:00
committed by Isaac Freund
parent 993bdf96d1
commit aa1ef64448
10 changed files with 120 additions and 16 deletions

View File

@ -538,10 +538,12 @@ fn handleFrame(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
}
fn renderAndCommit(output: *Output, scene_output: *wlr.SceneOutput) !void {
if (output.gamma_dirty) {
var state = wlr.Output.State.init();
defer state.finish();
var state = wlr.Output.State.init();
defer state.finish();
if (!scene_output.buildState(&state, null)) return error.CommitFailed;
if (output.gamma_dirty) {
const control = server.root.gamma_control_manager.getControl(output.wlr_output);
if (!wlr.GammaControlV1.apply(control, &state)) return error.OutOfMemory;
@ -553,16 +555,21 @@ fn renderAndCommit(output: *Output, scene_output: *wlr.SceneOutput) !void {
// has a null LUT. The wayland backend for example has this behavior.
state.committed.gamma_lut = false;
}
if (!scene_output.buildState(&state, null)) return error.CommitFailed;
if (!output.wlr_output.commitState(&state)) return error.CommitFailed;
output.gamma_dirty = false;
} else {
if (!scene_output.commit(null)) return error.CommitFailed;
}
if (output.allowTearing() and server.config.allow_tearing == .enabled) {
state.tearing_page_flip = true;
if (!output.wlr_output.testState(&state)) {
log.debug("tearing page flip test failed for {s}, retrying without tearing", .{output.wlr_output.name});
state.tearing_page_flip = false;
}
}
if (!output.wlr_output.commitState(&state)) return error.CommitFailed;
if (output.gamma_dirty) output.gamma_dirty = false;
if (server.lock_manager.state == .locked or
(server.lock_manager.state == .waiting_for_lock_surfaces and output.locked_content.node.enabled) or
server.lock_manager.state == .waiting_for_blank)
@ -635,6 +642,14 @@ fn setTitle(output: Output) void {
}
}
fn allowTearing(output: *Output) bool {
if (output.current.fullscreen) |fullscreen_view| {
return fullscreen_view.allowTearing();
}
return false;
}
pub fn handleLayoutNamespaceChange(output: *Output) void {
// The user changed the layout namespace of this output. Try to find a
// matching layout.