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 void setVk(QVkKhrDisplayVulkanInstance *inst);
47
48private:
49 QVkKhrDisplayVulkanInstance *m_vk = nullptr;
50 QRect m_geometry;
51 int m_depth = 32;
52 QImage::Format m_format = QImage::Format_ARGB32_Premultiplied;
54};
55
56void QVkKhrDisplayScreen::setVk(QVkKhrDisplayVulkanInstance *inst)
57{
58 m_vk = inst;
59 m_geometry = QRect(QPoint(0, 0), m_vk->displaySize());
60 QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry, m_geometry);
61 qDebug() << "Screen will report geometry" << m_geometry;
62
63 // Thanks to this deferred screen setup, a QWindow with a size based on the
64 // dummy screen size may already exist. Try to resize it.
65 QScreen *thisScreen = screen();
66 const auto windows = QGuiApplication::allWindows();
67 for (QWindow *window : windows) {
68 if (window->isTopLevel() && window->screen() == thisScreen)
69 window->handle()->setGeometry(QRect()); // set fullscreen geometry
70 }
71}
72
74{
75public:
78
80
81 void setGeometry(const QRect &r) override;
82
83private:
84 VkSurfaceKHR m_surface = VK_NULL_HANDLE;
85};
86
88{
89 if (m_surface) {
90 QVulkanInstance *inst = window()->vulkanInstance();
91 if (inst)
92 static_cast<QVkKhrDisplayVulkanInstance *>(inst->handle())->destroySurface(m_surface);
93 }
94}
95
97{
98 if (m_surface)
99 return &m_surface;
100
101 QVulkanInstance *inst = window()->vulkanInstance();
102 if (!inst) {
103 qWarning("Attempted to create Vulkan surface without an instance; was QWindow::setVulkanInstance() called?");
104 return nullptr;
105 }
106 QVkKhrDisplayVulkanInstance *vkdinst = static_cast<QVkKhrDisplayVulkanInstance *>(inst->handle());
107 m_surface = vkdinst->createSurface(window());
108
109 return &m_surface;
110}
111
113{
114 // We only support full-screen windows
115 QRect rect(screen()->availableGeometry());
116 QWindowSystemInterface::handleGeometryChange(window(), rect);
117 QPlatformWindow::setGeometry(rect);
118
119 const QRect lastReportedGeometry = qt_window_private(window())->geometry;
120 if (rect != lastReportedGeometry)
121 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), rect.size()));
122}
123
124// does not actually support raster content, just paint into a QImage and that's it for now
126{
127public:
129
130 QPaintDevice *paintDevice() override { return &m_image; }
131 void flush(QWindow *window, const QRegion &region, const QPoint &offset) override {
132 Q_UNUSED(window);
133 Q_UNUSED(region);
134 Q_UNUSED(offset);
135 }
136 void resize(const QSize &size, const QRegion &staticContents) override {
137 Q_UNUSED(staticContents);
138 QImage::Format format = QGuiApplication::primaryScreen()->handle()->format();
139 if (m_image.size() != size)
140 m_image = QImage(size, format);
141 }
142
143private:
144 QImage m_image;
145};
146
148{
149 Q_UNUSED(parameters);
150}
151
153{
154 QWindowSystemInterface::handleScreenRemoved(m_primaryScreen);
155 delete m_services;
156 delete m_fontDatabase;
157 delete m_vtHandler;
158}
159
160bool QVkKhrDisplayIntegration::hasCapability(QPlatformIntegration::Capability cap) const
161{
162 switch (cap) {
163 case ThreadedPixmaps: return true;
164 case WindowManagement: return false;
165 default: return QPlatformIntegration::hasCapability(cap);
166 }
167}
168
170{
171 m_primaryScreen = new QVkKhrDisplayScreen;
172
173 // The real values are only known when the QVulkanInstance initializes, use
174 // dummy values until then.
175 m_primaryScreen->m_geometry = QRect(0, 0, 1920, 1080);
176 m_primaryScreen->m_depth = 32;
177 m_primaryScreen->m_format = QImage::Format_ARGB32_Premultiplied;
178
179 QWindowSystemInterface::handleScreenAdded(m_primaryScreen);
180
181 m_inputContext = QPlatformInputContextFactory::create();
182
183 m_vtHandler = new QFbVtHandler;
184
185 if (!qEnvironmentVariableIntValue("QT_QPA_DISABLE_INPUT"))
186 createInputHandlers();
187}
188
190{
191 if (!m_fontDatabase)
192 m_fontDatabase = new QGenericUnixFontDatabase;
193
194 return m_fontDatabase;
195}
196
198{
199 if (!m_services)
200 m_services = new QPlatformServices;
201
202 return m_services;
203}
204
206{
207 return m_inputContext;
208}
209
211{
212 return QGenericUnixTheme::createUnixTheme(name);
213}
214
219
221{
222 if (window->surfaceType() != QSurface::VulkanSurface) {
223 qWarning("vkkhrdisplay platform plugin only supports QWindow with surfaceType == VulkanSurface");
224 // Assume VulkanSurface, better than crashing. Consider e.g. an autotest
225 // creating a default QWindow just to have something to be used with
226 // QRhi's Null backend. Continuing to set up a Vulkan window (even
227 // though the request was Raster or something) is better than failing to
228 // create a platform window, and may even be sufficient in some cases.
229 }
230
232 w->setGeometry(QRect()); // set fullscreen geometry
233 w->requestActivateWindow();
234 return w;
235}
236
241
243{
244 return createUnixEventDispatcher();
245}
246
247void QVkKhrDisplayIntegration::handleInstanceCreated(QVkKhrDisplayVulkanInstance *inst, void *userData)
248{
249 QVkKhrDisplayIntegration *self = static_cast<QVkKhrDisplayIntegration *>(userData);
250 self->m_primaryScreen->setVk(inst);
251}
252
254{
255 QVkKhrDisplayVulkanInstance *inst = new QVkKhrDisplayVulkanInstance(instance);
256 inst->setCreatedCallback(handleInstanceCreated, const_cast<QVkKhrDisplayIntegration *>(this));
257 return inst;
258}
259
263
264static int resourceType(const QByteArray &key)
265{
266 static const QByteArray names[] = { // match ResourceType
267 QByteArrayLiteral("vksurface")
268 };
269 const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
270 const QByteArray *result = std::find(names, end, key);
271 if (result == end)
272 result = std::find(names, end, key.toLower());
273 return int(result - names);
274}
275
276void *QVkKhrDisplayIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
277{
278 void *result = nullptr;
279
280 switch (resourceType(resource)) {
281 case VkSurface:
282 if (window && window->handle() && window->surfaceType() == QSurface::VulkanSurface)
283 result = static_cast<QVkKhrDisplayWindow *>(window->handle())->vulkanSurfacePtr();
284 break;
285 default:
286 break;
287 }
288
289 return result;
290}
291
292void QVkKhrDisplayIntegration::createInputHandlers()
293{
294#if QT_CONFIG(libinput)
295 if (!qEnvironmentVariableIntValue("QT_QPA_NO_LIBINPUT")) {
296 new QLibInputHandler("libinput"_L1, QString());
297 return;
298 }
299#endif
300
301#if QT_CONFIG(tslib)
302 bool useTslib = qEnvironmentVariableIntValue("QT_QPA_TSLIB");
303 if (useTslib)
304 new QTsLibMouseHandler("TsLib"_L1, QString());
305#endif
306
307#if QT_CONFIG(evdev)
308 new QEvdevKeyboardManager("EvdevKeyboard"_L1, QString(), this);
309 new QEvdevMouseManager("EvdevMouse"_L1, QString(), this);
310#if QT_CONFIG(tslib)
311 if (!useTslib)
312#endif
313 new QEvdevTouchManager("EvdevTouch"_L1, QString() /* spec */, this);
314#endif
315}
316
317QT_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.
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)