diff options
author | Simon Ser <contact@emersion.fr> | 2021-08-10 18:47:14 +0200 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2021-09-07 11:18:18 +0200 |
commit | 3c74bd0c915e7ddd1b5dcc05d14f5555de10e980 (patch) | |
tree | 505a22f40ab0fc4379961d668129c73dba9b5786 /backend/drm/atomic.c | |
parent | 3fbf6e02a35e66abb52ca9c79527f3d07e8d9e4a (diff) |
backend/drm: introduce wlr_drm_connector_state
Previously, we were copying wlr_output_state on the stack and
patching it up to be guaranteed to have a proper drmModeModeInfo
stored in it (and not a custom mode). Also, we had a bunch of
helpers deriving DRM-specific information from the generic
wlr_output_state.
Copying the wlr_output_state worked fine so far, but with output
layers we'll be getting a wl_list in there. An empty wl_list stores
two pointers to itself, copying it on the stack blindly results in
infinite loops in wl_list_for_each.
To fix this, rework our DRM backend to stop copying wlr_output_state,
instead add a new struct wlr_drm_connector_state which holds both
the wlr_output_state and additional DRM-specific information.
Diffstat (limited to 'backend/drm/atomic.c')
-rw-r--r-- | backend/drm/atomic.c | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index ba493f6f..70f55aff 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -54,16 +54,14 @@ static void atomic_add(struct atomic *atom, uint32_t id, uint32_t prop, uint64_t } static bool create_mode_blob(struct wlr_drm_backend *drm, - struct wlr_drm_connector *conn, const struct wlr_output_state *state, - uint32_t *blob_id) { - if (!drm_connector_state_active(conn, state)) { + struct wlr_drm_connector *conn, + const struct wlr_drm_connector_state *state, uint32_t *blob_id) { + if (!state->active) { *blob_id = 0; return true; } - drmModeModeInfo mode = {0}; - drm_connector_state_mode(conn, state, &mode); - if (drmModeCreatePropertyBlob(drm->fd, &mode, + if (drmModeCreatePropertyBlob(drm->fd, &state->mode, sizeof(drmModeModeInfo), blob_id)) { wlr_log_errno(WLR_ERROR, "Unable to create mode property blob"); return false; @@ -166,13 +164,14 @@ error: } static bool atomic_crtc_commit(struct wlr_drm_connector *conn, - const struct wlr_output_state *state, uint32_t flags, bool test_only) { + const struct wlr_drm_connector_state *state, uint32_t flags, + bool test_only) { struct wlr_drm_backend *drm = conn->backend; struct wlr_output *output = &conn->output; struct wlr_drm_crtc *crtc = conn->crtc; - bool modeset = drm_connector_state_is_modeset(state); - bool active = drm_connector_state_active(conn, state); + bool modeset = state->modeset; + bool active = state->active; uint32_t mode_id = crtc->mode_id; if (modeset) { @@ -182,30 +181,30 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn, } uint32_t gamma_lut = crtc->gamma_lut; - if (state->committed & WLR_OUTPUT_STATE_GAMMA_LUT) { + if (state->base->committed & WLR_OUTPUT_STATE_GAMMA_LUT) { // Fallback to legacy gamma interface when gamma properties are not // available (can happen on older Intel GPUs that support gamma but not // degamma). if (crtc->props.gamma_lut == 0) { if (!drm_legacy_crtc_set_gamma(drm, crtc, - state->gamma_lut_size, - state->gamma_lut)) { + state->base->gamma_lut_size, + state->base->gamma_lut)) { return false; } } else { - if (!create_gamma_lut_blob(drm, state->gamma_lut_size, - state->gamma_lut, &gamma_lut)) { + if (!create_gamma_lut_blob(drm, state->base->gamma_lut_size, + state->base->gamma_lut, &gamma_lut)) { return false; } } } uint32_t fb_damage_clips = 0; - if ((state->committed & WLR_OUTPUT_STATE_DAMAGE) && + if ((state->base->committed & WLR_OUTPUT_STATE_DAMAGE) && crtc->primary->props.fb_damage_clips != 0) { int rects_len; const pixman_box32_t *rects = pixman_region32_rectangles( - (pixman_region32_t *)&state->damage, &rects_len); + (pixman_region32_t *)&state->base->damage, &rects_len); if (drmModeCreatePropertyBlob(drm->fd, rects, sizeof(*rects) * rects_len, &fb_damage_clips) != 0) { wlr_log_errno(WLR_ERROR, "Failed to create FB_DAMAGE_CLIPS property blob"); @@ -215,9 +214,9 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn, bool prev_vrr_enabled = output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED; bool vrr_enabled = prev_vrr_enabled; - if ((state->committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED) && + if ((state->base->committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED) && drm_connector_supports_vrr(conn)) { - vrr_enabled = state->adaptive_sync_enabled; + vrr_enabled = state->base->adaptive_sync_enabled; } if (test_only) { |