Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qandroidplatformvulkanwindow.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 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
5#include "androidjnimain.h"
9
10#include <QSurfaceFormat>
11#include <qpa/qplatformscreen.h>
12#include <qpa/qwindowsysteminterface.h>
13
14#include <android/native_window.h>
15#include <android/native_window_jni.h>
16
18
21 m_nativeSurfaceId(-1),
22 m_nativeWindow(nullptr),
23 m_vkSurface(0),
24 m_createVkSurface(nullptr),
25 m_destroyVkSurface(nullptr)
26{
27}
28
30{
31 m_surfaceWaitCondition.wakeOne();
33 if (m_nativeSurfaceId != -1)
34 QtAndroid::destroySurface(m_nativeSurfaceId);
35 clearSurface();
37}
38
40{
41 if (rect == geometry())
42 return;
43
44 m_oldGeometry = geometry();
45
47 if (m_nativeSurfaceId != -1)
48 QtAndroid::setSurfaceGeometry(m_nativeSurfaceId, rect);
49
50 QRect availableGeometry = screen()->availableGeometry();
51 if (rect.width() > 0
52 && rect.height() > 0
53 && availableGeometry.width() > 0
54 && availableGeometry.height() > 0) {
56 }
57
58 if (rect.topLeft() != m_oldGeometry.topLeft())
60}
61
63{
67 if (m_nativeSurfaceId != -1) {
68 QtAndroid::destroySurface(m_nativeSurfaceId);
69 m_nativeSurfaceId = -1;
70 }
71 clearSurface();
73 }
74}
75
77{
78 return window()->requestedFormat();
79}
80
81void QAndroidPlatformVulkanWindow::clearSurface()
82{
83 if (m_vkSurface && m_destroyVkSurface) {
84 m_destroyVkSurface(window()->vulkanInstance()->vkInstance(), m_vkSurface, nullptr);
85 m_vkSurface = 0;
86 }
87
88 if (m_nativeWindow) {
89 ANativeWindow_release(m_nativeWindow);
90 m_nativeWindow = nullptr;
91 }
92}
93
94void QAndroidPlatformVulkanWindow::sendExpose()
95{
96 QRect availableGeometry = screen()->availableGeometry();
97 if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
99}
100
101void QAndroidPlatformVulkanWindow::surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h)
102{
103 Q_UNUSED(jniEnv);
104 Q_UNUSED(w);
105 Q_UNUSED(h);
106
107 lockSurface();
108 m_androidSurfaceObject = surface;
109 if (surface)
110 m_surfaceWaitCondition.wakeOne();
112
113 if (surface)
114 sendExpose();
115}
116
118{
120 return &m_vkSurface;
121
122 bool needsExpose = false;
123 if (!m_vkSurface) {
124 clearSurface();
125
127 if (m_nativeSurfaceId == -1) {
128 AndroidDeadlockProtector protector;
129 if (!protector.acquire())
130 return &m_vkSurface;
131 const bool windowStaysOnTop = bool(window()->flags() & Qt::WindowStaysOnTopHint);
132 m_nativeSurfaceId = QtAndroid::createSurface(this, geometry(), windowStaysOnTop, 32);
133 m_surfaceWaitCondition.wait(&m_surfaceMutex);
134 }
135
136 if (m_nativeSurfaceId == -1 || !m_androidSurfaceObject.isValid())
137 return &m_vkSurface;
138
139 QJniEnvironment env;
140 m_nativeWindow = ANativeWindow_fromSurface(env.jniEnv(), m_androidSurfaceObject.object());
141
142 VkAndroidSurfaceCreateInfoKHR surfaceInfo;
143 memset(&surfaceInfo, 0, sizeof(surfaceInfo));
144 surfaceInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
145 surfaceInfo.window = m_nativeWindow;
146 QVulkanInstance *inst = window()->vulkanInstance();
147 if (!inst) {
148 qWarning("Attempted to create Vulkan surface without an instance; was QWindow::setVulkanInstance() called?");
149 return &m_vkSurface;
150 }
151 if (!m_createVkSurface) {
152 m_createVkSurface = reinterpret_cast<PFN_vkCreateAndroidSurfaceKHR>(
153 inst->getInstanceProcAddr("vkCreateAndroidSurfaceKHR"));
154 }
155 if (!m_destroyVkSurface) {
156 m_destroyVkSurface = reinterpret_cast<PFN_vkDestroySurfaceKHR>(
157 inst->getInstanceProcAddr("vkDestroySurfaceKHR"));
158 }
159 VkResult err = m_createVkSurface(inst->vkInstance(), &surfaceInfo, nullptr, &m_vkSurface);
160 if (err != VK_SUCCESS)
161 qWarning("Failed to create Android VkSurface: %d", err);
162
163 needsExpose = true;
164 }
165
166 if (needsExpose)
167 sendExpose();
168
169 return &m_vkSurface;
170}
171
void surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h) override
void applicationStateChanged(Qt::ApplicationState) override
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
QSurfaceFormat format() const override
Returns the actual surface format of the window.
virtual void applicationStateChanged(Qt::ApplicationState)
virtual void repaint(const QRegion &)
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
\inmodule QtCore
\inmodule QtCore
Definition qmutex.h:317
virtual QRect availableGeometry() const
Reimplement in subclass to return the pixel geometry of the available space This normally is the desk...
QSurface * surface() const
QWindow * window() const
Returns the window which belongs to the QPlatformWindow.
QPlatformScreen * screen() const override
Returns the platform screen handle corresponding to this platform window, or null if the window is no...
virtual QRect geometry() const
Returns the current geometry of a window.
\inmodule QtCore\reentrant
Definition qpoint.h:23
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:238
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:220
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:235
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
The QSurfaceFormat class represents the format of a QSurface. \inmodule QtGui.
The QVulkanInstance class represents a native Vulkan instance, enabling Vulkan rendering onto a QSurf...
bool wait(QMutex *, QDeadlineTimer=QDeadlineTimer(QDeadlineTimer::Forever))
static bool handleExposeEvent(QWindow *window, const QRegion &region)
\inmodule QtGui
Definition qwindow.h:63
rect
[4]
else opt state
[0]
Combined button and popup list for selecting options.
void destroySurface(int surfaceId)
void setSurfaceGeometry(int surfaceId, const QRect &geometry)
int createSurface(AndroidSurfaceClient *client, const QRect &geometry, bool onTop, int imageDepth)
ApplicationState
Definition qnamespace.h:261
@ ApplicationHidden
Definition qnamespace.h:263
@ WindowStaysOnTopHint
Definition qnamespace.h:232
#define qWarning
Definition qlogging.h:162
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei width
GLbitfield flags
GLfloat GLfloat GLfloat GLfloat h
#define Q_UNUSED(x)
QObject::connect nullptr
QReadWriteLock lock
[0]
aWidget window() -> setWindowTitle("New Window Title")
[2]