summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/android/android.pro9
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp36
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.h7
-rw-r--r--src/plugins/platforms/android/qandroidplatformvulkaninstance.cpp66
-rw-r--r--src/plugins/platforms/android/qandroidplatformvulkaninstance.h63
-rw-r--r--src/plugins/platforms/android/qandroidplatformvulkanwindow.cpp210
-rw-r--r--src/plugins/platforms/android/qandroidplatformvulkanwindow.h91
-rw-r--r--src/plugins/platforms/direct2d/direct2d.pro2
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowsvulkaninstance.cpp136
-rw-r--r--src/plugins/platforms/windows/qwindowsvulkaninstance.h76
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp72
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h10
-rw-r--r--src/plugins/platforms/windows/windows.pri5
-rw-r--r--src/plugins/platforms/windows/windows.pro2
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp26
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp15
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbvulkaninstance.cpp156
-rw-r--r--src/plugins/platforms/xcb/qxcbvulkaninstance.h79
-rw-r--r--src/plugins/platforms/xcb/qxcbvulkanwindow.cpp83
-rw-r--r--src/plugins/platforms/xcb/qxcbvulkanwindow.h65
-rw-r--r--src/plugins/platforms/xcb/xcb_qpa_lib.pro12
26 files changed, 1233 insertions, 18 deletions
diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro
index 03592bfa7d..73db9e93a3 100644
--- a/src/plugins/platforms/android/android.pro
+++ b/src/plugins/platforms/android/android.pro
@@ -11,6 +11,8 @@ QT += \
eventdispatcher_support-private accessibility_support-private \
fontdatabase_support-private egl_support-private
+qtConfig(vulkan): QT += vulkan_support-private
+
OTHER_FILES += $$PWD/android.json
INCLUDEPATH += \
@@ -78,6 +80,13 @@ HEADERS += $$PWD/qandroidplatformintegration.h \
qtConfig(android-style-assets): SOURCES += $$PWD/extract.cpp
else: SOURCES += $$PWD/extract-dummy.cpp
+qtConfig(vulkan) {
+ SOURCES += $$PWD/qandroidplatformvulkaninstance.cpp \
+ $$PWD/qandroidplatformvulkanwindow.cpp
+ HEADERS += $$PWD/qandroidplatformvulkaninstance.h \
+ $$PWD/qandroidplatformvulkanwindow.h
+}
+
PLUGIN_TYPE = platforms
load(qt_plugin)
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 13f9dc5a68..0668c43d18 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -69,6 +69,11 @@
#include <QtPlatformHeaders/QEGLNativeContext>
+#if QT_CONFIG(vulkan)
+#include "qandroidplatformvulkanwindow.h"
+#include "qandroidplatformvulkaninstance.h"
+#endif
+
QT_BEGIN_NAMESPACE
int QAndroidPlatformIntegration::m_defaultGeometryWidth = 320;
@@ -121,6 +126,23 @@ void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteA
return 0;
}
+void *QAndroidPlatformNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
+{
+#if QT_CONFIG(vulkan)
+ if (resource == "vkSurface") {
+ if (window->surfaceType() == QSurface::VulkanSurface) {
+ QAndroidPlatformVulkanWindow *w = static_cast<QAndroidPlatformVulkanWindow *>(window->handle());
+ // return a pointer to the VkSurfaceKHR, not the value
+ return w ? w->vkSurface() : nullptr;
+ }
+ }
+#else
+ Q_UNUSED(resource);
+ Q_UNUSED(window);
+#endif
+ return nullptr;
+}
+
QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &paramList)
: m_touchDevice(nullptr)
#ifndef QT_NO_ACCESSIBILITY
@@ -286,6 +308,11 @@ QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *wind
if (!QtAndroid::activity())
return nullptr;
+#if QT_CONFIG(vulkan)
+ if (window->surfaceType() == QSurface::VulkanSurface)
+ return new QAndroidPlatformVulkanWindow(window);
+#endif
+
return new QAndroidPlatformOpenGLWindow(window, m_eglDisplay);
}
@@ -426,4 +453,13 @@ void QAndroidPlatformIntegration::setScreenSize(int width, int height)
QMetaObject::invokeMethod(m_primaryScreen, "setSize", Qt::AutoConnection, Q_ARG(QSize, QSize(width, height)));
}
+#if QT_CONFIG(vulkan)
+
+QPlatformVulkanInstance *QAndroidPlatformIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const
+{
+ return new QAndroidPlatformVulkanInstance(instance);
+}
+
+#endif // QT_CONFIG(vulkan)
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h
index be10c3d161..0d2a0d2ad6 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/qandroidplatformintegration.h
@@ -40,6 +40,8 @@
#ifndef QANDROIDPLATFORMINTERATION_H
#define QANDROIDPLATFORMINTERATION_H
+#include <QtGui/qtguiglobal.h>
+
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformmenu.h>
#include <qpa/qplatformnativeinterface.h>
@@ -64,6 +66,7 @@ class QAndroidPlatformNativeInterface: public QPlatformNativeInterface
{
public:
void *nativeResourceForIntegration(const QByteArray &resource) override;
+ void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) override;
std::shared_ptr<AndroidStyle> m_androidStyle;
};
@@ -124,6 +127,10 @@ public:
void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; }
static void setDefaultApplicationState(Qt::ApplicationState applicationState) { m_defaultApplicationState = applicationState; }
+#if QT_CONFIG(vulkan)
+ QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) const override;
+#endif
+
private:
EGLDisplay m_eglDisplay;
QTouchDevice *m_touchDevice;
diff --git a/src/plugins/platforms/android/qandroidplatformvulkaninstance.cpp b/src/plugins/platforms/android/qandroidplatformvulkaninstance.cpp
new file mode 100644
index 0000000000..a411d0f007
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformvulkaninstance.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformvulkaninstance.h"
+
+QT_BEGIN_NAMESPACE
+
+QAndroidPlatformVulkanInstance::QAndroidPlatformVulkanInstance(QVulkanInstance *instance)
+ : m_instance(instance)
+{
+ m_lib.setFileName(QStringLiteral("vulkan"));
+
+ if (!m_lib.load()) {
+ qWarning("Failed to load %s", qPrintable(m_lib.fileName()));
+ return;
+ }
+
+ init(&m_lib);
+}
+
+void QAndroidPlatformVulkanInstance::createOrAdoptInstance()
+{
+ initInstance(m_instance, QByteArrayList() << QByteArrayLiteral("VK_KHR_android_surface"));
+}
+
+QAndroidPlatformVulkanInstance::~QAndroidPlatformVulkanInstance()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformvulkaninstance.h b/src/plugins/platforms/android/qandroidplatformvulkaninstance.h
new file mode 100644
index 0000000000..67edcceed9
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformvulkaninstance.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMVULKANINSTANCE_H
+#define QANDROIDPLATFORMVULKANINSTANCE_H
+
+#include <QtVulkanSupport/private/qbasicvulkanplatforminstance_p.h>
+#include <QLibrary>
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidPlatformVulkanInstance : public QBasicPlatformVulkanInstance
+{
+public:
+ QAndroidPlatformVulkanInstance(QVulkanInstance *instance);
+ ~QAndroidPlatformVulkanInstance();
+
+ void createOrAdoptInstance() override;
+
+private:
+ QVulkanInstance *m_instance;
+ QLibrary m_lib;
+};
+
+QT_END_NAMESPACE
+
+#endif // QANDROIDPLATFORMVULKANINSTANCE_H
diff --git a/src/plugins/platforms/android/qandroidplatformvulkanwindow.cpp b/src/plugins/platforms/android/qandroidplatformvulkanwindow.cpp
new file mode 100644
index 0000000000..cc41a871f3
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformvulkanwindow.cpp
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformvulkanwindow.h"
+#include "qandroidplatformscreen.h"
+#include "androidjnimain.h"
+#include "qandroideventdispatcher.h"
+#include "androiddeadlockprotector.h"
+
+#include <QSurfaceFormat>
+#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatformscreen.h>
+
+#include <android/native_window.h>
+#include <android/native_window_jni.h>
+
+QT_BEGIN_NAMESPACE
+
+QAndroidPlatformVulkanWindow::QAndroidPlatformVulkanWindow(QWindow *window)
+ : QAndroidPlatformWindow(window),
+ m_nativeSurfaceId(-1),
+ m_nativeWindow(nullptr),
+ m_vkSurface(0),
+ m_createVkSurface(nullptr),
+ m_destroyVkSurface(nullptr)
+{
+}
+
+QAndroidPlatformVulkanWindow::~QAndroidPlatformVulkanWindow()
+{
+ m_surfaceWaitCondition.wakeOne();
+ lockSurface();
+ if (m_nativeSurfaceId != -1)
+ QtAndroid::destroySurface(m_nativeSurfaceId);
+ clearSurface();
+ unlockSurface();
+}
+
+void QAndroidPlatformVulkanWindow::setGeometry(const QRect &rect)
+{
+ if (rect == geometry())
+ return;
+
+ m_oldGeometry = geometry();
+
+ QAndroidPlatformWindow::setGeometry(rect);
+ if (m_nativeSurfaceId != -1)
+ QtAndroid::setSurfaceGeometry(m_nativeSurfaceId, rect);
+
+ QRect availableGeometry = screen()->availableGeometry();
+ if (m_oldGeometry.width() == 0
+ && m_oldGeometry.height() == 0
+ && rect.width() > 0
+ && rect.height() > 0
+ && availableGeometry.width() > 0
+ && availableGeometry.height() > 0) {
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), rect.size()));
+ }
+
+ if (rect.topLeft() != m_oldGeometry.topLeft())
+ repaint(QRegion(rect));
+}
+
+void QAndroidPlatformVulkanWindow::applicationStateChanged(Qt::ApplicationState state)
+{
+ QAndroidPlatformWindow::applicationStateChanged(state);
+ if (state <= Qt::ApplicationHidden) {
+ lockSurface();
+ if (m_nativeSurfaceId != -1) {
+ QtAndroid::destroySurface(m_nativeSurfaceId);
+ m_nativeSurfaceId = -1;
+ }
+ clearSurface();
+ unlockSurface();
+ }
+}
+
+QSurfaceFormat QAndroidPlatformVulkanWindow::format() const
+{
+ return window()->requestedFormat();
+}
+
+void QAndroidPlatformVulkanWindow::clearSurface()
+{
+ if (m_vkSurface && m_destroyVkSurface) {
+ m_destroyVkSurface(window()->vulkanInstance()->vkInstance(), m_vkSurface, nullptr);
+ m_vkSurface = 0;
+ }
+
+ if (m_nativeWindow) {
+ ANativeWindow_release(m_nativeWindow);
+ m_nativeWindow = nullptr;
+ }
+}
+
+void QAndroidPlatformVulkanWindow::sendExpose()
+{
+ QRect availableGeometry = screen()->availableGeometry();
+ if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(QRect(QPoint(), geometry().size())));
+}
+
+void QAndroidPlatformVulkanWindow::surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h)
+{
+ Q_UNUSED(jniEnv);
+ Q_UNUSED(w);
+ Q_UNUSED(h);
+
+ lockSurface();
+ m_androidSurfaceObject = surface;
+ if (surface)
+ m_surfaceWaitCondition.wakeOne();
+ unlockSurface();
+
+ if (surface)
+ sendExpose();
+}
+
+VkSurfaceKHR *QAndroidPlatformVulkanWindow::vkSurface()
+{
+ if (QAndroidEventDispatcherStopper::stopped())
+ return &m_vkSurface;
+
+ bool needsExpose = false;
+ if (!m_vkSurface) {
+ clearSurface();
+
+ QMutexLocker lock(&m_surfaceMutex);
+ if (m_nativeSurfaceId == -1) {
+ AndroidDeadlockProtector protector;
+ if (!protector.acquire())
+ return &m_vkSurface;
+ const bool windowStaysOnTop = bool(window()->flags() & Qt::WindowStaysOnTopHint);
+ m_nativeSurfaceId = QtAndroid::createSurface(this, geometry(), windowStaysOnTop, 32);
+ m_surfaceWaitCondition.wait(&m_surfaceMutex);
+ }
+
+ if (m_nativeSurfaceId == -1 || !m_androidSurfaceObject.isValid())
+ return &m_vkSurface;
+
+ QJNIEnvironmentPrivate env;
+ m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurfaceObject.object());
+
+ VkAndroidSurfaceCreateInfoKHR surfaceInfo;
+ memset(&surfaceInfo, 0, sizeof(surfaceInfo));
+ surfaceInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
+ surfaceInfo.window = m_nativeWindow;
+ QVulkanInstance *inst = window()->vulkanInstance();
+ if (!inst) {
+ qWarning("Attempted to create Vulkan surface without an instance; was QWindow::setVulkanInstance() called?");
+ return &m_vkSurface;
+ }
+ if (!m_createVkSurface) {
+ m_createVkSurface = reinterpret_cast<PFN_vkCreateAndroidSurfaceKHR>(
+ inst->getInstanceProcAddr("vkCreateAndroidSurfaceKHR"));
+ }
+ if (!m_destroyVkSurface) {
+ m_destroyVkSurface = reinterpret_cast<PFN_vkDestroySurfaceKHR>(
+ inst->getInstanceProcAddr("vkDestroySurfaceKHR"));
+ }
+ VkResult err = m_createVkSurface(inst->vkInstance(), &surfaceInfo, nullptr, &m_vkSurface);
+ if (err != VK_SUCCESS)
+ qWarning("Failed to create Android VkSurface: %d", err);
+
+ needsExpose = true;
+ }
+
+ if (needsExpose)
+ sendExpose();
+
+ return &m_vkSurface;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformvulkanwindow.h b/src/plugins/platforms/android/qandroidplatformvulkanwindow.h
new file mode 100644
index 0000000000..19eca98720
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformvulkanwindow.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMVULKANWINDOW_H
+#define QANDROIDPLATFORMVULKANWINDOW_H
+
+#if defined(VULKAN_H_) && !defined(VK_USE_PLATFORM_ANDROID_KHR)
+#error "vulkan.h included without Android WSI"
+#endif
+
+#define VK_USE_PLATFORM_ANDROID_KHR
+
+#include <QWaitCondition>
+#include <QtCore/private/qjni_p.h>
+
+#include "androidsurfaceclient.h"
+#include "qandroidplatformwindow.h"
+
+#include "qandroidplatformvulkaninstance.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidPlatformVulkanWindow : public QAndroidPlatformWindow, public AndroidSurfaceClient
+{
+public:
+ explicit QAndroidPlatformVulkanWindow(QWindow *window);
+ ~QAndroidPlatformVulkanWindow();
+
+ void setGeometry(const QRect &rect) override;
+ QSurfaceFormat format() const override;
+ void applicationStateChanged(Qt::ApplicationState) override;
+
+ VkSurfaceKHR *vkSurface();
+
+protected:
+ void surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h) override;
+
+private:
+ void sendExpose();
+ void clearSurface();
+
+ int m_nativeSurfaceId;
+ ANativeWindow *m_nativeWindow;
+ QJNIObjectPrivate m_androidSurfaceObject;
+ QWaitCondition m_surfaceWaitCondition;
+ QSurfaceFormat m_format;
+ QRect m_oldGeometry;
+ VkSurfaceKHR m_vkSurface;
+ PFN_vkCreateAndroidSurfaceKHR m_createVkSurface;
+ PFN_vkDestroySurfaceKHR m_destroyVkSurface;
+};
+
+QT_END_NAMESPACE
+
+#endif // QANDROIDPLATFORMVULKANWINDOW_H
diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro
index 224f122fc4..87405ae19f 100644
--- a/src/plugins/platforms/direct2d/direct2d.pro
+++ b/src/plugins/platforms/direct2d/direct2d.pro
@@ -5,6 +5,8 @@ QT += \
eventdispatcher_support-private accessibility_support-private \
fontdatabase_support-private theme_support-private
+qtConfig(vulkan): QT += vulkan_support-private
+
LIBS += -ldwmapi -ld2d1 -ld3d11 -ldwrite -lVersion -lgdi32
include(../windows/windows.pri)
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 316f93e3ac..6614c76a53 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -606,4 +606,11 @@ void QWindowsIntegration::beep() const
MessageBeep(MB_OK); // For QApplication
}
+#if QT_CONFIG(vulkan)
+QPlatformVulkanInstance *QWindowsIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const
+{
+ return new QWindowsVulkanInstance(instance);
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index 607203829f..fbdb341dab 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -113,6 +113,10 @@ public:
QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const override;
#endif
+#if QT_CONFIG(vulkan)
+ QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) const override;
+#endif
+
protected:
virtual QWindowsWindow *createPlatformWindowHelper(QWindow *window, const QWindowsWindowData &) const;
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
index d750eef19d..8bc2e1b441 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
@@ -64,7 +64,8 @@ enum ResourceType {
HandleType,
GlHandleType,
GetDCType,
- ReleaseDCType
+ ReleaseDCType,
+ VkSurface
};
static int resourceType(const QByteArray &key)
@@ -77,7 +78,8 @@ static int resourceType(const QByteArray &key)
"handle",
"glhandle",
"getdc",
- "releasedc"
+ "releasedc",
+ "vkSurface"
};
const char ** const end = names + sizeof(names) / sizeof(names[0]);
const char **result = std::find(names, end, key);
@@ -112,6 +114,12 @@ void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resourc
case QWindow::OpenGLSurface:
case QWindow::OpenVGSurface:
break;
+#if QT_CONFIG(vulkan)
+ case QWindow::VulkanSurface:
+ if (type == VkSurface)
+ return bw->surface(nullptr, nullptr); // returns the address of the VkSurfaceKHR, not the value, as expected
+ break;
+#endif
}
qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
return 0;
diff --git a/src/plugins/platforms/windows/qwindowsvulkaninstance.cpp b/src/plugins/platforms/windows/qwindowsvulkaninstance.cpp
new file mode 100644
index 0000000000..d81ee8ba29
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsvulkaninstance.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsvulkaninstance.h"
+
+QT_BEGIN_NAMESPACE
+
+QWindowsVulkanInstance::QWindowsVulkanInstance(QVulkanInstance *instance)
+ : m_instance(instance),
+ m_getPhysDevPresSupport(nullptr),
+ m_createSurface(nullptr),
+ m_destroySurface(nullptr)
+{
+ if (qEnvironmentVariableIsSet("QT_VULKAN_LIB"))
+ m_lib.setFileName(QString::fromUtf8(qgetenv("QT_VULKAN_LIB")));
+ else
+ m_lib.setFileName(QStringLiteral("vulkan-1"));
+
+ if (!m_lib.load()) {
+ qWarning("Failed to load %s: %s", qPrintable(m_lib.fileName()), qPrintable(m_lib.errorString()));
+ return;
+ }
+
+ init(&m_lib);
+}
+
+void QWindowsVulkanInstance::createOrAdoptInstance()
+{
+ initInstance(m_instance, QByteArrayList() << QByteArrayLiteral("VK_KHR_win32_surface"));
+
+ if (!m_vkInst)
+ return;
+
+ m_getPhysDevPresSupport = reinterpret_cast<PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR>(
+ m_vkGetInstanceProcAddr(m_vkInst, "vkGetPhysicalDeviceWin32PresentationSupportKHR"));
+ if (!m_getPhysDevPresSupport)
+ qWarning("Failed to find vkGetPhysicalDeviceWin32PresentationSupportKHR");
+}
+
+QWindowsVulkanInstance::~QWindowsVulkanInstance()
+{
+}
+
+bool QWindowsVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ QWindow *window)
+{
+ if (!m_getPhysDevPresSupport || !m_getPhysDevSurfaceSupport)
+ return true;
+
+ bool ok = m_getPhysDevPresSupport(physicalDevice, queueFamilyIndex);
+
+ VkSurfaceKHR surface = QVulkanInstance::surfaceForWindow(window);
+ VkBool32 supported = false;
+ m_getPhysDevSurfaceSupport(physicalDevice, queueFamilyIndex, surface, &supported);
+ ok &= bool(supported);
+
+ return ok;
+}
+
+VkSurfaceKHR QWindowsVulkanInstance::createSurface(HWND win)
+{
+ VkSurfaceKHR surface = 0;
+
+ if (!m_createSurface) {
+ m_createSurface = reinterpret_cast<PFN_vkCreateWin32SurfaceKHR>(
+ m_vkGetInstanceProcAddr(m_vkInst, "vkCreateWin32SurfaceKHR"));
+ }
+ if (!m_createSurface) {
+ qWarning("Failed to find vkCreateWin32SurfaceKHR");
+ return surface;
+ }
+ if (!m_destroySurface) {
+ m_destroySurface = reinterpret_cast<PFN_vkDestroySurfaceKHR>(
+ m_vkGetInstanceProcAddr(m_vkInst, "vkDestroySurfaceKHR"));
+ }
+ if (!m_destroySurface) {
+ qWarning("Failed to find vkDestroySurfaceKHR");
+ return surface;
+ }
+
+ VkWin32SurfaceCreateInfoKHR surfaceInfo;
+ memset(&surfaceInfo, 0, sizeof(surfaceInfo));
+ surfaceInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
+ surfaceInfo.hinstance = GetModuleHandle(nullptr);
+ surfaceInfo.hwnd = win;
+ VkResult err = m_createSurface(m_vkInst, &surfaceInfo, nullptr, &surface);
+ if (err != VK_SUCCESS)
+ qWarning("Failed to create Vulkan surface: %d", err);
+
+ return surface;
+}
+
+void QWindowsVulkanInstance::destroySurface(VkSurfaceKHR surface)
+{
+ if (m_destroySurface && surface)
+ m_destroySurface(m_vkInst, surface, nullptr);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsvulkaninstance.h b/src/plugins/platforms/windows/qwindowsvulkaninstance.h
new file mode 100644
index 0000000000..ca60ab7627
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsvulkaninstance.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSVULKANINSTANCE_H
+#define QWINDOWSVULKANINSTANCE_H
+
+#if defined(VULKAN_H_) && !defined(VK_USE_PLATFORM_WIN32_KHR)
+#error "vulkan.h included without Win32 WSI"
+#endif
+
+#define VK_USE_PLATFORM_WIN32_KHR
+
+#include <QtVulkanSupport/private/qbasicvulkanplatforminstance_p.h>
+#include <QLibrary>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsVulkanInstance : public QBasicPlatformVulkanInstance
+{
+public:
+ QWindowsVulkanInstance(QVulkanInstance *instance);
+ ~QWindowsVulkanInstance();
+
+ void createOrAdoptInstance() override;
+ bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window) override;
+
+ VkSurfaceKHR createSurface(HWND win);
+ void destroySurface(VkSurfaceKHR surface);
+
+private:
+ QVulkanInstance *m_instance;
+ QLibrary m_lib;
+ PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR m_getPhysDevPresSupport;
+ PFN_vkCreateWin32SurfaceKHR m_createSurface;
+ PFN_vkDestroySurfaceKHR m_destroySurface;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSVULKANINSTANCE_H
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 8950ec3bfc..25f7e11c60 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -67,6 +67,10 @@
#include <dwmapi.h>
+#if QT_CONFIG(vulkan)
+#include "qwindowsvulkaninstance.h"
+#endif
+
QT_BEGIN_NAMESPACE
enum {
@@ -308,13 +312,15 @@ static QWindow::Visibility windowVisibility_sys(HWND hwnd)
return QWindow::Windowed;
}
-static inline bool windowIsOpenGL(const QWindow *w)
+static inline bool windowIsAccelerated(const QWindow *w)
{
switch (w->surfaceType()) {
case QSurface::OpenGLSurface:
return true;
case QSurface::RasterGLSurface:
return qt_window_private(const_cast<QWindow *>(w))->compositing;
+ case QSurface::VulkanSurface:
+ return true;
default:
return false;
}
@@ -375,11 +381,11 @@ bool QWindowsWindow::setWindowLayered(HWND hwnd, Qt::WindowFlags flags, bool has
return needsLayered;
}
-static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, bool openGL, qreal level)
+static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, bool accelerated, qreal level)
{
if (QWindowsWindow::setWindowLayered(hwnd, flags, hasAlpha, level)) {
const BYTE alpha = BYTE(qRound(255.0 * level));
- if (hasAlpha && !openGL && (flags & Qt::FramelessWindowHint)) {
+ if (hasAlpha && !accelerated && (flags & Qt::FramelessWindowHint)) {
// Non-GL windows with alpha: Use blend function to update.
BLENDFUNCTION blend = {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA};
UpdateLayeredWindow(hwnd, NULL, NULL, NULL, NULL, NULL, 0, &blend, ULW_ALPHA);
@@ -393,13 +399,13 @@ static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, bo
static inline void updateGLWindowSettings(const QWindow *w, HWND hwnd, Qt::WindowFlags flags, qreal opacity)
{
- const bool isGL = windowIsOpenGL(w);
+ const bool isAccelerated = windowIsAccelerated(w);
const bool hasAlpha = w->format().hasAlpha();
- if (isGL && hasAlpha)
+ if (isAccelerated && hasAlpha)
applyBlurBehindWindow(hwnd);
- setWindowOpacity(hwnd, flags, hasAlpha, isGL, opacity);
+ setWindowOpacity(hwnd, flags, hasAlpha, isAccelerated, opacity);
}
/*!
@@ -1053,6 +1059,9 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
m_data(data),
m_cursor(new CursorHandle),
m_format(aWindow->requestedFormat())
+#if QT_CONFIG(vulkan)
+ , m_vkSurface(0)
+#endif
{
// Clear the creation context as the window can be found in QWindowsContext's map.
QWindowsContext::instance()->setWindowCreationContext(QSharedPointer<QWindowCreationContext>());
@@ -1068,6 +1077,10 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
setFlag(OpenGL_ES2);
}
#endif // QT_NO_OPENGL
+#if QT_CONFIG(vulkan)
+ if (aWindow->surfaceType() == QSurface::VulkanSurface)
+ setFlag(VulkanSurface);
+#endif
updateDropSite(window()->isTopLevel());
registerTouchWindow();
@@ -1121,6 +1134,14 @@ void QWindowsWindow::destroyWindow()
if (hasMouseCapture())
setMouseGrabEnabled(false);
setDropSiteEnabled(false);
+#if QT_CONFIG(vulkan)
+ if (m_vkSurface) {
+ QVulkanInstance *inst = window()->vulkanInstance();
+ if (inst)
+ static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface);
+ m_vkSurface = 0;
+ }
+#endif
#ifndef QT_NO_OPENGL
if (m_surface) {
if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
@@ -1470,8 +1491,10 @@ void QWindowsWindow::handleHidden()
void QWindowsWindow::handleCompositionSettingsChanged()
{
const QWindow *w = window();
- if (w->surfaceType() == QWindow::OpenGLSurface && w->format().hasAlpha())
+ if ((w->surfaceType() == QWindow::OpenGLSurface || w->surfaceType() == QWindow::VulkanSurface)
+ && w->format().hasAlpha()) {
applyBlurBehindWindow(handle());
+ }
}
static QRect normalFrameGeometry(HWND hwnd)
@@ -1693,8 +1716,11 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
BeginPaint(hwnd, &ps);
// Observed painting problems with Aero style disabled (QTBUG-7865).
- if (Q_UNLIKELY(testFlag(OpenGLSurface) && testFlag(OpenGLDoubleBuffered) && !dwmIsCompositionEnabled()))
+ if (Q_UNLIKELY(!dwmIsCompositionEnabled())
+ && ((testFlag(OpenGLSurface) && testFlag(OpenGLDoubleBuffered)) || testFlag(VulkanSurface)))
+ {
SelectClipRgn(ps.hdc, NULL);
+ }
// If the a window is obscured by another window (such as a child window)
// we still need to send isExposed=true, for compatibility.
@@ -2030,7 +2056,7 @@ void QWindowsWindow::setOpacity(qreal level)
m_opacity = level;
if (m_data.hwnd)
setWindowOpacity(m_data.hwnd, m_data.flags,
- window()->format().hasAlpha(), testFlag(OpenGLSurface),
+ window()->format().hasAlpha(), testFlag(OpenGLSurface) || testFlag(VulkanSurface),
level);
}
}
@@ -2448,11 +2474,27 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins)
void *QWindowsWindow::surface(void *nativeConfig, int *err)
{
-#ifdef QT_NO_OPENGL
+#if QT_CONFIG(vulkan)
+ Q_UNUSED(nativeConfig);
+ Q_UNUSED(err);
+ if (window()->surfaceType() == QSurface::VulkanSurface) {
+ if (!m_vkSurface) {
+ QVulkanInstance *inst = window()->vulkanInstance();
+ if (inst)
+ m_vkSurface = static_cast<QWindowsVulkanInstance *>(inst->handle())->createSurface(handle());
+ else
+ qWarning("Attempted to create Vulkan surface without an instance; was QWindow::setVulkanInstance() called?");
+ }
+ // Different semantics for VkSurfaces: the return value is the address,
+ // not the value, given that this is a 64-bit handle even on x86.
+ return &m_vkSurface;
+ }
+#elif defined(QT_NO_OPENGL)
Q_UNUSED(err)
Q_UNUSED(nativeConfig)
return 0;
-#else
+#endif
+#ifndef QT_NO_OPENGL
if (!m_surface) {
if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig, err);
@@ -2464,6 +2506,14 @@ void *QWindowsWindow::surface(void *nativeConfig, int *err)
void QWindowsWindow::invalidateSurface()
{
+#if QT_CONFIG(vulkan)
+ if (m_vkSurface) {
+ QVulkanInstance *inst = window()->vulkanInstance();
+ if (inst)
+ static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface);
+ m_vkSurface = 0;
+ }
+#endif
#ifndef QT_NO_OPENGL
if (m_surface) {
if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index b55529588c..46236c10b5 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -46,6 +46,10 @@
#include <qpa/qplatformwindow.h>
#include <QtPlatformHeaders/qwindowswindowfunctions.h>
+#if QT_CONFIG(vulkan)
+#include "qwindowsvulkaninstance.h"
+#endif
+
QT_BEGIN_NAMESPACE
class QWindowsOleDropTarget;
@@ -209,6 +213,7 @@ public:
Compositing = 0x200000,
HasBorderInFullScreen = 0x400000,
WithinDpiChanged = 0x800000,
+ VulkanSurface = 0x1000000
};
QWindowsWindow(QWindow *window, const QWindowsWindowData &data);
@@ -351,6 +356,11 @@ private:
HICON m_iconSmall = 0;
HICON m_iconBig = 0;
void *m_surface = nullptr;
+
+#if QT_CONFIG(vulkan)
+ // note: intentionally not using void * in order to avoid breaking x86
+ VkSurfaceKHR m_vkSurface = 0;
+#endif
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index 1a80526aab..7694824d20 100644
--- a/src/plugins/platforms/windows/windows.pri
+++ b/src/plugins/platforms/windows/windows.pri
@@ -68,6 +68,11 @@ qtConfig(dynamicgl) {
HEADERS += $$PWD/qwindowseglcontext.h
}
+qtConfig(vulkan) {
+ SOURCES += $$PWD/qwindowsvulkaninstance.cpp
+ HEADERS += $$PWD/qwindowsvulkaninstance.h
+}
+
!contains( DEFINES, QT_NO_CLIPBOARD ) {
SOURCES += $$PWD/qwindowsclipboard.cpp
HEADERS += $$PWD/qwindowsclipboard.h
diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro
index 23168c10dc..4d788d91f8 100644
--- a/src/plugins/platforms/windows/windows.pro
+++ b/src/plugins/platforms/windows/windows.pro
@@ -5,6 +5,8 @@ QT += \
eventdispatcher_support-private accessibility_support-private \
fontdatabase_support-private theme_support-private
+qtConfig(vulkan): QT += vulkan_support-private
+
LIBS += -lgdi32 -ldwmapi
include(windows.pri)
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 40858b39e0..7f1cff1299 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -83,6 +83,11 @@
#include <QtCore/QFileInfo>
+#if QT_CONFIG(vulkan)
+#include "qxcbvulkaninstance.h"
+#include "qxcbvulkanwindow.h"
+#endif
+
QT_BEGIN_NAMESPACE
// Find out if our parent process is gdb by looking at the 'exe' symlink under /proc,.
@@ -199,11 +204,19 @@ QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const
{
QXcbScreen *screen = static_cast<QXcbScreen *>(window->screen()->handle());
QXcbGlIntegration *glIntegration = screen->connection()->glIntegration();
- if (window->type() != Qt::Desktop && window->supportsOpenGL()) {
- if (glIntegration) {
- QXcbWindow *xcbWindow = glIntegration->createWindow(window);
+ if (window->type() != Qt::Desktop) {
+ if (window->supportsOpenGL()) {
+ if (glIntegration) {
+ QXcbWindow *xcbWindow = glIntegration->createWindow(window);
+ xcbWindow->create();
+ return xcbWindow;
+ }
+#if QT_CONFIG(vulkan)
+ } else if (window->surfaceType() == QSurface::VulkanSurface) {
+ QXcbWindow *xcbWindow = new QXcbVulkanWindow(window);
xcbWindow->create();
return xcbWindow;
+#endif
}
}
@@ -498,4 +511,11 @@ void QXcbIntegration::beep() const
xcb_bell(connection, 0);
}
+#if QT_CONFIG(vulkan)
+QPlatformVulkanInstance *QXcbIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const
+{
+ return new QXcbVulkanInstance(instance);
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index baa5c9d835..6e12739138 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -113,6 +113,10 @@ public:
void beep() const override;
+#if QT_CONFIG(vulkan)
+ QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) const override;
+#endif
+
static QXcbIntegration *instance() { return m_instance; }
private:
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index cc05671580..eff38fc868 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -67,6 +67,10 @@
#include "qxcbnativeinterfacehandler.h"
+#if QT_CONFIG(vulkan)
+#include "qxcbvulkanwindow.h"
+#endif
+
QT_BEGIN_NAMESPACE
// return QXcbNativeInterface::ResourceType for the key.
@@ -82,7 +86,8 @@ static int resourceType(const QByteArray &key)
QByteArrayLiteral("rootwindow"),
QByteArrayLiteral("subpixeltype"), QByteArrayLiteral("antialiasingenabled"),
QByteArrayLiteral("atspibus"),
- QByteArrayLiteral("compositingenabled")
+ QByteArrayLiteral("compositingenabled"),
+ QByteArrayLiteral("vksurface")
};
const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
const QByteArray *result = std::find(names, end, key);
@@ -257,6 +262,14 @@ void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceStr
case Screen:
result = screenForWindow(window);
break;
+#if QT_CONFIG(vulkan)
+ case VkSurface:
+ if (window->surfaceType() == QSurface::VulkanSurface && window->handle()) {
+ // return a pointer to the VkSurfaceKHR value, not the value itself
+ result = static_cast<QXcbVulkanWindow *>(window->handle())->surface();
+ }
+ break;
+#endif
default:
break;
}
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index 4186d77f4d..b9f1ebcdc6 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -73,7 +73,8 @@ public:
ScreenSubpixelType,
ScreenAntialiasingEnabled,
AtspiBus,
- CompositingEnabled
+ CompositingEnabled,
+ VkSurface
};
QXcbNativeInterface();
diff --git a/src/plugins/platforms/xcb/qxcbvulkaninstance.cpp b/src/plugins/platforms/xcb/qxcbvulkaninstance.cpp
new file mode 100644
index 0000000000..4d540defa9
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbvulkaninstance.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbvulkaninstance.h"
+#include "qxcbwindow.h"
+#include "qxcbscreen.h"
+
+QT_BEGIN_NAMESPACE
+
+QXcbVulkanInstance::QXcbVulkanInstance(QVulkanInstance *instance)
+ : m_instance(instance),
+ m_getPhysDevPresSupport(nullptr),
+ m_createSurface(nullptr),
+ m_destroySurface(nullptr)
+{
+ if (qEnvironmentVariableIsSet("QT_VULKAN_LIB"))
+ m_lib.setFileName(QString::fromUtf8(qgetenv("QT_VULKAN_LIB")));
+ else
+ m_lib.setFileName(QStringLiteral("vulkan"));
+
+ if (!m_lib.load()) {
+ qWarning("Failed to load %s: %s", qPrintable(m_lib.fileName()), qPrintable(m_lib.errorString()));
+ return;
+ }
+
+ init(&m_lib);
+}
+
+QXcbVulkanInstance::~QXcbVulkanInstance()
+{
+}
+
+void QXcbVulkanInstance::createOrAdoptInstance()
+{
+ initInstance(m_instance, QByteArrayList() << QByteArrayLiteral("VK_KHR_xcb_surface"));
+
+ if (!m_vkInst)
+ return;
+
+ m_getPhysDevPresSupport = reinterpret_cast<PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR>(
+ m_vkGetInstanceProcAddr(m_vkInst, "vkGetPhysicalDeviceXcbPresentationSupportKHR"));
+ if (!m_getPhysDevPresSupport)
+ qWarning("Failed to find vkGetPhysicalDeviceXcbPresentationSupportKHR");
+}
+
+bool QXcbVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ QWindow *window)
+{
+ if (!m_getPhysDevPresSupport || !m_getPhysDevSurfaceSupport)
+ return true;
+
+ QXcbWindow *w = static_cast<QXcbWindow *>(window->handle());
+ if (!w) {
+ qWarning("Attempted to call supportsPresent() without a valid platform window");
+ return false;
+ }
+ xcb_connection_t *connection = w->xcbScreen()->xcb_connection();
+ bool ok = m_getPhysDevPresSupport(physicalDevice, queueFamilyIndex, connection, w->visualId());
+
+ VkSurfaceKHR surface = QVulkanInstance::surfaceForWindow(window);
+ VkBool32 supported = false;
+ m_getPhysDevSurfaceSupport(physicalDevice, queueFamilyIndex, surface, &supported);
+ ok &= bool(supported);
+
+ return ok;
+}
+
+VkSurfaceKHR QXcbVulkanInstance::createSurface(QXcbWindow *window)
+{
+ VkSurfaceKHR surface = 0;
+
+ if (!m_createSurface) {
+ m_createSurface = reinterpret_cast<PFN_vkCreateXcbSurfaceKHR>(
+ m_vkGetInstanceProcAddr(m_vkInst, "vkCreateXcbSurfaceKHR"));
+ }
+ if (!m_createSurface) {
+ qWarning("Failed to find vkCreateXcbSurfaceKHR");
+ return surface;
+ }
+ if (!m_destroySurface) {
+ m_destroySurface = reinterpret_cast<PFN_vkDestroySurfaceKHR>(
+ m_vkGetInstanceProcAddr(m_vkInst, "vkDestroySurfaceKHR"));
+ }
+ if (!m_destroySurface) {
+ qWarning("Failed to find vkDestroySurfaceKHR");
+ return surface;
+ }
+
+ VkXcbSurfaceCreateInfoKHR surfaceInfo;
+ memset(&surfaceInfo, 0, sizeof(surfaceInfo));
+ surfaceInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
+ surfaceInfo.connection = window->xcbScreen()->xcb_connection();
+ surfaceInfo.window = window->xcb_window();
+ VkResult err = m_createSurface(m_vkInst, &surfaceInfo, nullptr, &surface);
+ if (err != VK_SUCCESS)
+ qWarning("Failed to create Vulkan surface: %d", err);
+
+ return surface;
+}
+
+void QXcbVulkanInstance::destroySurface(VkSurfaceKHR surface)
+{
+ if (m_destroySurface && surface)
+ m_destroySurface(m_vkInst, surface, nullptr);
+}
+
+void QXcbVulkanInstance::presentQueued(QWindow *window)
+{
+ QXcbWindow *w = static_cast<QXcbWindow *>(window->handle());
+ if (!w) {
+ qWarning("Attempted to call presentQueued() without a valid platform window");
+ return;
+ }
+
+ if (w->needsSync())
+ w->postSyncWindowRequest();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbvulkaninstance.h b/src/plugins/platforms/xcb/qxcbvulkaninstance.h
new file mode 100644
index 0000000000..dbe057d944
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbvulkaninstance.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBVULKANINSTANCE_H
+#define QXCBVULKANINSTANCE_H
+
+#if defined(VULKAN_H_) && !defined(VK_USE_PLATFORM_XCB_KHR)
+#error "vulkan.h included without xcb WSI"
+#endif
+
+#define VK_USE_PLATFORM_XCB_KHR
+
+#include <QtVulkanSupport/private/qbasicvulkanplatforminstance_p.h>
+#include <QLibrary>
+
+QT_BEGIN_NAMESPACE
+
+class QXcbWindow;
+
+class QXcbVulkanInstance : public QBasicPlatformVulkanInstance
+{
+public:
+ QXcbVulkanInstance(QVulkanInstance *instance);
+ ~QXcbVulkanInstance();
+
+ void createOrAdoptInstance() override;
+ bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window) override;
+ void presentQueued(QWindow *window) override;
+
+ VkSurfaceKHR createSurface(QXcbWindow *window);
+ void destroySurface(VkSurfaceKHR surface);
+
+private:
+ QVulkanInstance *m_instance;
+ QLibrary m_lib;
+ PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR m_getPhysDevPresSupport;
+ PFN_vkCreateXcbSurfaceKHR m_createSurface;
+ PFN_vkDestroySurfaceKHR m_destroySurface;
+};
+
+QT_END_NAMESPACE
+
+#endif // QXCBVULKANINSTANCE_H
diff --git a/src/plugins/platforms/xcb/qxcbvulkanwindow.cpp b/src/plugins/platforms/xcb/qxcbvulkanwindow.cpp
new file mode 100644
index 0000000000..f9136c8b72
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbvulkanwindow.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbvulkanwindow.h"
+
+QT_BEGIN_NAMESPACE
+
+QXcbVulkanWindow::QXcbVulkanWindow(QWindow *window)
+ : QXcbWindow(window),
+ m_surface(0)
+{
+}
+
+QXcbVulkanWindow::~QXcbVulkanWindow()
+{
+ if (m_surface) {
+ QVulkanInstance *inst = window()->vulkanInstance();
+ if (inst)
+ static_cast<QXcbVulkanInstance *>(inst->handle())->destroySurface(m_surface);
+ }
+}
+
+void QXcbVulkanWindow::resolveFormat(const QSurfaceFormat &format)
+{
+ m_format = format;
+ m_format.setRedBufferSize(8);
+ m_format.setGreenBufferSize(8);
+ m_format.setBlueBufferSize(8);
+}
+
+VkSurfaceKHR *QXcbVulkanWindow::surface()
+{
+ if (m_surface)
+ return &m_surface;
+
+ QVulkanInstance *inst = window()->vulkanInstance();
+ if (!inst) {
+ qWarning("Attempted to create Vulkan surface without an instance; was QWindow::setVulkanInstance() called?");
+ return nullptr;
+ }
+ QXcbVulkanInstance *xcbinst = static_cast<QXcbVulkanInstance *>(inst->handle());
+ m_surface = xcbinst->createSurface(this);
+
+ return &m_surface;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbvulkanwindow.h b/src/plugins/platforms/xcb/qxcbvulkanwindow.h
new file mode 100644
index 0000000000..43c96820c5
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbvulkanwindow.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBVULKANWINDOW_H
+#define QXCBVULKANWINDOW_H
+
+#include "qxcbwindow.h"
+#include "qxcbvulkaninstance.h"
+
+QT_BEGIN_NAMESPACE
+
+class QXcbVulkanWindow : public QXcbWindow
+{
+public:
+ QXcbVulkanWindow(QWindow *window);
+ ~QXcbVulkanWindow();
+
+ VkSurfaceKHR *surface();
+
+protected:
+ void resolveFormat(const QSurfaceFormat &format) override;
+
+private:
+ VkSurfaceKHR m_surface;
+};
+
+QT_END_NAMESPACE
+
+#endif // QXCBVULKANWINDOW_H
diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
index 6db0c76dea..c7f2993220 100644
--- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro
+++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
@@ -10,6 +10,8 @@ QT += \
qtHaveModule(linuxaccessibility_support-private): \
QT += linuxaccessibility_support-private
+qtConfig(vulkan): QT += vulkan_support-private
+
SOURCES = \
qxcbclipboard.cpp \
qxcbconnection.cpp \
@@ -70,6 +72,16 @@ qtConfig(xcb-sm) {
include(gl_integrations/gl_integrations.pri)
+qtConfig(vulkan) {
+ SOURCES += \
+ qxcbvulkaninstance.cpp \
+ qxcbvulkanwindow.cpp
+
+ HEADERS += \
+ qxcbvulkaninstance.h \
+ qxcbvulkanwindow.h
+}
+
!qtConfig(system-xcb) {
DEFINES += XCB_USE_RENDER
QMAKE_USE += xcb-static xcb