mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-19 06:47:02 -04:00
backend/drm: implement KMS state snapshot/restore
Following ideas from [1], snapshot the entire KMS state when the VT is switched away, and restore it when the VT is switched back. > Well the neat trick is that userspace doesn’t need to be able to > understand properties to save and restore them - the actual property > value transport between kernel and userspace is fully generic. That way, even if another DRM master changes a property we don't understand like CTM or HDR_OUTPUT_METADATA, we can switch it back and avoid getting garbage on screen. [1]: https://blog.ffwll.ch/2016/01/vt-switching-with-atomic-modeset.html
This commit is contained in:
parent
e0b2bf2a6b
commit
f0bb53c4ab
7 changed files with 155 additions and 20 deletions
|
|
@ -55,6 +55,7 @@ static void backend_destroy(struct wlr_backend *backend) {
|
|||
finish_drm_renderer(&drm->mgpu_renderer);
|
||||
}
|
||||
|
||||
drmModeAtomicFree(drm->atomic_snapshot);
|
||||
finish_drm_resources(drm);
|
||||
|
||||
free(drm->name);
|
||||
|
|
@ -101,30 +102,18 @@ static void handle_session_active(struct wl_listener *listener, void *data) {
|
|||
|
||||
if (session->active) {
|
||||
wlr_log(WLR_INFO, "DRM fd resumed");
|
||||
scan_drm_connectors(drm, NULL);
|
||||
|
||||
struct wlr_drm_connector *conn;
|
||||
wl_list_for_each(conn, &drm->connectors, link) {
|
||||
struct wlr_output_mode *mode = NULL;
|
||||
uint32_t committed = WLR_OUTPUT_STATE_ENABLED;
|
||||
if (conn->status != DRM_MODE_DISCONNECTED && conn->output.enabled
|
||||
&& conn->output.current_mode != NULL) {
|
||||
committed |= WLR_OUTPUT_STATE_MODE;
|
||||
mode = conn->output.current_mode;
|
||||
}
|
||||
struct wlr_output_state state = {
|
||||
.committed = committed,
|
||||
.allow_artifacts = true,
|
||||
.enabled = mode != NULL,
|
||||
.mode_type = WLR_OUTPUT_STATE_MODE_FIXED,
|
||||
.mode = mode,
|
||||
};
|
||||
if (!drm_connector_commit_state(conn, &state)) {
|
||||
wlr_drm_conn_log(conn, WLR_ERROR, "Failed to restore state after VT switch");
|
||||
}
|
||||
if (!drm->iface->restore_state(drm)) {
|
||||
wlr_log(WLR_ERROR, "Failed to restore KMS state after VT switch");
|
||||
}
|
||||
|
||||
scan_drm_connectors(drm, NULL);
|
||||
} else {
|
||||
wlr_log(WLR_INFO, "DRM fd paused");
|
||||
|
||||
if (drm->iface->snapshot_state && !drm->iface->snapshot_state(drm)) {
|
||||
wlr_log(WLR_ERROR, "Failed to snapshot KMS state");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue