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