backend/drm: extract post-commit logic into functions

It's more readable, and we'll soon call this from a loop for
multi-connector commits.
This commit is contained in:
Simon Ser 2024-02-14 14:00:30 +01:00 committed by Kenny Levinsen
parent f8f2dde1f0
commit 3d72da9ed7
1 changed files with 41 additions and 29 deletions

View File

@ -449,24 +449,11 @@ static struct wlr_drm_page_flip *drm_page_flip_create(struct wlr_drm_connector *
return page_flip; return page_flip;
} }
static bool drm_crtc_commit(struct wlr_drm_connector *conn, static void drm_connector_apply_commit(const struct wlr_drm_connector_state *state,
const struct wlr_drm_connector_state *state, struct wlr_drm_page_flip *page_flip) {
uint32_t flags, bool test_only) { struct wlr_drm_connector *conn = state->connector;
// Disallow atomic-only flags
assert((flags & ~DRM_MODE_PAGE_FLIP_FLAGS) == 0);
struct wlr_drm_page_flip *page_flip = NULL;
if (flags & DRM_MODE_PAGE_FLIP_EVENT) {
page_flip = drm_page_flip_create(conn);
if (page_flip == NULL) {
return false;
}
}
struct wlr_drm_backend *drm = conn->backend;
struct wlr_drm_crtc *crtc = conn->crtc; struct wlr_drm_crtc *crtc = conn->crtc;
bool ok = drm->iface->crtc_commit(conn, state, page_flip, flags, test_only);
if (ok && !test_only) {
drm_fb_copy(&crtc->primary->queued_fb, state->primary_fb); drm_fb_copy(&crtc->primary->queued_fb, state->primary_fb);
if (crtc->cursor != NULL) { if (crtc->cursor != NULL) {
drm_fb_copy(&crtc->cursor->queued_fb, state->cursor_fb); drm_fb_copy(&crtc->cursor->queued_fb, state->cursor_fb);
@ -483,7 +470,11 @@ static bool drm_crtc_commit(struct wlr_drm_connector *conn,
if (state->base->committed & WLR_OUTPUT_STATE_MODE) { if (state->base->committed & WLR_OUTPUT_STATE_MODE) {
conn->refresh = calculate_refresh_rate(&state->mode); conn->refresh = calculate_refresh_rate(&state->mode);
} }
} else { }
static void drm_connector_rollback_commit(const struct wlr_drm_connector_state *state) {
struct wlr_drm_crtc *crtc = state->connector->crtc;
// The set_cursor() hook is a bit special: it's not really synchronized // The set_cursor() hook is a bit special: it's not really synchronized
// to commit() or test(). Once set_cursor() returns true, the new // to commit() or test(). Once set_cursor() returns true, the new
// cursor is effectively committed. So don't roll it back here, or we // cursor is effectively committed. So don't roll it back here, or we
@ -495,7 +486,28 @@ static bool drm_crtc_commit(struct wlr_drm_connector *conn,
wl_list_for_each(layer, &crtc->layers, link) { wl_list_for_each(layer, &crtc->layers, link) {
drm_fb_clear(&layer->pending_fb); drm_fb_clear(&layer->pending_fb);
} }
}
static bool drm_crtc_commit(struct wlr_drm_connector *conn,
const struct wlr_drm_connector_state *state,
uint32_t flags, bool test_only) {
// Disallow atomic-only flags
assert((flags & ~DRM_MODE_PAGE_FLIP_FLAGS) == 0);
struct wlr_drm_page_flip *page_flip = NULL;
if (flags & DRM_MODE_PAGE_FLIP_EVENT) {
page_flip = drm_page_flip_create(conn);
if (page_flip == NULL) {
return false;
}
}
struct wlr_drm_backend *drm = conn->backend;
bool ok = drm->iface->crtc_commit(conn, state, page_flip, flags, test_only);
if (ok && !test_only) {
drm_connector_apply_commit(state, page_flip);
} else {
drm_connector_rollback_commit(state);
drm_page_flip_destroy(page_flip); drm_page_flip_destroy(page_flip);
} }
return ok; return ok;