]> git.mdlowis.com Git - proto/labwc.git/commitdiff
magnifier: fix flickering on simultaneous gamma changes
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Mon, 17 Jun 2024 14:36:07 +0000 (16:36 +0200)
committerConsolatis <35009135+Consolatis@users.noreply.github.com>
Sat, 29 Jun 2024 21:36:41 +0000 (23:36 +0200)
Gamma changes take another code path and thus did not
render the magnifier. This patch consalidates both
code paths and therefore also renders the magnifier on
gamma changes.

Fixes: #1905
include/common/scene-helpers.h
src/common/scene-helpers.c
src/magnifier.c
src/output.c

index 11697a94c745ce9a1a4b7c36626c4f726592d821..021d3b16f1660e1e6a1a6899aa75b2f14a74b22c 100644 (file)
@@ -7,6 +7,7 @@
 struct wlr_scene_node;
 struct wlr_surface;
 struct wlr_scene_output;
+struct wlr_output_state;
 
 struct wlr_surface *lab_wlr_surface_from_node(struct wlr_scene_node *node);
 
@@ -18,6 +19,7 @@ struct wlr_surface *lab_wlr_surface_from_node(struct wlr_scene_node *node);
 struct wlr_scene_node *lab_wlr_scene_get_prev_node(struct wlr_scene_node *node);
 
 /* A variant of wlr_scene_output_commit() that respects wlr_output->pending */
-bool lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output);
+bool lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output,
+       struct wlr_output_state *output_state);
 
 #endif /* LABWC_SCENE_HELPERS_H */
index 755d65d42a486ea3654b42658854654b7f6d78f1..3ed59726362a11155b39f2d7294b671213be3d95 100644 (file)
@@ -40,11 +40,12 @@ lab_wlr_scene_get_prev_node(struct wlr_scene_node *node)
  * as it doesn't use the pending state at all.
  */
 bool
-lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output)
+lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output,
+               struct wlr_output_state *state)
 {
        assert(scene_output);
+       assert(state);
        struct wlr_output *wlr_output = scene_output->output;
-       struct wlr_output_state *state = &wlr_output->pending;
        struct output *output = wlr_output->data;
        bool wants_magnification = output_wants_magnification(output);
 
@@ -70,11 +71,18 @@ lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output)
                magnify(output, state->buffer, &additional_damage);
        }
 
