Merge branch 'testless_reuse' into 'main'

drm: Don't test reused states

Closes #1081

See merge request wayland/weston!1920
This commit is contained in:
Derek Foreman 2025-12-19 12:50:12 -06:00
commit 7feaf178b6
3 changed files with 41 additions and 6 deletions

View file

@ -82,6 +82,8 @@
#define MAX_DMABUF_PLANES 4
#endif
#define DRM_MAX_REUSE_FAILURES 10
/**
* A small wrapper to print information into the 'drm-backend' debug scope.
*
@ -224,6 +226,8 @@ struct drm_device {
/* struct drm_colorop_3x1d_lut::link */
struct wl_list drm_colorop_3x1d_lut_list;
int reused_state_failures;
};
struct drm_backend {
@ -635,6 +639,9 @@ struct drm_output {
submit_frame_cb virtual_submit_frame;
enum wdrm_content_type content_type;
bool reused_state;
bool force_rebuild_state;
};
void

View file

@ -1099,6 +1099,7 @@ drm_repaint_flush_device(struct drm_device *device)
struct drm_pending_state *pending_state;
struct weston_output *base;
int ret;
bool failed_reuse = false;
pending_state = device->repaint_data;
if (!pending_state)
@ -1120,7 +1121,22 @@ drm_repaint_flush_device(struct drm_device *device)
if (!base->will_repaint || !tmp || tmp->device != device)
continue;
if (ret == -EBUSY)
if (tmp->reused_state) {
failed_reuse = true;
tmp->force_rebuild_state = true;
device->reused_state_failures++;
}
}
if (failed_reuse)
drm_debug(b, "[repaint] failed with reused state, will rebuild and try again.\n");
wl_list_for_each(base, &b->compositor->output_list, link) {
struct drm_output *tmp = to_drm_output(base);
if (!base->will_repaint || !tmp || tmp->device != device)
continue;
if (ret == -EBUSY || failed_reuse)
weston_output_schedule_repaint_restart(base);
else
weston_output_schedule_repaint_reset(base);

View file

@ -920,10 +920,17 @@ drm_output_propose_state(struct weston_output *output_base,
/* Record the current lowest zpos of the underlay plane */
uint64_t current_lowest_zpos_underlay = DRM_PLANE_ZPOS_INVALID_PLANE;
output->reused_state = false;
if (mode & DRM_OUTPUT_PROPOSE_STATE_REUSE) {
struct weston_paint_node *pnode;
bool found_primary = false;
if (output->force_rebuild_state) {
debug_propose_fail(output, mode, "previous state failed");
return NULL;
}
if (output->state_cur->mode == DRM_OUTPUT_PROPOSE_STATE_INVALID) {
debug_propose_fail(output, mode, "no previous state");
return NULL;
@ -1005,10 +1012,13 @@ drm_output_propose_state(struct weston_output *output_base,
pnode->surface->buffer_release_ref.buffer_release);
}
if (drm_pending_state_test(pending_state) != 0) {
debug_propose_fail(output, mode, "atomic test not OK");
drm_output_state_free(state);
return NULL;
if (device->reused_state_failures > DRM_MAX_REUSE_FAILURES) {
drm_debug(b, "\t\t[reuse] must test due to high number of failures\n");
if (drm_pending_state_test(pending_state) != 0) {
debug_propose_fail(output, mode, "atomic test not OK");
drm_output_state_free(state);
return NULL;
}
}
if (!found_primary) {
@ -1022,7 +1032,7 @@ drm_output_propose_state(struct weston_output *output_base,
drm_fb_unref(pstate->fb);
pstate->fb = NULL;
}
output->reused_state = true;
return state;
}
@ -1397,6 +1407,8 @@ drm_assign_planes(struct weston_output *output_base)
assert(state);
assert(state->planes_enabled == !output_base->disable_planes);
output->force_rebuild_state = false;
drm_debug(b, "\t[repaint] Using %s composition\n",
drm_propose_state_mode_to_string(mode));