diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index df94410b..c7b630d6 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -62,7 +62,9 @@ static bool create_mode_blob(struct wlr_drm_backend *drm, return true; } - if (drmModeCreatePropertyBlob(drm->fd, &conn->crtc->pending.mode->drm_mode, + drmModeModeInfo mode = {0}; + drm_connector_state_mode(conn, state, &mode); + if (drmModeCreatePropertyBlob(drm->fd, &mode, sizeof(drmModeModeInfo), blob_id)) { wlr_log_errno(WLR_ERROR, "Unable to create mode property blob"); return false; diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 0d4cc9b7..5e01ce99 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -333,13 +333,11 @@ static bool drm_crtc_commit(struct wlr_drm_connector *conn, struct wlr_drm_crtc *crtc = conn->crtc; bool ok = drm->iface->crtc_commit(drm, conn, state, flags); if (ok && !(flags & DRM_MODE_ATOMIC_TEST_ONLY)) { - memcpy(&crtc->current, &crtc->pending, sizeof(struct wlr_drm_crtc_state)); drm_plane_set_committed(crtc->primary); if (crtc->cursor != NULL) { drm_plane_set_committed(crtc->cursor); } } else { - memcpy(&crtc->pending, &crtc->current, sizeof(struct wlr_drm_crtc_state)); drm_fb_clear(&crtc->primary->pending_fb); if (crtc->cursor != NULL) { drm_fb_clear(&crtc->cursor->pending_fb); @@ -438,10 +436,7 @@ static struct wlr_output_mode *drm_connector_get_pending_mode( return output->pending.mode; case WLR_OUTPUT_STATE_MODE_CUSTOM:; drmModeModeInfo mode = {0}; - generate_cvt_mode(&mode, output->pending.custom_mode.width, - output->pending.custom_mode.height, - (float)output->pending.custom_mode.refresh / 1000, false, false); - mode.type = DRM_MODE_TYPE_USERDEF; + drm_connector_state_mode(conn, &output->pending, &mode); return wlr_drm_connector_add_mode(output, &mode); } abort(); @@ -680,8 +675,6 @@ static bool drm_connector_init_renderer(struct wlr_drm_connector *conn, } struct wlr_drm_plane *plane = crtc->primary; - crtc->pending.mode = mode; - int width = mode->wlr_mode.width; int height = mode->wlr_mode.height; uint32_t format = DRM_FORMAT_ARGB8888; @@ -702,8 +695,6 @@ static bool drm_connector_init_renderer(struct wlr_drm_connector *conn, "retrying without modifiers"); modifiers = false; - crtc->pending.mode = mode; - if (!drm_plane_init_surface(plane, drm, width, height, format, modifiers)) { return false; @@ -1047,6 +1038,31 @@ bool drm_connector_state_active(struct wlr_drm_connector *conn, return conn->output.enabled; } +void drm_connector_state_mode(struct wlr_drm_connector *conn, + const struct wlr_output_state *state, drmModeModeInfo *out) { + assert(drm_connector_state_active(conn, state)); + + struct wlr_output_mode *wlr_mode = conn->output.current_mode; + if (state->committed & WLR_OUTPUT_STATE_MODE) { + switch (state->mode_type) { + case WLR_OUTPUT_STATE_MODE_FIXED: + wlr_mode = state->mode; + break; + case WLR_OUTPUT_STATE_MODE_CUSTOM:; + drmModeModeInfo mode = {0}; + generate_cvt_mode(&mode, state->custom_mode.width, + state->custom_mode.height, + (float)state->custom_mode.refresh / 1000, false, false); + mode.type = DRM_MODE_TYPE_USERDEF; + memcpy(out, &mode, sizeof(drmModeModeInfo)); + return; + } + } + + struct wlr_drm_mode *mode = (struct wlr_drm_mode *)wlr_mode; + memcpy(out, &mode->drm_mode, sizeof(drmModeModeInfo)); +} + static const int32_t subpixel_map[] = { [DRM_MODE_SUBPIXEL_UNKNOWN] = WL_OUTPUT_SUBPIXEL_UNKNOWN, [DRM_MODE_SUBPIXEL_HORIZONTAL_RGB] = WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB, diff --git a/backend/drm/legacy.c b/backend/drm/legacy.c index dad45253..43436165 100644 --- a/backend/drm/legacy.c +++ b/backend/drm/legacy.c @@ -32,10 +32,12 @@ static bool legacy_crtc_commit(struct wlr_drm_backend *drm, uint32_t *conns = NULL; size_t conns_len = 0; drmModeModeInfo *mode = NULL; + drmModeModeInfo mode_info = {0}; if (active) { conns = &conn->id; conns_len = 1; - mode = &crtc->pending.mode->drm_mode; + drm_connector_state_mode(conn, state, &mode_info); + mode = &mode_info; } uint32_t dpms = active ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF; diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index 64961ab4..4715cbf7 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -41,15 +41,9 @@ struct wlr_drm_plane { union wlr_drm_plane_props props; }; -struct wlr_drm_crtc_state { - struct wlr_drm_mode *mode; -}; - struct wlr_drm_crtc { uint32_t id; - struct wlr_drm_crtc_state pending, current; - // Atomic modesetting only uint32_t mode_id; uint32_t gamma_lut; @@ -161,6 +155,8 @@ struct wlr_drm_fb *plane_get_next_fb(struct wlr_drm_plane *plane); bool drm_connector_state_is_modeset(const struct wlr_output_state *state); bool drm_connector_state_active(struct wlr_drm_connector *conn, const struct wlr_output_state *state); +void drm_connector_state_mode(struct wlr_drm_connector *conn, + const struct wlr_output_state *state, drmModeModeInfo *mode); #define wlr_drm_conn_log(conn, verb, fmt, ...) \ wlr_log(verb, "connector %s: " fmt, conn->name, ##__VA_ARGS__)