diff options
author | Lionel CHAZALLON <longchair@hotmail.com> | 2018-02-24 12:30:05 +0100 |
---|---|---|
committer | Lionel CHAZALLON <longchair@hotmail.com> | 2018-03-05 16:14:36 +0000 |
commit | 56149c0fbb19946050a3249acef4e86e511d3cd4 (patch) | |
tree | 8eb7657b7673964ed3d38994c45c8514050518f9 /src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp | |
parent | 954fe2c35d0b0435b7f0443d917a5145dfd0c2a4 (diff) |
eglfs/kms: Add DRM/KMS atomic support
This commit adds support for DRM atomic to qtbase eglfs/KMS QPA when
libdrm and device supports it.
Compared To legacy DRM API, atomic API allows to update multiple planes
in one vsync. This is the first part of some work that should follow
and allow:
- DRM framebuffer upscaling for embedded devices that have weaker GPUs
- Sharing the drm atomic request if the KMSDevice so that applications
in userland can blend content on overlay in the same vsync loop.
One of the application for DRM atomic and Qt is typically videoplayer
integration at high resolutions (UHD) on embedded devices which cannot
use their GPU to render such videos, but are able to render it to a drm
overlay.
Change-Id: I047adf3e3d07a53440d52c2a7073c9ed054adf34
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp')
-rw-r--r-- | src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp | 65 |
1 files changed, 50 insertions, 15 deletions
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index 4742143121..f16869c009 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -47,6 +47,7 @@ #include <QtCore/QLoggingCategory> #include <QtGui/private/qguiapplication_p.h> +#include <QtGui/private/qtguiglobal_p.h> #include <QtFbSupport/private/qfbvthandler_p.h> #include <errno.h> @@ -243,6 +244,11 @@ void QEglFSKmsGbmScreen::waitForFlip() drmEvent.page_flip_handler = pageFlipHandler; drmHandleEvent(device()->fd(), &drmEvent); } + +#if QT_CONFIG(drm_atomic) + if (device()->hasAtomicSupport()) + device()->atomicReset(); +#endif } void QEglFSKmsGbmScreen::flip() @@ -274,34 +280,63 @@ void QEglFSKmsGbmScreen::flip() QKmsOutput &op(output()); const int fd = device()->fd(); m_flipPending = true; - int ret = drmModePageFlip(fd, + + if (device()->hasAtomicSupport()) { +#if QT_CONFIG(drm_atomic) + drmModeAtomicReq *request = device()->atomic_request(); + if (request) { + drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->framebufferPropertyId, fb->fb); + drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcPropertyId, op.crtc_id); + } +#endif + } else { + int ret = drmModePageFlip(fd, op.crtc_id, fb->fb, DRM_MODE_PAGE_FLIP_EVENT, this); - if (ret) { - qErrnoWarning("Could not queue DRM page flip on screen %s", qPrintable(name())); - m_flipPending = false; - gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next); - m_gbm_bo_next = nullptr; - return; + if (ret) { + qErrnoWarning("Could not queue DRM page flip on screen %s", qPrintable(name())); + m_flipPending = false; + gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next); + m_gbm_bo_next = nullptr; + return; + } } for (CloneDestination &d : m_cloneDests) { if (d.screen != this) { d.screen->ensureModeSet(fb->fb); d.cloneFlipPending = true; - int ret = drmModePageFlip(fd, - d.screen->output().crtc_id, - fb->fb, - DRM_MODE_PAGE_FLIP_EVENT, - d.screen); - if (ret) { - qErrnoWarning("Could not queue DRM page flip for clone screen %s", qPrintable(name())); - d.cloneFlipPending = false; + + if (device()->hasAtomicSupport()) { +#if QT_CONFIG(drm_atomic) + drmModeAtomicReq *request = device()->atomic_request(); + if (request) { + drmModeAtomicAddProperty(request, d.screen->output().eglfs_plane->id, + d.screen->output().eglfs_plane->framebufferPropertyId, fb->fb); + drmModeAtomicAddProperty(request, d.screen->output().eglfs_plane->id, + d.screen->output().eglfs_plane->crtcPropertyId, op.crtc_id); + } +#endif + } else { + int ret = drmModePageFlip(fd, + d.screen->output().crtc_id, + fb->fb, + DRM_MODE_PAGE_FLIP_EVENT, + d.screen); + if (ret) { + qErrnoWarning("Could not queue DRM page flip for clone screen %s", qPrintable(name())); + d.cloneFlipPending = false; + } } } } + +#if QT_CONFIG(drm_atomic) + if (device()->hasAtomicSupport()) + device()->atomicCommit(this); +#endif } void QEglFSKmsGbmScreen::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) |