summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/eglfs
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2016-12-02 10:39:35 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2016-12-03 00:06:21 +0000
commitf30b88846566bc1254e5e6d61077092cdaeba409 (patch)
tree2b5041bbf2fd7913617b60e2cd5ecfc9955006ff /src/plugins/platforms/eglfs
parent8d0854c2bd7cf371883726cacb3f8c8549a11eac (diff)
eglfs: allow forcing an overlay plane
Add a QT_QPA_EGLFS_KMS_PLANE_INDEX environment variable that applies both to the GBM and EGLDevice backends. When set to a value between 0 and the number of planes on the connector - 1, the chosen overlay plane will be used for output, meaning there will be a drmModeSetPlane to configure, and, in case of EGLDevice, the plane's corresponding EGL layer will get chosen instead of the CRTC's. Task-number: QTBUG-57386 Change-Id: I12c89472ea5730987052f39211fadc597d1302ef Reviewed-by: Pasi Petäjäjärvi <pasi.petajajarvi@qt.io>
Diffstat (limited to 'src/plugins/platforms/eglfs')
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp37
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp15
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp35
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp27
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h3
5 files changed, 89 insertions, 28 deletions
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
index bed775ff81..d4df0dc66e 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
@@ -181,24 +181,41 @@ void QEglFSKmsGbmScreen::flip()
FrameBuffer *fb = framebufferForBufferObject(m_gbm_bo_next);
- if (!output().mode_set) {
- int ret = drmModeSetCrtc(device()->fd(),
- output().crtc_id,
+ QEglFSKmsOutput &op(output());
+ const int fd = device()->fd();
+ const uint32_t w = op.modes[op.mode].hdisplay;
+ const uint32_t h = op.modes[op.mode].vdisplay;
+
+ if (!op.mode_set) {
+ int ret = drmModeSetCrtc(fd,
+ op.crtc_id,
fb->fb,
0, 0,
- &output().connector_id, 1,
- &output().modes[output().mode]);
+ &op.connector_id, 1,
+ &op.modes[op.mode]);
- if (ret) {
- qErrnoWarning("Could not set DRM mode!");
+ if (ret == -1) {
+ qErrnoWarning(errno, "Could not set DRM mode!");
} else {
- output().mode_set = true;
+ 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");
+ }
+ }
}
}
- int ret = drmModePageFlip(device()->fd(),
- output().crtc_id,
+ int ret = drmModePageFlip(fd,
+ op.crtc_id,
fb->fb,
DRM_MODE_PAGE_FLIP_EVENT,
this);
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 b443a724ec..cf1de71831 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
@@ -39,11 +39,11 @@
****************************************************************************/
#include "qeglfskmsegldeviceintegration.h"
+#include "qeglfskmsegldevice.h"
+#include "qeglfskmsegldevicescreen.h"
#include <QtEglSupport/private/qeglconvenience_p.h>
#include "private/qeglfswindow_p.h"
#include "private/qeglfscursor_p.h"
-#include "qeglfskmsegldevice.h"
-#include "qeglfskmsscreen.h"
#include <QLoggingCategory>
#include <private/qmath_p.h>
@@ -171,20 +171,23 @@ void QEglJetsonTK1Window::resetSurface()
return;
}
- QEglFSKmsScreen *cur_screen = static_cast<QEglFSKmsScreen*>(screen());
+ QEglFSKmsEglDeviceScreen *cur_screen = static_cast<QEglFSKmsEglDeviceScreen *>(screen());
Q_ASSERT(cur_screen);
- qCDebug(qLcEglfsKmsDebug, "Searching for id: %d", cur_screen->output().crtc_id);
+ QEglFSKmsOutput &output(cur_screen->output());
+ const uint32_t wantedId = !output.wants_plane ? output.crtc_id : output.plane_id;
+ qCDebug(qLcEglfsKmsDebug, "Searching for id: %d", wantedId);
EGLOutputLayerEXT layer = EGL_NO_OUTPUT_LAYER_EXT;
for (int i = 0; i < actualCount; ++i) {
EGLAttrib id;
if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_CRTC_EXT, &id)) {
qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - crtc %d", i, layers[i], (int) id);
- if (id == EGLAttrib(cur_screen->output().crtc_id))
+ if (id == EGLAttrib(wantedId))
layer = layers[i];
} else if (m_integration->m_funcs->query_output_layer_attrib(display, layers[i], EGL_DRM_PLANE_EXT, &id)) {
- // Not used yet, just for debugging.
qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - plane %d", i, layers[i], (int) id);
+ if (id == EGLAttrib(wantedId))
+ layer = layers[i];
} else {
qCDebug(qLcEglfsKmsDebug, " [%d] layer %p - unknown", i, layers[i]);
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
index 1f672afeb4..3935c99b9e 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
@@ -67,13 +67,16 @@ QPlatformCursor *QEglFSKmsEglDeviceScreen::cursor() const
void QEglFSKmsEglDeviceScreen::waitForFlip()
{
- if (!output().mode_set) {
- output().mode_set = true;
+ QEglFSKmsOutput &op(output());
+ const int fd = device()->fd();
+ const uint32_t w = op.modes[op.mode].hdisplay;
+ const uint32_t h = op.modes[op.mode].vdisplay;
- drmModeCrtcPtr currentMode = drmModeGetCrtc(device()->fd(), output().crtc_id);
- const bool alreadySet = currentMode
- && currentMode->width == output().modes[output().mode].hdisplay
- && currentMode->height == output().modes[output().mode].vdisplay;
+ if (!op.mode_set) {
+ op.mode_set = true;
+
+ drmModeCrtcPtr currentMode = drmModeGetCrtc(fd, op.crtc_id);
+ const bool alreadySet = currentMode && currentMode->width == w && currentMode->height == h;
if (currentMode)
drmModeFreeCrtc(currentMode);
if (alreadySet) {
@@ -87,14 +90,26 @@ void QEglFSKmsEglDeviceScreen::waitForFlip()
}
qCDebug(qLcEglfsKmsDebug, "Setting mode");
- int ret = drmModeSetCrtc(device()->fd(), output().crtc_id,
+ int ret = drmModeSetCrtc(fd, op.crtc_id,
uint32_t(-1), 0, 0,
- &output().connector_id, 1,
- &output().modes[output().mode]);
+ &op.connector_id, 1,
+ &op.modes[op.mode]);
if (ret)
- qFatal("drmModeSetCrtc failed");
+ qErrnoWarning(errno, "drmModeSetCrtc failed");
}
+ 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 == -1)
+ qErrnoWarning(errno, "drmModeSetPlane failed");
+ }
+ }
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp
index b3c1fbb1bd..75dd083750 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp
@@ -329,9 +329,32 @@ QEglFSKmsScreen *QEglFSKmsDevice::createScreenForConnector(drmModeResPtr resourc
drmModeGetCrtc(m_dri_fd, crtc_id),
modes,
connector->subpixel,
- connectorProperty(connector, QByteArrayLiteral("DPMS"))
+ connectorProperty(connector, QByteArrayLiteral("DPMS")),
+ false,
+ 0,
+ false
};
+ bool ok;
+ int idx = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_PLANE_INDEX", &ok);
+ if (ok) {
+ drmModePlaneRes *planeResources = drmModeGetPlaneResources(m_dri_fd);
+ if (planeResources) {
+ if (idx >= 0 && idx < int(planeResources->count_planes)) {
+ drmModePlane *plane = drmModeGetPlane(m_dri_fd, planeResources->planes[idx]);
+ if (plane) {
+ output.wants_plane = true;
+ output.plane_id = plane->plane_id;
+ qCDebug(qLcEglfsKmsDebug, "Forcing plane index %d, plane id %u (belongs to crtc id %u)",
+ idx, plane->plane_id, plane->crtc_id);
+ drmModeFreePlane(plane);
+ }
+ } else {
+ qWarning("Invalid plane index %d, must be between 0 and %u", idx, planeResources->count_planes - 1);
+ }
+ }
+ }
+
m_crtc_allocator |= (1 << output.crtc_id);
m_connector_allocator |= (1 << output.connector_id);
@@ -406,7 +429,7 @@ void QEglFSKmsDevice::createScreens()
if (idx >= 0 && idx < resources->count_connectors)
wantedConnectorIndex = idx;
else
- qWarning("Invalid connector index %d", idx);
+ qWarning("Invalid connector index %d, must be between 0 and %u", idx, resources->count_connectors - 1);
}
for (int i = 0; i < resources->count_connectors; i++) {
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
index 2b6a0ffe6c..fa331f0931 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
@@ -67,6 +67,9 @@ struct QEglFSKmsOutput
QList<drmModeModeInfo> modes;
int subpixel;
drmModePropertyPtr dpms_prop;
+ bool wants_plane;
+ uint32_t plane_id;
+ bool plane_set;
};
class Q_EGLFS_EXPORT QEglFSKmsScreen : public QEglFSScreen