From 3df1528a8fba3109a41c58f5434425d2914cd2ae Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Mon, 28 Oct 2024 17:53:12 +0100 Subject: [PATCH] backend/drm: Store viewport with framebuffer Accessing the output state viewport require a buffer, and that might not have a state with a buffer when preparing the plane properties for an atomic commit. Instead, store the properties at the same time as the fb, and use a similar mechanism to carry the state around. --- backend/drm/atomic.c | 10 ++-------- backend/drm/drm.c | 7 +++++++ include/backend/drm/drm.h | 8 ++++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index b52230f90..143f37a65 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -439,15 +439,9 @@ static void atomic_connector_add(struct atomic *atom, if (crtc->props.vrr_enabled != 0) { atomic_add(atom, crtc->id, crtc->props.vrr_enabled, state->vrr_enabled); } - if (state->base->committed & WLR_OUTPUT_STATE_BUFFER) { - struct wlr_fbox src_box; - struct wlr_box dst_box; - output_state_get_buffer_src_box(state->base, &src_box); - output_state_get_buffer_dst_box(state->base, &dst_box); - set_plane_props(atom, drm, crtc->primary, state->primary_fb, crtc->id, - &dst_box, &src_box); - } + set_plane_props(atom, drm, crtc->primary, state->primary_fb, crtc->id, + &state->primary_viewport.dst_box, &state->primary_viewport.src_box); if (crtc->primary->props.fb_damage_clips != 0) { atomic_add(atom, crtc->primary->id, crtc->primary->props.fb_damage_clips, state->fb_damage_clips); diff --git a/backend/drm/drm.c b/backend/drm/drm.c index d8724c02a..d70492af1 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -557,6 +557,7 @@ static void drm_connector_apply_commit(const struct wlr_drm_connector_state *sta struct wlr_drm_crtc *crtc = conn->crtc; drm_fb_copy(&crtc->primary->queued_fb, state->primary_fb); + crtc->primary->queued_viewport = state->primary_viewport; if (crtc->cursor != NULL) { drm_fb_copy(&crtc->cursor->queued_fb, state->cursor_fb); } @@ -673,8 +674,10 @@ static void drm_connector_state_init(struct wlr_drm_connector_state *state, struct wlr_drm_plane *primary = conn->crtc->primary; if (primary->queued_fb != NULL) { state->primary_fb = drm_fb_lock(primary->queued_fb); + state->primary_viewport = primary->queued_viewport; } else if (primary->current_fb != NULL) { state->primary_fb = drm_fb_lock(primary->current_fb); + state->primary_viewport = primary->current_viewport; } if (conn->cursor_enabled) { @@ -761,6 +764,9 @@ static bool drm_connector_state_update_primary_fb(struct wlr_drm_connector *conn return false; } + output_state_get_buffer_src_box(state->base, &state->primary_viewport.src_box); + output_state_get_buffer_dst_box(state->base, &state->primary_viewport.dst_box); + return true; } @@ -2058,6 +2064,7 @@ static void handle_page_flip(int fd, unsigned seq, struct wlr_drm_plane *plane = conn->crtc->primary; if (plane->queued_fb) { drm_fb_move(&plane->current_fb, &plane->queued_fb); + plane->current_viewport = plane->queued_viewport; } if (conn->crtc->cursor && conn->crtc->cursor->queued_fb) { drm_fb_move(&conn->crtc->cursor->current_fb, diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index 5b239a18e..3ef83e3e0 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -15,6 +15,11 @@ #include "backend/drm/properties.h" #include "backend/drm/renderer.h" +struct wlr_drm_viewport { + struct wlr_fbox src_box; + struct wlr_box dst_box; +}; + struct wlr_drm_plane { uint32_t type; uint32_t id; @@ -24,8 +29,10 @@ struct wlr_drm_plane { /* Buffer submitted to the kernel, will be presented on next vblank */ struct wlr_drm_fb *queued_fb; + struct wlr_drm_viewport queued_viewport; /* Buffer currently displayed on screen */ struct wlr_drm_fb *current_fb; + struct wlr_drm_viewport current_viewport; struct wlr_drm_format_set formats; @@ -139,6 +146,7 @@ struct wlr_drm_connector_state { bool active; drmModeModeInfo mode; struct wlr_drm_fb *primary_fb; + struct wlr_drm_viewport primary_viewport; struct wlr_drm_fb *cursor_fb; struct wlr_drm_syncobj_timeline *wait_timeline;