Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qeglfskmsscreen.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
3// Copyright (C) 2016 Pelagicore AG
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5// Qt-Security score:significant reason:default
6
9
10#include <private/qeglfsintegration_p.h>
11#include <private/qeglfskmsintegration_p.h>
12
13#include <QtCore/QMutex>
14#include <QtCore/QLoggingCategory>
15
16#include <QtGui/private/qguiapplication_p.h>
17#include <QtFbSupport/private/qfbvthandler_p.h>
18
20
23
25{
26public:
27 QEglFSKmsInterruptHandler(QEglFSKmsScreen *screen) : m_screen(screen) {
28 m_vtHandler = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration())->vtHandler();
29 connect(m_vtHandler, &QFbVtHandler::interrupted, this, &QEglFSKmsInterruptHandler::restoreVideoMode);
30 connect(m_vtHandler, &QFbVtHandler::aboutToSuspend, this, &QEglFSKmsInterruptHandler::restoreVideoMode);
31 }
32
33public slots:
35
36private:
38 QEglFSKmsScreen *m_screen;
39};
40
41QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsDevice *device, const QKmsOutput &output, bool headless)
42 : QEglFSScreen(static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration())->display())
43 , m_device(device)
44 , m_output(output)
45 , m_cursorOutOfRange(false)
46 , m_powerState(PowerStateOn)
47 , m_interruptHandler(new QEglFSKmsInterruptHandler(this))
48 , m_headless(headless)
49{
50 m_siblings << this; // gets overridden later
51
52 if (m_output.edid_blob) {
53 QByteArray edid(reinterpret_cast<const char *>(m_output.edid_blob->data), m_output.edid_blob->length);
54 if (m_edid.parse(edid))
55 qCDebug(qLcEglfsKmsDebug, "EDID data for output \"%s\": identifier '%s', manufacturer '%s', model '%s', serial '%s', physical size: %.2fx%.2f",
56 name().toLatin1().constData(),
57 m_edid.identifier.toLatin1().constData(),
58 m_edid.manufacturer.toLatin1().constData(),
59 m_edid.model.toLatin1().constData(),
60 m_edid.serialNumber.toLatin1().constData(),
61 m_edid.physicalSize.width(), m_edid.physicalSize.height());
62 else
63 qCDebug(qLcEglfsKmsDebug) << "Failed to parse EDID data for output" << name(); // keep this debug, not warning
64 } else {
65 qCDebug(qLcEglfsKmsDebug) << "No EDID data for output" << name();
66 }
67
68 {
69 QMutexLocker lock(&s_screensMutex);
70 s_screens.insert(this);
71 }
72}
73
74QEglFSKmsScreen::~QEglFSKmsScreen()
75{
76 {
77 QMutexLocker lock(&s_screensMutex);
78 s_screens.remove(this);
79 }
80
81 m_output.cleanup(m_device);
82 delete m_interruptHandler;
83}
84
85void QEglFSKmsScreen::setVirtualPosition(const QPoint &pos)
86{
87 m_pos = pos;
88}
89
90// Reimplement rawGeometry(), not geometry(). The base class implementation of
91// geometry() calls rawGeometry() and may apply additional transforms.
92QRect QEglFSKmsScreen::rawGeometry() const
93{
94 if (m_headless)
95 return QRect(QPoint(0, 0), m_device->screenConfig()->headlessSize());
96
97 return QRect(m_pos.x(), m_pos.y(),
98 m_output.size.width(),
99 m_output.size.height());
100}
101
102int QEglFSKmsScreen::depth() const
103{
104 return format() == QImage::Format_RGB16 ? 16 : 32;
105}
106
107QImage::Format QEglFSKmsScreen::format() const
108{
109 // the result can be slightly incorrect, it won't matter in practice
110 switch (m_output.drm_format) {
111 case DRM_FORMAT_ARGB8888:
112 case DRM_FORMAT_ABGR8888:
113 return QImage::Format_ARGB32;
114 case DRM_FORMAT_RGB565:
115 case DRM_FORMAT_BGR565:
116 return QImage::Format_RGB16;
117 case DRM_FORMAT_XRGB2101010:
118 return QImage::Format_RGB30;
119 case DRM_FORMAT_XBGR2101010:
120 return QImage::Format_BGR30;
121 case DRM_FORMAT_ARGB2101010:
122 return QImage::Format_A2RGB30_Premultiplied;
123 case DRM_FORMAT_ABGR2101010:
124 return QImage::Format_A2BGR30_Premultiplied;
125 default:
126 return QImage::Format_RGB32;
127 }
128}
129
130QSizeF QEglFSKmsScreen::physicalSize() const
131{
132 if (!m_output.physical_size.isEmpty()) {
133 return m_output.physical_size;
134 } else {
135 const QSize s = geometry().size();
136 return QSizeF(0.254 * s.width(), 0.254 * s.height());
137 }
138}
139
140QDpi QEglFSKmsScreen::logicalDpi() const
141{
142 return logicalBaseDpi();
143}
144
145QDpi QEglFSKmsScreen::logicalBaseDpi() const
146{
147 return QDpi(100, 100);
148}
149
150Qt::ScreenOrientation QEglFSKmsScreen::nativeOrientation() const
151{
152 return Qt::PrimaryOrientation;
153}
154
155Qt::ScreenOrientation QEglFSKmsScreen::orientation() const
156{
157 return Qt::PrimaryOrientation;
158}
159
160QString QEglFSKmsScreen::name() const
161{
162 return !m_headless ? m_output.name : QStringLiteral("qt_Headless");
163}
164
165QString QEglFSKmsScreen::manufacturer() const
166{
167 return m_edid.manufacturer;
168}
169
170QString QEglFSKmsScreen::model() const
171{
172 return m_edid.model.isEmpty() ? m_edid.identifier : m_edid.model;
173}
174
175QString QEglFSKmsScreen::serialNumber() const
176{
177 return m_edid.serialNumber;
178}
179
180void QEglFSKmsScreen::waitForFlip()
181{
182}
183
184void QEglFSKmsScreen::updateOutput(QKmsOutput output)
185{
186 m_output = output;
187}
188
189void QEglFSKmsScreen::restoreMode()
190{
191 m_output.restoreMode(m_device);
192}
193
194qreal QEglFSKmsScreen::refreshRate() const
195{
196 if (m_headless)
197 return 60;
198
199 quint32 refresh = m_output.modes[m_output.mode].vrefresh;
200 return refresh > 0 ? refresh : 60;
201}
202
203void QEglFSKmsScreen::removeSibling(QPlatformScreen *screen)
204{
205 m_siblings.removeAll(screen);
206}
207
208QList<QPlatformScreen::Mode> QEglFSKmsScreen::modes() const
209{
210 QList<QPlatformScreen::Mode> list;
211 list.reserve(m_output.modes.size());
212
213 for (const drmModeModeInfo &info : std::as_const(m_output.modes))
214 list.append({QSize(info.hdisplay, info.vdisplay),
215 qreal(info.vrefresh > 0 ? info.vrefresh : 60)});
216
217 return list;
218}
219
220int QEglFSKmsScreen::currentMode() const
221{
222 return m_output.mode;
223}
224
225int QEglFSKmsScreen::preferredMode() const
226{
227 return m_output.preferred_mode;
228}
229
230QPlatformScreen::SubpixelAntialiasingType QEglFSKmsScreen::subpixelAntialiasingTypeHint() const
231{
232 return m_output.subpixelAntialiasingTypeHint();
233}
234
235QPlatformScreen::PowerState QEglFSKmsScreen::powerState() const
236{
237 return m_powerState;
238}
239
240void QEglFSKmsScreen::setPowerState(QPlatformScreen::PowerState state)
241{
242 m_output.setPowerState(m_device, state);
243 m_powerState = state;
244}
245
246/* Informs exact page flip timing which can be used rendering optimization.
247 Consider this is from drm event reader thread. */
248void QEglFSKmsScreen::pageFlipped(unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec)
249{
250 Q_UNUSED(sequence);
251 Q_UNUSED(tv_sec);
252 Q_UNUSED(tv_usec);
253}
254
255bool QEglFSKmsScreen::isScreenKnown(QEglFSKmsScreen *s)
256{
257 QMutexLocker lock(&s_screensMutex);
258 return s_screens.contains(s);
259}
260
261QT_END_NAMESPACE
QEglFSKmsInterruptHandler(QEglFSKmsScreen *screen)
Combined button and popup list for selecting options.
static QSet< QEglFSKmsScreen * > s_screens
static QT_BEGIN_NAMESPACE QMutex s_screensMutex