Commit 6703bc9d authored by Xaver Hugl's avatar Xaver Hugl
Browse files

Improve teardown of DrmGpu

parent ae8e69b4
......@@ -73,13 +73,7 @@ DrmBackend::DrmBackend(QObject *parent)
DrmBackend::~DrmBackend()
{
if (m_gpus.size() > 0) {
// wait for pageflips
while (m_pageFlipsPending != 0) {
QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
}
qDeleteAll(m_gpus);
}
qDeleteAll(m_gpus);
}
void DrmBackend::init()
......@@ -185,8 +179,6 @@ void DrmBackend::reactivate()
o->moveCursor();
}
}
// restart compositor
m_pageFlipsPending = 0;
for (DrmOutput *output : qAsConst(m_outputs)) {
output->renderLoop()->uninhibit();
......@@ -238,9 +230,7 @@ void DrmBackend::pageFlipHandler(int fd, unsigned int frame, unsigned int sec, u
Q_UNUSED(frame)
auto output = static_cast<DrmOutput *>(data);
DrmGpu *gpu = output->gpu();
DrmBackend *backend = output->m_backend;
std::chrono::nanoseconds timestamp = convertTimestamp(gpu->presentationClock(),
CLOCK_MONOTONIC,
......@@ -252,8 +242,6 @@ void DrmBackend::pageFlipHandler(int fd, unsigned int frame, unsigned int sec, u
}
output->pageFlipped();
backend->m_pageFlipsPending--;
RenderLoopPrivate *renderLoopPrivate = RenderLoopPrivate::get(output->renderLoop());
renderLoopPrivate->notifyFrameCompleted(timestamp);
}
......@@ -538,7 +526,6 @@ bool DrmBackend::present(DrmBuffer *buffer, DrmOutput *output)
}
if (output->present(buffer)) {
m_pageFlipsPending++;
return true;
} else if (output->gpu()->deleteBufferAfterPageFlip()) {
delete buffer;
......
......@@ -115,7 +115,6 @@ private:
// active and enabled pipelines (above + wl_output)
QVector<DrmOutput*> m_enabledOutputs;
int m_pageFlipsPending = 0;
bool m_active = false;
QVector<DrmGpu*> m_gpus;
QScopedPointer<DpmsInputEventFilter> m_dpmsFilter;
......
......@@ -68,6 +68,7 @@ DrmGpu::DrmGpu(DrmBackend *backend, QByteArray devNode, int fd, int drmId) : m_b
DrmGpu::~DrmGpu()
{
waitIdle();
if (m_eglDisplay != EGL_NO_DISPLAY) {
eglTerminate(m_eglDisplay);
}
......@@ -325,4 +326,34 @@ void DrmGpu::dispatchEvents()
drmHandleEvent(m_fd, &context);
}
void DrmGpu::waitIdle()
{
m_socketNotifier->setEnabled(false);
while (true) {
const bool idle = std::all_of(m_outputs.constBegin(), m_outputs.constEnd(), [](DrmOutput *output){
return !output->m_pageFlipPending;
});
if (idle) {
break;
}
fd_set set;
FD_ZERO(&set);
FD_SET(m_fd, &set);
timeval timeout;
timeout.tv_sec = 30;
timeout.tv_usec = 0;
const int descriptorCount = select(m_fd + 1, &set, nullptr, nullptr, &timeout);
if (descriptorCount < 0) {
qCWarning(KWIN_DRM) << "select() in DrmGpu::waitIdle failed:" << strerror(errno);
break;
} else if (FD_ISSET(m_fd, &set)) {
dispatchEvents();
} else {
qCWarning(KWIN_DRM) << "No drm events for gpu" << m_devNode << "within last 30 seconds";
break;
}
};
m_socketNotifier->setEnabled(true);
}
}
......@@ -104,6 +104,8 @@ public:
*/
clockid_t presentationClock() const;
void waitIdle();
Q_SIGNALS:
void outputAdded(DrmOutput *output);
void outputRemoved(DrmOutput *output);
......
......@@ -834,6 +834,7 @@ bool DrmOutput::presentLegacy(DrmBuffer *buffer)
const bool ok = drmModePageFlip(m_gpu->fd(), m_crtc->id(), buffer->bufferId(), DRM_MODE_PAGE_FLIP_EVENT, this) == 0;
if (ok) {
m_crtc->setNext(buffer);
m_pageFlipPending = true;
} else {
qCWarning(KWIN_DRM) << "Page flip failed:" << strerror(errno);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment