drm: avoid crashes on non-existent modes in restoring after vt

This commit is contained in:
Vaxry 2024-07-10 12:28:38 +02:00
parent e3f2c0d5cc
commit 965f429b29
2 changed files with 26 additions and 2 deletions

View file

@ -396,6 +396,8 @@ void Aquamarine::CSession::handleLibinputEvent(libinput_event* e) {
auto eventType = libinput_event_get_type(e); auto eventType = libinput_event_get_type(e);
auto data = libinput_device_get_user_data(device); 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) { if (!data && eventType != LIBINPUT_EVENT_DEVICE_ADDED) {
backend->log(AQ_LOG_ERROR, "libinput: No aq device in event and not added"); backend->log(AQ_LOG_ERROR, "libinput: No aq device in event and not added");
return; return;
@ -847,6 +849,7 @@ void Aquamarine::CLibinputDevice::init() {
} }
Aquamarine::CLibinputDevice::~CLibinputDevice() { Aquamarine::CLibinputDevice::~CLibinputDevice() {
libinput_device_set_user_data(device, nullptr);
libinput_device_unref(device); libinput_device_unref(device);
} }

View file

@ -264,6 +264,8 @@ void Aquamarine::CDRMBackend::restoreAfterVT() {
if (!impl->reset()) if (!impl->reset())
backend->log(AQ_LOG_ERROR, "drm: failed reset"); backend->log(AQ_LOG_ERROR, "drm: failed reset");
std::vector<SP<SDRMConnector>> noMode;
for (auto& c : connectors) { for (auto& c : connectors) {
if (!c->crtc || !c->output) if (!c->crtc || !c->output)
continue; continue;
@ -278,6 +280,12 @@ void Aquamarine::CDRMBackend::restoreAfterVT() {
auto& STATE = c->output->state->state(); 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()) if (STATE.mode && STATE.mode->modeInfo.has_value())
data.modeInfo = *STATE.mode->modeInfo; data.modeInfo = *STATE.mode->modeInfo;
else else
@ -309,6 +317,14 @@ void Aquamarine::CDRMBackend::restoreAfterVT() {
if (!impl->commit(c, data)) if (!impl->commit(c, data))
backend->log(AQ_LOG_ERROR, std::format("drm: crtc {} failed restore", c->crtc->id)); 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() { bool Aquamarine::CDRMBackend::checkFeatures() {
@ -1630,8 +1646,13 @@ uint32_t Aquamarine::CDRMFB::submitBuffer() {
} }
void Aquamarine::SDRMConnectorCommitData::calculateMode(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector) { void Aquamarine::SDRMConnectorCommitData::calculateMode(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector) {
const auto& STATE = connector->output->state->state(); const auto& STATE = connector->output->state->state();
const auto MODE = STATE.mode ? STATE.mode : STATE.customMode; 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 = { di_cvt_options options = {
.red_blank_ver = DI_CVT_REDUCED_BLANKING_NONE, .red_blank_ver = DI_CVT_REDUCED_BLANKING_NONE,