mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
output: allow tearing with atomic mode setting
Additionally, track errors and abandon the tearing allowance when it cannot be set for two-seconds' worth of consecutive frames.
This commit is contained in:
parent
14d9bbab90
commit
d033a2fbf6
4 changed files with 42 additions and 15 deletions
|
|
@ -186,10 +186,13 @@ this is for compatibility with Openbox.
|
|||
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).
|
||||
|
|
|
|||
|
|
@ -389,6 +389,8 @@ struct output {
|
|||
|
||||
bool leased;
|
||||
bool gamma_lut_changed;
|
||||
|
||||
uint32_t nr_tearing_failures;
|
||||
};
|
||||
|
||||
#undef LAB_NR_LAYERS
|
||||
|
|
|
|||
|
|
@ -885,13 +885,6 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
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")) {
|
||||
|
|
|
|||
37
src/output.c
37
src/output.c
|
|
@ -30,6 +30,14 @@
|
|||
#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)
|
||||
{
|
||||
|
|
@ -45,6 +53,11 @@ 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;
|
||||
}
|
||||
|
|
@ -112,11 +125,27 @@ output_frame_notify(struct wl_listener *listener, void *data)
|
|||
*/
|
||||
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 };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue