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
qvkkhrdisplayintegration.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
7
8#include <qpa/qplatformwindow.h>
9#include <qpa/qplatformbackingstore.h>
10#include <qpa/qplatforminputcontextfactory_p.h>
11#include <qpa/qwindowsysteminterface.h>
12
13#include <QtGui/private/qguiapplication_p.h>
14#include <QtGui/private/qwindow_p.h>
15#include <QtGui/private/qgenericunixeventdispatcher_p.h>
16#include <QtGui/private/qgenericunixfontdatabase_p.h>
17#include <QtGui/private/qgenericunixtheme_p.h>
18#include <qpa/qplatformservices.h>
19
20#include <QtFbSupport/private/qfbvthandler_p.h>
21
22#if QT_CONFIG(libinput)
23#include <QtInputSupport/private/qlibinputhandler_p.h>
24#endif
25
26#if QT_CONFIG(evdev)
27#include <QtInputSupport/private/qevdevmousemanager_p.h>
28#include <QtInputSupport/private/qevdevkeyboardmanager_p.h>
29#include <QtInputSupport/private/qevdevtouchmanager_p.h>
30#endif
31
32#if QT_CONFIG(tslib)
33#include <QtInputSupport/private/qtslib_p.h>
34#endif
35
37
38using namespace Qt::StringLiterals;
39
41{
42public:
43 QRect geometry() const override { return m_geometry; }
44 int depth() const override { return m_depth; }
45 QImage::Format format() const override { return m_format; }
46 QString name() const override { return m_name; }
47 QSizeF physicalSize() const override;
49
50private:
51 QVkKhrDisplayVulkanInstance *m_vk = nullptr;
52 QRect m_geometry;
53 QString m_name;
54 QSizeF m_physicalSize;
55 int m_depth = 32;
56 QImage::Format m_format = QImage::Format_ARGB32_Premultiplied;
58};
59
61{
62 // The physical dimensions are zero when not known (or until the
63 // QVulkanInstance initializes), fall back to the default then.
64 if (m_physicalSize.isEmpty())
65 return QPlatformScreen::physicalSize();
66 return m_physicalSize;
67}
68
70{
71 m_vk = inst;
72 m_name = m_vk->displayName();
73 m_physicalSize = m_vk->physicalSize();
74 m_geometry = QRect(QPoint(0, 0), m_vk->displaySize());
75 QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry, m_geometry);
76 qCDebug(qLcVkKhrDisplay) << "Screen will report name" << m_name << "geometry" << m_geometry
77 << "physical size" << m_physicalSize;
78
79 // Thanks to this deferred screen setup, a QWindow with a size based on the
80 // dummy screen size may already exist. Try to resize it.
81 QScreen *thisScreen = screen();
82 const auto windows = QGuiApplication::allWindows();
83 for (QWindow *window : windows) {
84 if (window->isTopLevel() && window->screen() == thisScreen)
85 window->handle()->setGeometry(QRect()); // set fullscreen geometry
86 }
87}
88
90{
91public:
94
96
97 void setGeometry(const QRect &r) override;
98
99private:
100 VkSurfaceKHR m_surface = VK_NULL_HANDLE;
101};
102
104{
105 if (m_surface) {
106 QVulkanInstance *inst = window()->vulkanInstance();
107 if (inst)
108 static_cast<QVkKhrDisplayVulkanInstance *>(inst->handle())->destroySurface(m_surface);
109 }
110}
111
113{
114 if (m_surface)
115 return &m_surface;
116
117 QVulkanInstance *inst = window()->vulkanInstance();
118 if (!inst) {
119 qWarning("Attempted to create Vulkan surface without an instance; was QWindow::setVulkanInstance() called?");
120 return nullptr;
121 }
122 QVkKhrDisplayVulkanInstance *vkdinst = static_cast<QVkKhrDisplayVulkanInstance *>(inst->handle());
123 m_surface = vkdinst->createSurface(window());
124
125 return &m_surface;
126}
127
129{
130 // We only support full-screen windows
131 QRect rect(screen()->availableGeometry());
132 QWindowSystemInterface::handleGeometryChange(window(), rect);
133 QPlatformWindow::setGeometry(rect);
134
135 const QRect lastReportedGeometry = qt_window_private(window())->geometry;
136 if (rect != lastReportedGeometry)
137 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), rect.size()));
138}
139
140// does not actually support raster content, just paint into a QImage and that's it for now
142{
143public:
145
146 QPaintDevice *paintDevice() override { return &m_image; }
147 void flush(QWindow *window, const QRegion &region, const QPoint &offset) override {
148 Q_UNUSED(window);
149 Q_UNUSED(region);
150 Q_UNUSED(offset);
151 }
152 void resize(const QSize &size, const QRegion &staticContents) override {
153 Q_UNUSED(staticContents);
154 QImage::Format format = QGuiApplication::primaryScreen()->handle()->format();
155 if (m_image.size() != size)
156 m_image = QImage(size, format);
157 }
158
159private:
160 QImage m_image;
161};
162
164{
165 Q_UNUSED(parameters);
166}
167
169{
170 QWindowSystemInterface::handleScreenRemoved(m_primaryScreen);
171 delete m_services;
172 delete m_fontDatabase;
173 delete m_vtHandler;
174}
175
176bool QVkKhrDisplayIntegration::hasCapability(QPlatformIntegration::Capability cap) const
177{
178 switch (cap) {
179 case ThreadedPixmaps: return true;
180 case WindowManagement: return false;
181 default: return QPlatformIntegration::hasCapability(cap);
182 }
183}
184
186{
187 m_primaryScreen = new QVkKhrDisplayScreen;
188
189 // The real values are only known when the QVulkanInstance initializes, use
190 // dummy values until then.
191 m_primaryScreen->m_geometry = QRect(0, 0, 1920, 1080);
192 m_primaryScreen->m_depth = 32;
193 m_primaryScreen->m_format = QImage::Format_ARGB32_Premultiplied;
194
195 QWindowSystemInterface::handleScreenAdded(m_primaryScreen);
196
197 m_inputContext = QPlatformInputContextFactory::create();
198
199 m_vtHandler = new QFbVtHandler;
200
201 if (!qEnvironmentVariableIntValue("QT_QPA_DISABLE_INPUT"))
202 createInputHandlers();
203}
204
206{
207 if (!m_fontDatabase)
208 m_fontDatabase = new QGenericUnixFontDatabase;
209
210 return m_fontDatabase;
211}
212
214{
215 if (!m_services)
216 m_services = new QPlatformServices;
217
218 return m_services;
219}
220
222{
223 return m_inputContext;
224}
225
227{
228 return QGenericUnixTheme::createUnixTheme(name);
229}
230
235
237{
238 if (window->surfaceType() != QSurface::VulkanSurface) {
239 qWarning("vkkhrdisplay platform plugin only supports QWindow with surfaceType == VulkanSurface");
240 // Assume VulkanSurface, better than crashing. Consider e.g. an autotest
241 // creating a default QWindow just to have something to be used with
242 // QRhi's Null backend. Continuing to set up a Vulkan window (even
243 // though the request was Raster or something) is better than failing to
244 // create a platform window, and may even be sufficient in some cases.
245 }
246
248 w->setGeometry(QRect()); // set fullscreen geometry
249 w->requestActivateWindow();
250 return w;
251}
252
257
259{
260 return createUnixEventDispatcher();
261}
262
263void QVkKhrDisplayIntegration::handleInstanceCreated(QVkKhrDisplayVulkanInstance *inst, void *userData)
264{
265 QVkKhrDisplayIntegration *self = static_cast<QVkKhrDisplayIntegration *>(userData);
266 self->m_primaryScreen->setVk(inst);
267}
268
270{
272 inst->setCreatedCallback(handleInstanceCreated, const_cast<QVkKhrDisplayIntegration *>(this));
273 return inst;
274}
275
279
280static int resourceType(const QByteArray &key)
281{
282 static const QByteArray names[] = { // match ResourceType
283 QByteArrayLiteral("vksurface")
284 };
285 const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
286 const QByteArray *result = std::find(names, end, key);
287 if (result == end)
288 result = std::find(names, end, key.toLower());
289 return int(result - names);
290}
291
292void *QVkKhrDisplayIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
293{
294 void *result = nullptr;
295
296 switch (resourceType(resource)) {
297 case VkSurface:
298 if (window && window->handle() && window->surfaceType() == QSurface::VulkanSurface)
299 result = static_cast<QVkKhrDisplayWindow *>(window->handle())->vulkanSurfacePtr();
300 break;
301 default:
302 break;
303 }
304
305 return result;
306}
307
308void QVkKhrDisplayIntegration::createInputHandlers()
309{
310#if QT_CONFIG(libinput)
311 if (!qEnvironmentVariableIntValue("QT_QPA_NO_LIBINPUT")) {
312 new QLibInputHandler("libinput"_L1, QString());
313 return;
314 }
315#endif
316
317#if QT_CONFIG(tslib)
318 bool useTslib = qEnvironmentVariableIntValue("QT_QPA_TSLIB");
319 if (useTslib)
320 new QTsLibMouseHandler("TsLib"_L1, QString());
321#endif
322
323#if QT_CONFIG(evdev)
324 new QEvdevKeyboardManager("EvdevKeyboard"_L1, QString(), this);
325 new QEvdevMouseManager("EvdevMouse"_L1, QString(), this);
326#if QT_CONFIG(tslib)
327 if (!useTslib)
328#endif
329 new QEvdevTouchManager("EvdevTouch"_L1, QString() /* spec */, this);
330#endif
331}
332
333QT_END_NAMESPACE
void flush(QWindow *window, const QRegion &region, const QPoint &offset) override
Flushes the given region from the specified window.
QPaintDevice * paintDevice() override
Implement this function to return the appropriate paint device.
void resize(const QSize &size, const QRegion &staticContents) override
bool hasCapability(QPlatformIntegration::Capability cap) const override
QPlatformBackingStore * createPlatformBackingStore(QWindow *window) const override
Factory function for QPlatformBackingStore.
QPlatformTheme * createPlatformTheme(const QString &name) const override
QVkKhrDisplayIntegration(const QStringList &parameters)
QPlatformVulkanInstance * createPlatformVulkanInstance(QVulkanInstance *instance) const override
QPlatformServices * services() const override
QPlatformInputContext * inputContext() const override
Returns the platforms input context.
QPlatformNativeInterface * nativeInterface() const override
QPlatformFontDatabase * fontDatabase() const override
Accessor for the platform integration's fontdatabase.
QAbstractEventDispatcher * createEventDispatcher() const override
Factory function for the GUI event dispatcher.
void initialize() override
Performs initialization steps that depend on having an event dispatcher available.
void * nativeResourceForWindow(const QByteArray &resource, QWindow *window) override
QPlatformWindow * createPlatformWindow(QWindow *window) const override
Factory function for QPlatformWindow.
QRect geometry() const override
Reimplement in subclass to return the pixel geometry of the screen.
QImage::Format format() const override
Reimplement in subclass to return the image format which corresponds to the screen format.
void setVk(QVkKhrDisplayVulkanInstance *inst)
int depth() const override
Reimplement in subclass to return current depth of the screen.
QSizeF physicalSize() const override
Reimplement this function in subclass to return the physical size of the screen, in millimeters.
QString name() const override
void setCreatedCallback(CreatedCallback callback, void *userData)
void setGeometry(const QRect &r) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
Combined button and popup list for selecting options.
static int resourceType(const QByteArray &key)