Nothing Special   »   [go: up one dir, main page]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backend/drm: Fix up tearing for atomic modesetting #1996

Merged
merged 1 commit into from
Jul 20, 2024

Conversation

kode54
Copy link
Contributor
@kode54 kode54 commented Jul 18, 2024

Remove the NO_ATOMIC check, and add a conditional fallback for errors, which usually result from properties being applied during a flip, such as hardware cursor image changes. Falling back is limited so that persistent errors do not keep immediate flips running forever, but instead disable them until an output is reset. Verified working at least on AMD Radeon 6700 XT.

src/output.c Outdated Show resolved Hide resolved
src/output.c Outdated Show resolved Hide resolved
@kode54 kode54 force-pushed the atomic-modesetting-tearing branch 4 times, most recently from bc0bbec to 71d8f2e Compare July 18, 2024 02:08
@Consolatis
Copy link
Member

Thanks for the PR.

LGTM, not tested.
Not merging right away to allow for further feedback.

Copy link
Member
@ahesford ahesford left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should expose a new configuration option for this. It's awkward, confusing, and will be obsolete whenever we (or wlroots, or whoever is the authority here) considers tearing allowance with atomic modesetting non-experimental. At best, we should note in the manual page (and perhaps in a comment in rc.xml.all) that enabling this option without setting WLR_DRM_NO_ATOMIC is experimental and not yet recommended for "production". That has the added benefit of simplifying the code, because we can drop the checks entirely instead of gating them behind another option. (Alternatively, we can log a warning if WLR_DRM_NO_ATOMIC is not set when tearing is enabled, and then remove the warning at some point in the future.)

src/output.c Outdated
Comment on lines 33 to 40
/* consecutive commit count before disabling until output reset */
#define TEARING_FAIL_LIMIT 120

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an arbitrary magic number. I think it would be better tied to the output refresh rate (e.g., throttle or disable the tearing preference after some fixed number of seconds) or perhaps exposed as a configuration option.

include/labwc.h Outdated
@@ -389,6 +389,8 @@ struct output {

bool leased;
bool gamma_lut_changed;

uint32_t tearing_fail_count;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe our normal style would dictate something like nr_tearing_failures rather than tearing_fail_count.

Using uint32_t seems like unnecessary specificity here, but I guess we don't use unsigned int anywhere else in that header. I wonder if the other uint32_t declarations are mandated by things like the wlroots API, which wouldn't apply to our internal counter.

src/output.c Outdated
lab_wlr_scene_output_commit(output->scene_output,
&output->pending);
get_tearing_preference(output) &&
output->tearing_fail_count < TEARING_FAIL_LIMIT;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check should be applied inside get_tearing_preference.

src/output.c Outdated
Comment on lines 122 to 148
if (!lab_wlr_scene_output_commit(output->scene_output,
&output->pending) && output->pending.tearing_page_flip) {
if (++output->tearing_fail_count >= TEARING_FAIL_LIMIT) {
wlr_log(WLR_INFO, "Tearing failed for %u consecutive"
" frames, disabling", (unsigned int)TEARING_FAIL_LIMIT);
}
output->pending.tearing_page_flip = false;
lab_wlr_scene_output_commit(output->scene_output,
&output->pending);
} else if (output->pending.tearing_page_flip) {
output->tearing_fail_count = 0;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think restructing this makes the logic a bit easier to read through (the setting of scene_output could be moved further up and used in the sanity check at the top of the function):

Suggested change
if (!lab_wlr_scene_output_commit(output->scene_output,
&output->pending) && output->pending.tearing_page_flip) {
if (++output->tearing_fail_count >= TEARING_FAIL_LIMIT) {
wlr_log(WLR_INFO, "Tearing failed for %u consecutive"
" frames, disabling", (unsigned int)TEARING_FAIL_LIMIT);
}
output->pending.tearing_page_flip = false;
lab_wlr_scene_output_commit(output->scene_output,
&output->pending);
} else if (output->pending.tearing_page_flip) {
output->tearing_fail_count = 0;
}
struct wlr_scene_output *scene_output = output->scene_output;
struct wlr_output_state *pending = &output->pending;
bool committed =
lab_wlr_scene_output_commit(scene_output, pending);
if (!pending->tearing_page_flip) {
return;
}
if (committed) {
output->tearing_fail_count = 0;
} else {
if (++output->tearing_fail_count >= TEARING_FAIL_LIMIT) {
wlr_log(WLR_INFO, "setting tearing allowance failed "
"for %u consecutive frames, disabling",
(unsigned int)TEARING_FAIL_LIMIT);
}
pending->tearing_page_flip = false;
lab_wlr_scene_output_commit(scene_output, pending);
}

@kode54 kode54 force-pushed the atomic-modesetting-tearing branch 6 times, most recently from 3a55005 to fcc6ff6 Compare July 18, 2024 08:56
Copy link
Member
@ahesford ahesford left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is looking good. With a nitpick and some trivial documentation cleanup, I think this will be ready to go.

Comment on lines 185 to 190
Allow tearing to reduce input lag. Default is no.
This option requires setting the environment variable
WLR_DRM_NO_ATOMIC=1.
Use of this variable without setting the environment variable
WLR_DRM_NO_ATOMIC=1 is considered experimental at this time, and
may have minor issues if used in combination with hardware cursors,
though none were observed yet as a noticeable problem in testing.
*yes* allow tearing if requested by the active window.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the existing description was not properly edited when we added it. Please drop the final sentence, and maybe we can refine the description for clarity:

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.

src/output.c Outdated
{
/* Two seconds worth of frames, guessing 60Hz if refresh is zero */
unsigned int refresh = output->wlr_output->refresh;
return refresh ? refresh / 500 : 120;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the interest of Postel's law:

Suggested change
return refresh ? refresh / 500 : 120;
return refresh > 0 ? refresh / 500 : 120;

@kode54 kode54 force-pushed the atomic-modesetting-tearing branch 3 times, most recently from 74a4c1d to dda1d43 Compare July 20, 2024 09:31
Additionally, track errors and abandon the tearing allowance when it
cannot be set for two-seconds' worth of consecutive frames.
@ahesford ahesford merged commit d033a2f into labwc:master Jul 20, 2024
4 of 5 checks passed
@ahesford
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants