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