]> git.mdlowis.com Git - proto/labwc.git/commitdiff
tearing: avoid permanent disable due to rejected commits (#2295)
authorRicardo Steijn <61013287+RicArch97@users.noreply.github.com>
Sun, 3 Nov 2024 21:05:46 +0000 (22:05 +0100)
committerGitHub <noreply@github.com>
Sun, 3 Nov 2024 21:05:46 +0000 (21:05 +0000)
Currently, the cursor plane does not allow async page flips which causes tearing page flips to be rejected if the cursor was moved.

However, in games where no cursor image is present, the async page flips can still work as expected.

Instead of permanently disabling tearing after too many failures, test the output state first before each frame to see if we can commit with tearing_page_flip set to true.

include/labwc.h
src/common/scene-helpers.c
src/output.c

index 09fdca7baf086869e07d0bc282bba358867a6faa..29f72c394e0085f9e959d13a007682042766930f 100644 (file)
@@ -406,8 +406,6 @@ struct output {
 
        bool leased;
        bool gamma_lut_changed;
-
-       uint32_t nr_tearing_failures;
 };
 
 #undef LAB_NR_LAYERS
index 6f3ee3735ad2ed647edb16ed4a4c2457b69837aa..1eb670ed503a578c8547bc56cbf731927d1029e3 100644 (file)
@@ -107,19 +107,33 @@ lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output,
                return false;
        }
 
+       if (state->tearing_page_flip) {
+               if (!wlr_output_test_state(wlr_output, state)) {
+                       state->tearing_page_flip = false;
+               }
+       }
+
        struct wlr_box additional_damage = {0};
        if (state->buffer && is_magnify_on()) {
                magnify(output, state->buffer, &additional_damage);
        }
 
-       if (state == &output->pending) {
-               if (!output_state_commit(output)) {
-                       wlr_log(WLR_INFO, "Failed to commit output %s",
-                               wlr_output->name);
-                       return false;
+       bool committed = wlr_output_commit_state(wlr_output, state);
+       /*
+        * Handle case where the ouput state test for tearing succeeded,
+        * but actual commit failed. Retry wihout tearing.
+        */
+       if (!committed && state->tearing_page_flip) {
+               state->tearing_page_flip = false;
+               committed = wlr_output_commit_state(wlr_output, state);
+       }
+       if (committed) {
+               if (state == &output->pending) {
+                       wlr_output_state_finish(&output->pending);
+                       wlr_output_state_init(&output->pending);
                }
-       } else if (!wlr_output_commit_state(wlr_output, state)) {
-               wlr_log(WLR_INFO, "Failed to commit state for output %s",
+       } else {
+               wlr_log(WLR_INFO, "Failed to commit output %s",
                        wlr_output->name);
                return false;
        }
index cd7299b121b83d1376178578896c43d2a88270c4..0eee633128d68ce0f83dfe11238b444dd47e1b1a 100644 (file)
 #include "view.h"
 #include "xwayland.h"
 
-static unsigned int
-get_tearing_retry_count(struct output *output)
-{
-       /* Two seconds worth of frames, guessing 60Hz if refresh is invalid */
-       int refresh = output->wlr_output->refresh;
-       return refresh > 0 ? refresh / 500 : 120;
-}
-
 bool
 output_get_tearing_allowance(struct output *output)
 {
@@ -57,11 +49,6 @@ output_get_tearing_allowance(struct output *output)
                return false;
        }
 
-       /* tearing should not have failed too many times */
-       if (output->nr_tearing_failures >= get_tearing_retry_count(output)) {
-               return false;
-       }
-
        /* allow tearing for any window when requested or forced */
        if (rc.allow_tearing == LAB_TEARING_ENABLED) {
                if (view->force_tearing == LAB_STATE_UNSPECIFIED) {
@@ -154,22 +141,7 @@ output_frame_notify(struct wl_listener *listener, void *data)
 
                pending->tearing_page_flip = output_get_tearing_allowance(output);
 
-               bool committed =
-                       lab_wlr_scene_output_commit(scene_output, pending);
-
-               if (pending->tearing_page_flip) {
-                       if (committed) {
-                               output->nr_tearing_failures = 0;
-                       } else {
-                               if (++output->nr_tearing_failures >=
-                                               get_tearing_retry_count(output)) {
-                                       wlr_log(WLR_INFO, "setting tearing allowance failed "
-                                               "for two consecutive seconds, disabling");
-                               }
-                               pending->tearing_page_flip = false;
-                               lab_wlr_scene_output_commit(scene_output, pending);
-                       }
-               }
+               lab_wlr_scene_output_commit(scene_output, pending);
        }
 
        struct timespec now = { 0 };