summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp')
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
index ecdfb352ab..ef732f9832 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
@@ -114,14 +114,18 @@ public:
: QEglFSWindow(w)
, m_integration(integration)
, m_egl_stream(EGL_NO_STREAM_KHR)
+ , m_framePending(false)
{ }
void invalidateSurface() override;
void resetSurface() override;
+ void flip();
+ static void pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data);
const QEglFSKmsEglDeviceIntegration *m_integration;
EGLStreamKHR m_egl_stream;
EGLint m_latency;
+ bool m_framePending;
};
void QEglFSKmsEglDeviceWindow::invalidateSurface()
@@ -142,6 +146,9 @@ void QEglFSKmsEglDeviceWindow::resetSurface()
streamAttribs[streamAttribCount++] = EGL_STREAM_FIFO_LENGTH_KHR;
streamAttribs[streamAttribCount++] = fifoLength;
}
+
+ streamAttribs[streamAttribCount++] = EGL_CONSUMER_AUTO_ACQUIRE_EXT;
+ streamAttribs[streamAttribCount++] = EGL_FALSE;
streamAttribs[streamAttribCount++] = EGL_NONE;
m_egl_stream = m_integration->m_funcs->create_stream(display, streamAttribs);
@@ -239,6 +246,49 @@ void QEglFSKmsEglDeviceWindow::resetSurface()
qCDebug(qLcEglfsKmsDebug, "Created stream producer surface %p", m_surface);
}
+void QEglFSKmsEglDeviceWindow::flip()
+{
+ EGLDisplay display = screen()->display();
+
+ EGLAttrib acquire_attribs[3] = { EGL_NONE };
+
+ acquire_attribs[0] = EGL_DRM_FLIP_EVENT_DATA_NV;
+ acquire_attribs[1] = (EGLAttrib)this;
+ acquire_attribs[2] = EGL_NONE;
+
+ if (m_egl_stream != EGL_NO_STREAM_KHR)
+ if (!m_integration->m_funcs->acquire_stream_attrib_nv(display, m_egl_stream, acquire_attribs))
+ qWarning("eglStreamConsumerAcquireAttribNV failed: eglError: %x", eglGetError());
+
+ m_framePending = true;
+
+ while (m_framePending) {
+ drmEventContext drmEvent;
+ memset(&drmEvent, 0, sizeof(drmEvent));
+ drmEvent.version = 3;
+ drmEvent.vblank_handler = nullptr;
+ drmEvent.page_flip_handler = pageFlipHandler;
+ drmHandleEvent(m_integration->m_device->fd(), &drmEvent);
+ }
+}
+
+void QEglFSKmsEglDeviceWindow::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+ Q_UNUSED(fd);
+ Q_UNUSED(sequence);
+ Q_UNUSED(tv_sec);
+ Q_UNUSED(tv_usec);
+
+ QEglFSKmsEglDeviceWindow *window = static_cast<QEglFSKmsEglDeviceWindow*>(user_data);
+ window->m_framePending = false;
+}
+
+void QEglFSKmsEglDeviceIntegration::presentBuffer(QPlatformSurface *surface)
+{
+ QEglFSKmsEglDeviceWindow *eglWindow = static_cast<QEglFSKmsEglDeviceWindow*>(surface);
+ eglWindow->flip();
+}
+
QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const
{
QEglFSKmsEglDeviceWindow *eglWindow = new QEglFSKmsEglDeviceWindow(window, this);