[platforms/drm] Properly handle case that mapping the blank buffer fails
Summary: If it's not possible to create a buffer to blank the output, KWin won't be able to render to the output. In that case the output should not be added to the list of outputs. To support this DrmOutput::blank and DrmOutput::init return bool to indicate whether they succeeded. DrmBackend handles this situation and doesn't add the output to the list of outputs if init failed. If after init there are no outputs KWin is in a state where it won't be functional. Thus the platform emits the initFailed signal to terminate. BUG: 365242 FIXED-IN: 5.7.2 Test Plan: No hardware to reproduce the condition Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D2135
This commit is contained in:
parent
aaf8ce16df
commit
cd9a0afafa
3 changed files with 26 additions and 9 deletions
|
@ -237,6 +237,11 @@ void DrmBackend::openDrm()
|
|||
);
|
||||
m_drmId = device->sysNum();
|
||||
queryResources();
|
||||
if (m_outputs.isEmpty()) {
|
||||
qCWarning(KWIN_DRM) << "No outputs, cannot render, will terminate now";
|
||||
emit initFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
// setup udevMonitor
|
||||
if (m_udevMonitor) {
|
||||
|
@ -315,7 +320,11 @@ void DrmBackend::queryResources()
|
|||
drmOutput->m_mode = connector->modes[0];
|
||||
}
|
||||
drmOutput->m_connector = connector->connector_id;
|
||||
drmOutput->init(connector.data());
|
||||
if (!drmOutput->init(connector.data())) {
|
||||
qCWarning(KWIN_DRM) << "Failed to create output for connector " << connector->connector_id;
|
||||
delete drmOutput;
|
||||
continue;
|
||||
}
|
||||
qCDebug(KWIN_DRM) << "Found new output with uuid" << drmOutput->uuid();
|
||||
connectedOutputs << drmOutput;
|
||||
}
|
||||
|
@ -339,7 +348,9 @@ void DrmBackend::queryResources()
|
|||
}
|
||||
m_outputs = connectedOutputs;
|
||||
readOutputsConfiguration();
|
||||
emit screensQueried();
|
||||
if (!m_outputs.isEmpty()) {
|
||||
emit screensQueried();
|
||||
}
|
||||
}
|
||||
|
||||
void DrmBackend::readOutputsConfiguration()
|
||||
|
|
|
@ -180,13 +180,15 @@ static DrmOutput::DpmsMode fromWaylandDpmsMode(KWayland::Server::OutputInterface
|
|||
}
|
||||
}
|
||||
|
||||
void DrmOutput::init(drmModeConnector *connector)
|
||||
bool DrmOutput::init(drmModeConnector *connector)
|
||||
{
|
||||
initEdid(connector);
|
||||
initDpms(connector);
|
||||
initUuid();
|
||||
m_savedCrtc.reset(drmModeGetCrtc(m_backend->fd(), m_crtcId));
|
||||
blank();
|
||||
if (!blank()) {
|
||||
return false;
|
||||
}
|
||||
setDpms(DpmsMode::On);
|
||||
if (!m_waylandOutput.isNull()) {
|
||||
delete m_waylandOutput.data();
|
||||
|
@ -287,6 +289,7 @@ void DrmOutput::init(drmModeConnector *connector)
|
|||
m_waylandOutput->create();
|
||||
qCDebug(KWIN_DRM) << "Created OutputDevice";
|
||||
m_waylandOutputDevice->create();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DrmOutput::initUuid()
|
||||
|
@ -318,14 +321,17 @@ bool DrmOutput::isCurrentMode(const drmModeModeInfo *mode) const
|
|||
&& qstrcmp(mode->name, m_mode.name) == 0;
|
||||
}
|
||||
|
||||
void DrmOutput::blank()
|
||||
bool DrmOutput::blank()
|
||||
{
|
||||
if (!m_blackBuffer) {
|
||||
m_blackBuffer = m_backend->createBuffer(size());
|
||||
m_blackBuffer->map();
|
||||
if (!m_blackBuffer->map()) {
|
||||
cleanupBlackBuffer();
|
||||
return false;
|
||||
}
|
||||
m_blackBuffer->image()->fill(Qt::black);
|
||||
}
|
||||
setMode(m_blackBuffer);
|
||||
return setMode(m_blackBuffer);
|
||||
}
|
||||
|
||||
bool DrmOutput::setMode(DrmBuffer *buffer)
|
||||
|
|
|
@ -61,9 +61,9 @@ public:
|
|||
void moveCursor(const QPoint &globalPos);
|
||||
bool present(DrmBuffer *buffer);
|
||||
void pageFlipped();
|
||||
void init(drmModeConnector *connector);
|
||||
bool init(drmModeConnector *connector);
|
||||
void restoreSaved();
|
||||
void blank();
|
||||
bool blank();
|
||||
|
||||
/**
|
||||
* This sets the changes and tests them against the DRM output
|
||||
|
|
Loading…
Reference in a new issue