mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2024-11-21 22:52:20 +00:00
backend/drm: refuse to switch CRTC for enabled connector
match_obj() might return a configuration where the CRTC for an enabled connector is switched to another one. We don't support this correctly: the wlr_output common code would need to query again the supported formats, re-allocate the swapchain, etc. What's more, the kernel doesn't even support this [1]: it requires planes to be disabled to change their CRTC, it rejects commits directly switching the CRTC used by a plane. [1]: https://cgit.freedesktop.org/drm/drm-misc/tree/drivers/gpu/drm/drm_atomic.c?h=6e90293618ed476d6b11f82ce724efbb9e9a071b#n697
This commit is contained in:
parent
99fb2fefc3
commit
bde68b1df7
@ -1087,47 +1087,43 @@ static void realloc_crtcs(struct wlr_drm_backend *drm,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In the case that we add a new connector (hotplug) and we fail to
|
||||
* match everything, we prefer to fail the new connector and keep all
|
||||
* of the old mappings instead.
|
||||
*/
|
||||
// Refuse to remove a CRTC from an enabled connector, and refuse to
|
||||
// change the CRTC of an enabled connector.
|
||||
for (size_t i = 0; i < num_connectors; ++i) {
|
||||
struct wlr_drm_connector *conn = connectors[i];
|
||||
if (conn->status == DRM_MODE_CONNECTED && conn->output.enabled &&
|
||||
connector_match[i] == -1) {
|
||||
if (conn->status != DRM_MODE_CONNECTED || !conn->output.enabled) {
|
||||
continue;
|
||||
}
|
||||
if (connector_match[i] == -1) {
|
||||
wlr_log(WLR_DEBUG, "Could not match a CRTC for previously connected output; "
|
||||
"keeping old configuration");
|
||||
"keeping old configuration");
|
||||
return;
|
||||
}
|
||||
assert(conn->crtc != NULL);
|
||||
if (connector_match[i] != conn->crtc - drm->crtcs) {
|
||||
wlr_log(WLR_DEBUG, "Cannot switch CRTC for enabled output; "
|
||||
"keeping old configuration");
|
||||
return;
|
||||
}
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "State after reallocation:");
|
||||
|
||||
// Apply new configuration
|
||||
wlr_log(WLR_DEBUG, "State after reallocation:");
|
||||
for (size_t i = 0; i < num_connectors; ++i) {
|
||||
struct wlr_drm_connector *conn = connectors[i];
|
||||
bool prev_enabled = conn->crtc;
|
||||
|
||||
wlr_log(WLR_DEBUG, " '%s': crtc=%zd",
|
||||
conn->name, connector_match[i]);
|
||||
|
||||
// We don't need to change anything.
|
||||
if (prev_enabled && connector_match[i] == conn->crtc - drm->crtcs) {
|
||||
if (conn->crtc != NULL && connector_match[i] == conn->crtc - drm->crtcs) {
|
||||
// We don't need to change anything
|
||||
continue;
|
||||
}
|
||||
|
||||
dealloc_crtc(conn);
|
||||
|
||||
if (connector_match[i] == -1) {
|
||||
if (prev_enabled) {
|
||||
wlr_drm_conn_log(conn, WLR_DEBUG, "Output has lost its CRTC");
|
||||
wlr_output_update_enabled(&conn->output, false);
|
||||
wlr_output_update_mode(&conn->output, NULL);
|
||||
}
|
||||
continue;
|
||||
if (connector_match[i] >= 0) {
|
||||
conn->crtc = &drm->crtcs[connector_match[i]];
|
||||
}
|
||||
|
||||
conn->crtc = &drm->crtcs[connector_match[i]];
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user