-       if (!wlr_output_commit(wlr_output)) {
-               wlr_log(WLR_INFO, "Failed to commit output %s",
+       if (state == &wlr_output->pending) {
+               if (!wlr_output_commit(wlr_output)) {
+                       wlr_log(WLR_INFO, "Failed to commit output %s",
+                               wlr_output->name);
+                       return false;
+               }
+       } else if (!wlr_output_commit_state(wlr_output, state)) {
+               wlr_log(WLR_INFO, "Failed to commit state for output %s",
                        wlr_output->name);
                return false;
        }
+
        /*
         * FIXME: Remove the following line as soon as
         * https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4253
index 327fd3e4f807602080b1aac9efc2dd09d402baaa..29b16154ef2b317d535f8229a129db70a000da4f 100644 (file)
@@ -96,7 +96,7 @@ magnify(struct output *output, struct wlr_buffer *output_buffer, struct wlr_box
 
        /* (Re)create the temporary buffer if required */
        if (tmp_buffer && (tmp_buffer->width != width || tmp_buffer->height != height)) {
-               wlr_log(WLR_DEBUG, "tmp buffer size changed, dropping");
+               wlr_log(WLR_DEBUG, "tmp magnifier buffer size changed, dropping");
                assert(tmp_texture);
                wlr_texture_destroy(tmp_texture);
                wlr_buffer_drop(tmp_buffer);
@@ -117,7 +117,7 @@ magnify(struct output *output, struct wlr_buffer *output_buffer, struct wlr_box
                tmp_texture = wlr_texture_from_buffer(server->renderer, tmp_buffer);
        }
        if (!tmp_texture) {
-               wlr_log(WLR_ERROR, "Failed to allocate temporary texture");
+               wlr_log(WLR_ERROR, "Failed to allocate temporary magnifier texture");
                wlr_buffer_drop(tmp_buffer);
                tmp_buffer = NULL;
                return;
@@ -209,7 +209,7 @@ magnify(struct output *output, struct wlr_buffer *output_buffer, struct wlr_box
        };
        wlr_render_pass_add_texture(tmp_render_pass, &opts);
        if (!wlr_render_pass_submit(tmp_render_pass)) {
-               wlr_log(WLR_ERROR, "Failed to submit render pass");
+               wlr_log(WLR_ERROR, "Failed to submit magnifier render pass");
                goto cleanup;
        }
 
index bb2b9760e79c4aaffca4cbda25d38d91cc4158db..1bf014295c8adaf47e22136b21a0ecdc94e27df8 100644 (file)
@@ -48,6 +48,36 @@ get_tearing_preference(struct output *output)
        return server->active_view->tearing_hint;
 }
 
+static void
+output_apply_gamma(struct output *output)
+{
+       assert(output);
+       assert(output->gamma_lut_changed);
+
+       struct server *server = output->server;
+       struct wlr_scene_output *scene_output = output->scene_output;
+
+       struct wlr_output_state pending;
+       wlr_output_state_init(&pending);
+
+       output->gamma_lut_changed = false;
+       struct wlr_gamma_control_v1 *gamma_control =
+               wlr_gamma_control_manager_v1_get_control(
+                       server->gamma_control_manager_v1,
+                       output->wlr_output);
+
+       if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) {
+               wlr_output_state_finish(&pending);
+               return;
+       }
+
+       if (!lab_wlr_scene_output_commit(scene_output, &pending)) {
+               wlr_gamma_control_v1_send_failed_and_destroy(gamma_control);
+       }
+
+       wlr_output_state_finish(&pending);
+}
+
 static void
 output_frame_notify(struct wl_listener *listener, void *data)
 {
@@ -71,39 +101,23 @@ output_frame_notify(struct wl_listener *listener, void *data)
                return;
        }
 
-       struct wlr_output *wlr_output = output->wlr_output;
-       struct server *server = output->server;
-
        if (output->gamma_lut_changed) {
-               struct wlr_output_state pending;
-               wlr_output_state_init(&pending);
-               if (!wlr_scene_output_build_state(output->scene_output, &pending, NULL)) {
-                       return;
-               }
-               output->gamma_lut_changed = false;
-               struct wlr_gamma_control_v1 *gamma_control =
-                       wlr_gamma_control_manager_v1_get_control(
-                               server->gamma_control_manager_v1, wlr_output);
-               if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) {
-                       wlr_output_state_finish(&pending);
-                       return;
-               }
-
-               if (!wlr_output_commit_state(output->wlr_output, &pending)) {
-                       wlr_gamma_control_v1_send_failed_and_destroy(gamma_control);
-                       wlr_output_state_finish(&pending);
-                       return;
-               }
+               /*
+                * We are not mixing the gamma state with
+                * other pending output changes to make it
+                * easier to handle a failed output commit
+                * due to gamma without impacting other
+                * unrelated output changes.
+                */
+               output_apply_gamma(output);
+       } else {
+               output->wlr_output->pending.tearing_page_flip =
+                       get_tearing_preference(output);
 
-               wlr_damage_ring_rotate(&output->scene_output->damage_ring);
-               wlr_output_state_finish(&pending);
-               return;
+               lab_wlr_scene_output_commit(output->scene_output,
+                       &output->wlr_output->pending);
        }
 
-       output->wlr_output->pending.tearing_page_flip =
-               get_tearing_preference(output);
-       lab_wlr_scene_output_commit(output->scene_output);
-
        struct timespec now = { 0 };
        clock_gettime(CLOCK_MONOTONIC, &now);
        wlr_scene_output_send_frame_done(output->scene_output, &now);