Don't remove outputs during page flip

Summary:
To do so leaves a dangling pointer on our pageFlipHandler

BUG: 396272

Test Plan: Wobbled a window whilst plugging a monitor in and out

Reviewers: #kwin

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D14210
This commit is contained in:
David Edmundson 2018-07-18 15:13:38 +01:00
parent 653e98d5ac
commit 9f2f6d9657
3 changed files with 24 additions and 2 deletions

View file

@ -400,7 +400,7 @@ void DrmBackend::updateOutputs()
it = m_outputs.erase(it);
m_enabledOutputs.removeOne(removed);
emit outputRemoved(removed);
delete removed;
removed->teardown();
}
// now check new connections

View file

@ -65,6 +65,15 @@ DrmOutput::DrmOutput(DrmBackend *backend)
DrmOutput::~DrmOutput()
{
Q_ASSERT(!m_pageFlipPending);
if (!m_deleted) {
teardown();
}
}
void DrmOutput::teardown()
{
m_deleted = true;
hideCursor();
m_crtc->blank();
@ -85,6 +94,10 @@ DrmOutput::~DrmOutput()
delete m_waylandOutputDevice.data();
delete m_cursor[0];
delete m_cursor[1];
if (!m_pageFlipPending) {
deleteLater();
} //else will be deleted in the page flip handler
//this is needed so that the pageflipcallback handle isn't deleted
}
void DrmOutput::releaseGbm()
@ -947,6 +960,10 @@ void DrmOutput::updateMode(int modeIndex)
void DrmOutput::pageFlipped()
{
m_pageFlipPending = false;
if (m_deleted) {
deleteLater();
return;
}
if (!m_crtc) {
return;

View file

@ -65,7 +65,10 @@ public:
QByteArray serialNumber;
QSize physicalSize;
};
virtual ~DrmOutput();
///deletes the output, calling this whilst a page flip is pending will result in an error
~DrmOutput() override;
///queues deleting the output after a page flip has completed.
void teardown();
void releaseGbm();
bool showCursor(DrmDumbBuffer *buffer);
bool showCursor();
@ -145,6 +148,7 @@ private:
friend class DrmCrtc; // TODO: For use of setModeLegacy. Remove later when we allow multiple connectors per crtc
// and save the connector ids in the DrmCrtc instance.
DrmOutput(DrmBackend *backend);
bool presentAtomically(DrmBuffer *buffer);
enum class AtomicCommitMode {
@ -214,6 +218,7 @@ private:
int m_cursorIndex = 0;
bool m_hasNewCursor = false;
bool m_internal = false;
bool m_deleted = false;
};
}