From 3a7d0c395e881000d6f47c09c35c5782e051ad74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Mon, 13 Apr 2015 09:23:03 +0200 Subject: [PATCH] Page flip event support in drm backend --- drm_backend.cpp | 39 ++++++++++++++++++++++++++++++++++++++- drm_backend.h | 2 ++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drm_backend.cpp b/drm_backend.cpp index 51d02cad7e..9617dec433 100644 --- a/drm_backend.cpp +++ b/drm_backend.cpp @@ -18,12 +18,15 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "drm_backend.h" +#include "composite.h" #include "logind.h" #include "scene_qpainter.h" #include "screens_drm.h" #include "udev.h" #include "utils.h" #include "virtual_terminal.h" +// Qt +#include // system #include #include @@ -69,6 +72,17 @@ void DrmBackend::init() VirtualTerminal::create(this); } +void DrmBackend::pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) +{ + Q_UNUSED(fd) + Q_UNUSED(frame) + Q_UNUSED(sec) + Q_UNUSED(usec) + DrmBuffer *buffer = reinterpret_cast(data); + buffer->m_backend->m_pageFlipPending = false; + Compositor::self()->bufferSwapComplete(); +} + void DrmBackend::openDrm() { VirtualTerminal::self()->init(); @@ -83,6 +97,16 @@ void DrmBackend::openDrm() return; } m_fd = fd; + QSocketNotifier *notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); + connect(notifier, &QSocketNotifier::activated, this, + [this] { + drmEventContext e; + memset(&e, 0, sizeof e); + e.version = DRM_EVENT_CONTEXT_VERSION; + e.page_flip_handler = pageFlipHandler; + drmHandleEvent(m_fd, &e); + } + ); m_drmId = device->sysNum(); queryResources(); emit screensQueried(); @@ -129,6 +153,11 @@ void DrmBackend::queryResources() m_crtcId = encoder->crtc_id; m_connector = connector->connector_id; m_mode = crtc->mode; + // TODO: improve + DrmBuffer *b = new DrmBuffer(this, m_resolution); + b->map(); + b->image()->fill(Qt::black); + drmModeSetCrtc(m_fd, m_crtcId, b->m_bufferId, 0, 0, &m_connector, 1, &m_mode); // for the moment only one crtc break; } @@ -136,7 +165,15 @@ void DrmBackend::queryResources() void DrmBackend::present(DrmBuffer *buffer) { - drmModeSetCrtc(m_fd, m_crtcId, buffer->m_bufferId, 0, 0, &m_connector, 1, &m_mode); + if (!buffer || buffer->m_bufferId == 0) { + return; + } + if (m_pageFlipPending) { + return; + } + m_pageFlipPending = true; + Compositor::self()->aboutToSwapBuffers(); + drmModePageFlip(m_fd, m_crtcId, buffer->m_bufferId, DRM_MODE_PAGE_FLIP_EVENT, buffer); } Screens *DrmBackend::createScreens(QObject *parent) diff --git a/drm_backend.h b/drm_backend.h index cee2ca77d4..597ed9b371 100644 --- a/drm_backend.h +++ b/drm_backend.h @@ -58,6 +58,7 @@ Q_SIGNALS: void screensQueried(); private: + static void pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data); void openDrm(); void queryResources(); QScopedPointer m_udev; @@ -68,6 +69,7 @@ private: quint32 m_crtcId = 0; quint32 m_connector = 0; drmModeModeInfo m_mode; + bool m_pageFlipPending = false; }; class DrmBuffer