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