summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/android')
-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
7 files changed, 482 insertions, 0 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