eglfs_kms: Decode EDID blob

Retrieve and parse EDID blob.
Return screen product information from EDID.

[ChangeLog][QPA][eglfs][kms] Add screen product information from EDID.

Change-Id: I766999afd9298e82f6147fdeba5d14757bfb4b03
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
bb10
Pier Luigi Fiorini 2016-12-14 07:21:44 +01:00
parent 5f7ab88055
commit 3792ab804d
7 changed files with 66 additions and 4 deletions

View File

@ -336,6 +336,7 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
modes,
connector->subpixel,
connectorProperty(connector, QByteArrayLiteral("DPMS")),
connectorPropertyBlob(connector, QByteArrayLiteral("EDID")),
false,
0,
false
@ -383,6 +384,23 @@ drmModePropertyPtr QKmsDevice::connectorProperty(drmModeConnectorPtr connector,
return Q_NULLPTR;
}
drmModePropertyBlobPtr QKmsDevice::connectorPropertyBlob(drmModeConnectorPtr connector, const QByteArray &name)
{
drmModePropertyPtr prop;
drmModePropertyBlobPtr blob = nullptr;
for (int i = 0; i < connector->count_props && !blob; i++) {
prop = drmModeGetProperty(m_dri_fd, connector->props[i]);
if (!prop)
continue;
if ((prop->flags & DRM_MODE_PROP_BLOB) && (strcmp(prop->name, name.constData()) == 0))
blob = drmModeGetPropertyBlob(m_dri_fd, connector->prop_values[i]);
drmModeFreeProperty(prop);
}
return blob;
}
QKmsDevice::QKmsDevice(QKmsScreenConfig *screenConfig, const QString &path)
: m_screenConfig(screenConfig)
, m_path(path)
@ -627,6 +645,11 @@ void QKmsOutput::cleanup(QKmsDevice *device)
dpms_prop = nullptr;
}
if (edid_blob) {
drmModeFreePropertyBlob(edid_blob);
edid_blob = nullptr;
}
restoreMode(device);
if (saved_crtc) {

View File

@ -107,6 +107,7 @@ struct QKmsOutput
QList<drmModeModeInfo> modes;
int subpixel;
drmModePropertyPtr dpms_prop;
drmModePropertyBlobPtr edid_blob;
bool wants_plane;
uint32_t plane_id;
bool plane_set;
@ -154,6 +155,7 @@ protected:
drmModeConnectorPtr connector,
VirtualDesktopInfo *vinfo);
drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name);
drmModePropertyBlobPtr connectorPropertyBlob(drmModeConnectorPtr connector, const QByteArray &name);
QKmsScreenConfig *m_screenConfig;
QString m_path;

View File

@ -4,7 +4,7 @@ PLUGIN_TYPE = egldeviceintegrations
PLUGIN_CLASS_NAME = QEglFSKmsGbmIntegrationPlugin
load(qt_plugin)
QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private kms_support-private
QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private kms_support-private edid_support-private
INCLUDEPATH += $$PWD/../../api $$PWD/../eglfs_kms_support

View File

@ -1,6 +1,6 @@
TARGET = qeglfs-kms-egldevice-integration
QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private kms_support-private
QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private kms_support-private edid_support-private
INCLUDEPATH += $$PWD/../../api $$PWD/../eglfs_kms_support

View File

@ -2,7 +2,7 @@ TARGET = QtEglFsKmsSupport
CONFIG += no_module_headers internal_module
load(qt_module)
QT += core-private gui-private eglfsdeviceintegration-private kms_support-private
QT += core-private gui-private eglfsdeviceintegration-private kms_support-private edid_support-private
INCLUDEPATH += $$PWD/../../api

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Pelagicore AG
** Contact: https://www.qt.io/licensing/
@ -76,6 +76,22 @@ QEglFSKmsScreen::QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output)
, m_interruptHandler(new QEglFSKmsInterruptHandler(this))
{
m_siblings << this; // gets overridden later
if (m_output.edid_blob) {
QByteArray edid(reinterpret_cast<const char *>(m_output.edid_blob->data), m_output.edid_blob->length);
if (m_edid.parse(edid))
qCDebug(qLcEglfsKmsDebug, "EDID data for output \"%s\": identifier '%s', manufacturer '%s', model '%s', serial '%s', physical size: %.2fx%.2f",
name().toLatin1().constData(),
m_edid.identifier.toLatin1().constData(),
m_edid.manufacturer.toLatin1().constData(),
m_edid.model.toLatin1().constData(),
m_edid.serialNumber.toLatin1().constData(),
m_edid.physicalSize.width(), m_edid.physicalSize.height());
else
qCWarning(qLcEglfsKmsDebug) << "Failed to parse EDID data for output" << name();
} else {
qCWarning(qLcEglfsKmsDebug) << "No EDID data for output" << name();
}
}
QEglFSKmsScreen::~QEglFSKmsScreen()
@ -146,6 +162,21 @@ QString QEglFSKmsScreen::name() const
return m_output.name;
}
QString QEglFSKmsScreen::manufacturer() const
{
return m_edid.manufacturer;
}
QString QEglFSKmsScreen::model() const
{
return m_edid.model.isEmpty() ? m_edid.identifier : m_edid.model;
}
QString QEglFSKmsScreen::serialNumber() const
{
return m_edid.serialNumber;
}
void QEglFSKmsScreen::destroySurface()
{
}

View File

@ -47,6 +47,7 @@
#include <QtCore/QMutex>
#include <QtKmsSupport/private/qkmsdevice_p.h>
#include <QtEdidSupport/private/qedidparser_p.h>
QT_BEGIN_NAMESPACE
@ -72,6 +73,10 @@ public:
QString name() const override;
QString manufacturer() const override;
QString model() const override;
QString serialNumber() const override;
qreal refreshRate() const override;
QList<QPlatformScreen *> virtualSiblings() const override { return m_siblings; }
@ -102,6 +107,7 @@ protected:
QKmsDevice *m_device;
QKmsOutput m_output;
QEdidParser m_edid;
QPoint m_pos;
QList<QPlatformScreen *> m_siblings;