From e948f97814175d2e28ac4dba37f8e49b8775b2cf Mon Sep 17 00:00:00 2001 From: Pier Luigi Fiorini Date: Sun, 26 Jul 2015 10:57:01 +0200 Subject: eglfs_kms: Implement DPMS mode Implement the new QPlatformScreen API for power state. [ChangeLog][QPA][eglfs][kms] Allow to set DPMS mode and get the current value for each screen. Change-Id: I5abfb53c3e2f6579a2d6ff19d780b67f424903bf Reviewed-by: Laszlo Agocs --- .../eglfs_kms/qeglfskmsdevice.cpp | 19 +++++++++++++++- .../deviceintegration/eglfs_kms/qeglfskmsdevice.h | 1 + .../eglfs_kms/qeglfskmsscreen.cpp | 26 ++++++++++++++++++++-- .../deviceintegration/eglfs_kms/qeglfskmsscreen.h | 6 +++++ 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp index 0fa191ea60..f3df1f8445 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp @@ -283,7 +283,8 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr selected_mode, false, drmModeGetCrtc(m_dri_fd, crtc_id), - modes + modes, + connectorProperty(connector, QByteArrayLiteral("DPMS")) }; m_crtc_allocator |= (1 << output.crtc_id); @@ -292,6 +293,22 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr return new QEglFSKmsScreen(m_integration, this, output, pos); } +drmModePropertyPtr QEglFSKmsDevice::connectorProperty(drmModeConnectorPtr connector, const QByteArray &name) +{ + drmModePropertyPtr prop; + + for (int i = 0; i < connector->count_props; i++) { + prop = drmModeGetProperty(m_dri_fd, connector->props[i]); + if (!prop) + continue; + if (strcmp(prop->name, name.constData()) == 0) + return prop; + drmModeFreeProperty(prop); + } + + return Q_NULLPTR; +} + void QEglFSKmsDevice::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) { Q_UNUSED(fd); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h index 23fca934e5..411f9a7200 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h @@ -78,6 +78,7 @@ private: int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector); QEglFSKmsScreen *screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos); + drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name); static void pageFlipHandler(int fd, unsigned int sequence, diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp index b3e3f06f6c..227c8f9a62 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp @@ -119,6 +119,7 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration, , m_output(output) , m_pos(position) , m_cursor(Q_NULLPTR) + , m_powerState(PowerStateOn) , m_interruptHandler(new QEglFSKmsInterruptHandler(this)) { m_siblings << this; @@ -126,6 +127,10 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration, QEglFSKmsScreen::~QEglFSKmsScreen() { + if (m_output.dpms_prop) { + drmModeFreeProperty(m_output.dpms_prop); + m_output.dpms_prop = Q_NULLPTR; + } restoreMode(); if (m_output.saved_crtc) { drmModeFreeCrtc(m_output.saved_crtc); @@ -266,10 +271,12 @@ void QEglFSKmsScreen::flip() &m_output.connector_id, 1, &m_output.modes[m_output.mode]); - if (ret) + if (ret) { qErrnoWarning("Could not set DRM mode!"); - else + } else { m_output.mode_set = true; + setPowerState(PowerStateOn); + } } int ret = drmModePageFlip(m_device->fd(), @@ -314,4 +321,19 @@ qreal QEglFSKmsScreen::refreshRate() const return refresh > 0 ? refresh : 60; } +QPlatformScreen::PowerState QEglFSKmsScreen::powerState() const +{ + return m_powerState; +} + +void QEglFSKmsScreen::setPowerState(QPlatformScreen::PowerState state) +{ + if (!m_output.dpms_prop) + return; + + drmModeConnectorSetProperty(m_device->fd(), m_output.connector_id, + m_output.dpms_prop->prop_id, (int)state); + m_powerState = state; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h index 4c1b0d02ad..2ce8700478 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h @@ -60,6 +60,7 @@ struct QEglFSKmsOutput bool mode_set; drmModeCrtcPtr saved_crtc; QList modes; + drmModePropertyPtr dpms_prop; }; class QEglFSKmsScreen : public QEglFSScreen @@ -103,6 +104,9 @@ public: QEglFSKmsOutput &output() { return m_output; } void restoreMode(); + QPlatformScreen::PowerState powerState() const Q_DECL_OVERRIDE; + void setPowerState(QPlatformScreen::PowerState state) Q_DECL_OVERRIDE; + private: QEglFSKmsIntegration *m_integration; QEglFSKmsDevice *m_device; @@ -117,6 +121,8 @@ private: QList m_siblings; + PowerState m_powerState; + struct FrameBuffer { FrameBuffer() : fb(0) {} uint32_t fb; -- cgit v1.2.3