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 <laszlo.agocs@theqtcompany.com>
This commit is contained in:
Pier Luigi Fiorini 2015-07-26 10:57:01 +02:00
parent d71f3e0882
commit e948f97814
4 changed files with 49 additions and 3 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -60,6 +60,7 @@ struct QEglFSKmsOutput
bool mode_set;
drmModeCrtcPtr saved_crtc;
QList<drmModeModeInfo> 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<QPlatformScreen *> m_siblings;
PowerState m_powerState;
struct FrameBuffer {
FrameBuffer() : fb(0) {}
uint32_t fb;