mode.
*<core><allowTearing>* [yes|no]
- Allow tearing to reduce input lag. Default is no.
- This option requires setting the environment variable
- WLR_DRM_NO_ATOMIC=1.
- *yes* allow tearing if requested by the active window.
+ Allow tearing, if requested by the active window, to reduce input lag.
+ Default is no.
+
+ Note: Enabling this option with atomic mode setting is experimental. If
+ you experience undesirable side effects when tearing is allowed,
+ consider setting the environment variable WLR_DRM_NO_ATOMIC=1 when
+ launching labwc.
*<core><reuseOutputMode>* [yes|no]
Try to re-use the existing output mode (resolution / refresh rate).
set_adaptive_sync_mode(content, &rc.adaptive_sync);
} else if (!strcasecmp(nodename, "allowTearing.core")) {
set_bool(content, &rc.allow_tearing);
- if (rc.allow_tearing) {
- char *no_atomic_env = getenv("WLR_DRM_NO_ATOMIC");
- if (!no_atomic_env || strcmp(no_atomic_env, "1") != 0) {
- rc.allow_tearing = false;
- wlr_log(WLR_ERROR, "tearing requires WLR_DRM_NO_ATOMIC=1");
- }
- }
} else if (!strcasecmp(nodename, "reuseOutputMode.core")) {
set_bool(content, &rc.reuse_output_mode);
} else if (!strcmp(nodename, "policy.placement")) {
#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;
+}
+
static bool
get_tearing_preference(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;
+ }
+
/* If the active view requests tearing, or it is toggled on with action, allow it */
return server->active_view->tearing_hint;
}
*/
output_apply_gamma(output);
} else {
- output->pending.tearing_page_flip =
- get_tearing_preference(output);
+ struct wlr_scene_output *scene_output = output->scene_output;
+ struct wlr_output_state *pending = &output->pending;
- lab_wlr_scene_output_commit(output->scene_output,
- &output->pending);
+ pending->tearing_page_flip = get_tearing_preference(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);
+ }
+ }
}
struct timespec now = { 0 };