git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit67f61d280d346a711c4ad641ed40443a368fab80
parentf7167eaea9
authorIsaac Freund <[email protected]>
date2024-07-01 12:27
Output: fix Wayland backend support

The wlroots Wayland backend does not support gamma LUT application and
will currently fail to render anything if river commits a gamma LUT.

To fix this, test the state when applying a gamma LUT and fall back to a
state with no gamma LUT set if that fails.

This problem was revealed by 2e09b66 which flags gamma as dirty on all
outputs when they are enabled.

 build.zig.zon    |  4 ++--
 river/Output.zig | 15 ++++++++++-----
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/build.zig.zon b/build.zig.zon
index a1c2a92..28e5165 100644
--- a/build.zig.zon
+++ b/build.zig.zon
@@ -12,8 +12,8 @@
             .hash = "1220687c8c47a48ba285d26a05600f8700d37fc637e223ced3aa8324f3650bf52242",
         },
         .@"zig-wlroots" = .{
-            .url = "https://codeberg.org/ifreund/zig-wlroots/archive/v0.17.1.tar.gz",
-            .hash = "1220c65ab884c236cc950b564c70f6cd04046d86485ee76e0cde886cef7438021b4f",
+            .url = "https://codeberg.org/ifreund/zig-wlroots/archive/084736cd92364b5fa7d8161611d085ce272fa707.tar.gz",
+            .hash = "12208383c1cf42e9b932b90f68cd4f378582cf966355a6377fd8f913852e7bc2d7c6",
         },
         .@"zig-xkbcommon" = .{
             .url = "https://codeberg.org/ifreund/zig-xkbcommon/archive/v0.2.0.tar.gz",
diff --git a/river/Output.zig b/river/Output.zig
index 518bfc6..c9d8add 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -540,18 +540,23 @@ fn renderAndCommit(output: *Output, scene_output: *wlr.SceneOutput) !void {
         var state = wlr.Output.State.init();
         defer state.finish();
 
-        if (server.root.gamma_control_manager.getControl(output.wlr_output)) |control| {
-            log.info("applying gamma settings from client", .{});
-            if (!control.apply(&state)) return error.OutOfMemory;
-        } else {
-            log.info("clearing gamma settings from client", .{});
+        const control = server.root.gamma_control_manager.getControl(output.wlr_output);
+        if (!wlr.GammaControlV1.apply(control, &state)) return error.OutOfMemory;
+
+        if (!output.wlr_output.testState(&state)) {
+            wlr.GammaControlV1.sendFailedAndDestroy(control);
             state.clearGammaLut();
+            // If the backend does not support gamma LUTs it will reject any
+            // state with the gamma LUT committed bit set even if the state
+            // 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;
 
+        // TODO(wlroots) remove this rotate() call when updating to wlroots 0.18
         scene_output.damage_ring.rotate();
         output.gamma_dirty = false;
     } else {