From 965f429b295939454a9b20ac557feb304d07ef36 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 10 Jul 2024 12:28:38 +0200 Subject: [PATCH] drm: avoid crashes on non-existent modes in restoring after vt --- src/backend/Session.cpp | 3 +++ src/backend/drm/DRM.cpp | 25 +++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/backend/Session.cpp b/src/backend/Session.cpp index c584f01..ac2a5a4 100644 --- a/src/backend/Session.cpp +++ b/src/backend/Session.cpp @@ -396,6 +396,8 @@ void Aquamarine::CSession::handleLibinputEvent(libinput_event* e) { auto eventType = libinput_event_get_type(e); auto data = libinput_device_get_user_data(device); + backend->log(AQ_LOG_TRACE, std::format("libinput: Event {}", (int)eventType)); + if (!data && eventType != LIBINPUT_EVENT_DEVICE_ADDED) { backend->log(AQ_LOG_ERROR, "libinput: No aq device in event and not added"); return; @@ -847,6 +849,7 @@ void Aquamarine::CLibinputDevice::init() { } Aquamarine::CLibinputDevice::~CLibinputDevice() { + libinput_device_set_user_data(device, nullptr); libinput_device_unref(device); } diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index dc2aaa7..4d1065a 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -264,6 +264,8 @@ void Aquamarine::CDRMBackend::restoreAfterVT() { if (!impl->reset()) backend->log(AQ_LOG_ERROR, "drm: failed reset"); + std::vector> noMode; + for (auto& c : connectors) { if (!c->crtc || !c->output) continue; @@ -278,6 +280,12 @@ void Aquamarine::CDRMBackend::restoreAfterVT() { auto& STATE = c->output->state->state(); + if (!STATE.customMode && !STATE.mode) { + backend->log(AQ_LOG_WARNING, "drm: Connector {} has output but state has no mode, will send a reset state event later."); + noMode.emplace_back(c); + continue; + } + if (STATE.mode && STATE.mode->modeInfo.has_value()) data.modeInfo = *STATE.mode->modeInfo; else @@ -309,6 +317,14 @@ void Aquamarine::CDRMBackend::restoreAfterVT() { if (!impl->commit(c, data)) backend->log(AQ_LOG_ERROR, std::format("drm: crtc {} failed restore", c->crtc->id)); } + + for (auto& c : noMode) { + if (!c->output) + continue; + + // tell the consumer to re-set a state because we had no mode + c->output->events.state.emit(IOutput::SStateEvent{}); + } } bool Aquamarine::CDRMBackend::checkFeatures() { @@ -1630,8 +1646,13 @@ uint32_t Aquamarine::CDRMFB::submitBuffer() { } void Aquamarine::SDRMConnectorCommitData::calculateMode(Hyprutils::Memory::CSharedPointer connector) { - const auto& STATE = connector->output->state->state(); - const auto MODE = STATE.mode ? STATE.mode : STATE.customMode; + const auto& STATE = connector->output->state->state(); + const auto MODE = STATE.mode ? STATE.mode : STATE.customMode; + + if (!MODE) { + connector->backend->log(AQ_LOG_ERROR, "drm: no mode in calculateMode??"); + return; + } di_cvt_options options = { .red_blank_ver = DI_CVT_REDUCED_BLANKING_NONE,