diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-08-02 15:10:45 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-09-05 06:33:07 +0000 |
commit | 77a70b2195687ae25e4b7995f0fe213300437922 (patch) | |
tree | 401fa80cc75d27c608c9de70bed0e3f4db9cd3cd /src/plugins/platforms/eglfs/deviceintegration/eglfs_kms | |
parent | 744bb7e85a23210d9a7702427ec2e17dedc68c4d (diff) |
eglfs_kms: Skip modesetting when current is good enough
...unless explicitly requested via QT_QPA_EGLFS_ALWAYS_SET_MODE.
This mirrors the behavior of the EGLDevice backend.
Synchronize the "swap" behavior in other aspects too: do not retry
a failing modeset until infinity, and make the (currently limited but
soon enhanced) plane setup independent of the modesetting.
Task-number: QTBUG-62262
Change-Id: If43c4edf09c526a3d0f566994a3d632c217d2c31
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/plugins/platforms/eglfs/deviceintegration/eglfs_kms')
-rw-r--r-- | src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp | 67 |
1 files changed, 42 insertions, 25 deletions
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index a9fd0adf17..692879cb35 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -132,7 +132,7 @@ QPlatformCursor *QEglFSKmsGbmScreen::cursor() const gbm_surface *QEglFSKmsGbmScreen::createSurface() { if (!m_gbm_surface) { - qCDebug(qLcEglfsKmsDebug) << "Creating gbm_surface for screen" << name(); + qCDebug(qLcEglfsKmsDebug, "Creating gbm_surface for screen %s", qPrintable(name())); m_gbm_surface = gbm_surface_create(static_cast<QEglFSKmsGbmDevice *>(device())->gbmDevice(), rawGeometry().width(), rawGeometry().height(), @@ -179,31 +179,48 @@ void QEglFSKmsGbmScreen::flip() const uint32_t h = op.modes[op.mode].vdisplay; if (!op.mode_set) { - int ret = drmModeSetCrtc(fd, - op.crtc_id, - fb->fb, - 0, 0, - &op.connector_id, 1, - &op.modes[op.mode]); - - if (ret == -1) { - qErrnoWarning(errno, "Could not set DRM mode!"); - } else { - op.mode_set = true; - setPowerState(PowerStateOn); - - if (!op.plane_set) { - op.plane_set = true; - if (op.wants_plane) { - int ret = drmModeSetPlane(fd, op.plane_id, op.crtc_id, - uint32_t(-1), 0, - 0, 0, w, h, - 0 << 16, 0 << 16, w << 16, h << 16); - if (ret == -1) - qErrnoWarning(errno, "drmModeSetPlane failed"); - } + op.mode_set = true; + + bool doModeSet = true; + drmModeCrtcPtr currentMode = drmModeGetCrtc(fd, op.crtc_id); + const bool alreadySet = currentMode && !memcmp(¤tMode->mode, &op.modes[op.mode], sizeof(drmModeModeInfo)); + if (currentMode) + drmModeFreeCrtc(currentMode); + if (alreadySet) { + static bool alwaysDoSet = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ALWAYS_SET_MODE"); + if (!alwaysDoSet) { + qCDebug(qLcEglfsKmsDebug, "Mode already set, skipping modesetting for screen %s", qPrintable(name())); + doModeSet = false; } } + + if (doModeSet) { + qCDebug(qLcEglfsKmsDebug, "Setting mode for screen %s", qPrintable(name())); + int ret = drmModeSetCrtc(fd, + op.crtc_id, + fb->fb, + 0, 0, + &op.connector_id, 1, + &op.modes[op.mode]); + + if (ret == 0) + setPowerState(PowerStateOn); + else + qErrnoWarning(errno, "Could not set DRM mode for screen %s", qPrintable(name())); + } + } + + if (!op.plane_set) { + op.plane_set = true; + if (op.wants_plane) { + qCDebug(qLcEglfsKmsDebug, "Setting plane %u", op.plane_id); + int ret = drmModeSetPlane(fd, op.plane_id, op.crtc_id, + uint32_t(-1), 0, + 0, 0, w, h, + 0 << 16, 0 << 16, w << 16, h << 16); + if (ret) + qErrnoWarning(errno, "drmModeSetPlane failed"); + } } int ret = drmModePageFlip(fd, @@ -212,7 +229,7 @@ void QEglFSKmsGbmScreen::flip() DRM_MODE_PAGE_FLIP_EVENT, this); if (ret) { - qErrnoWarning("Could not queue DRM page flip!"); + qErrnoWarning("Could not queue DRM page flip on screen %s", qPrintable(name())); gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next); m_gbm_bo_next = Q_NULLPTR; } |