summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTinja Paavoseppä <tinja.paavoseppa@qt.io>2023-11-06 13:02:10 +0200
committerTinja Paavoseppä <tinja.paavoseppa@qt.io>2023-12-07 10:56:43 +0200
commit2020ce5fd2478389c56f34742fdeee9cd24ca8a5 (patch)
tree6ea05c32d80ca916b3d13883883e6309f5709527
parent76b58be4b8495f488607639f012de227dc047102 (diff)
Android: Give raster windows their own surface, and flush via RHI
Refactored platform windows on Android so that all window types, including raster windows, have their own surface to draw on. Raster windows now flush the backing-store via RHI/OpenGL. As a drive by, update to newer JNI syntax where appropriate. Task-number: QTBUG-116187 Change-Id: I3b764b7126abf53556750b0ccbb7d27efe007bc1 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtNative.java2
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtSurface.java4
-rw-r--r--src/gui/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/android/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp20
-rw-r--r--src/plugins/platforms/android/androidjnimain.h4
-rw-r--r--src/plugins/platforms/android/androidsurfaceclient.h24
-rw-r--r--src/plugins/platforms/android/qandroidplatformbackingstore.cpp48
-rw-r--r--src/plugins/platforms/android/qandroidplatformbackingstore.h28
-rw-r--r--src/plugins/platforms/android/qandroidplatformforeignwindow.h1
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp7
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglwindow.cpp62
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglwindow.h9
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp258
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.h30
-rw-r--r--src/plugins/platforms/android/qandroidplatformvulkanwindow.cpp45
-rw-r--r--src/plugins/platforms/android/qandroidplatformvulkanwindow.h11
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.cpp45
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.h37
19 files changed, 108 insertions, 531 deletions
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtNative.java b/src/android/jar/src/org/qtproject/qt/android/QtNative.java
index ee67362fec..e4d3ce5b7b 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtNative.java
@@ -377,7 +377,7 @@ class QtNative
// application methods
// surface methods
- public static native void setSurface(int id, Object surface, int w, int h);
+ public static native void setSurface(int id, Object surface);
// surface methods
// window methods
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtSurface.java b/src/android/jar/src/org/qtproject/qt/android/QtSurface.java
index 704574384a..92050c8885 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtSurface.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtSurface.java
@@ -50,13 +50,13 @@ class QtSurface extends SurfaceView implements SurfaceHolder.Callback
if (width < 1 || height < 1)
return;
- QtNative.setSurface(getId(), holder.getSurface(), width, height);
+ QtNative.setSurface(getId(), holder.getSurface());
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
- QtNative.setSurface(getId(), null, 0, 0);
+ QtNative.setSurface(getId(), null);
}
@Override
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 1f1fbc65c8..0b2bc18f94 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -641,6 +641,8 @@ endif()
qt_internal_extend_target(Gui CONDITION ANDROID
SOURCES
platform/android/qandroidnativeinterface.cpp
+ painting/qrasterbackingstore.cpp painting/qrasterbackingstore_p.h
+ painting/qrhibackingstore.cpp painting/qrhibackingstore_p.h
)
qt_internal_extend_target(Gui CONDITION ANDROID AND (TEST_architecture_arch STREQUAL arm64 OR TEST_architecture_arch STREQUAL arm)
diff --git a/src/plugins/platforms/android/CMakeLists.txt b/src/plugins/platforms/android/CMakeLists.txt
index db961e7a93..a3344bfd71 100644
--- a/src/plugins/platforms/android/CMakeLists.txt
+++ b/src/plugins/platforms/android/CMakeLists.txt
@@ -17,13 +17,11 @@ qt_internal_add_plugin(QAndroidIntegrationPlugin
androidjniinput.cpp androidjniinput.h
androidjnimain.cpp androidjnimain.h
androidjnimenu.cpp androidjnimenu.h
- androidsurfaceclient.h
main.cpp
qandroidassetsfileenginehandler.cpp qandroidassetsfileenginehandler.h
qandroideventdispatcher.cpp qandroideventdispatcher.h
qandroidinputcontext.cpp qandroidinputcontext.h
qandroidplatformaccessibility.cpp qandroidplatformaccessibility.h
- qandroidplatformbackingstore.cpp qandroidplatformbackingstore.h
qandroidplatformclipboard.cpp qandroidplatformclipboard.h
qandroidplatformdialoghelpers.cpp qandroidplatformdialoghelpers.h
qandroidplatformfiledialoghelper.cpp qandroidplatformfiledialoghelper.h
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 1a451b61e7..fdf4611ff6 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -18,6 +18,7 @@
#include "qandroidplatformdialoghelpers.h"
#include "qandroidplatformintegration.h"
#include "qandroidplatformclipboard.h"
+#include "qandroidplatformwindow.h"
#include <android/api-level.h>
#include <android/asset_manager_jni.h>
@@ -69,7 +70,7 @@ static void *m_mainLibraryHnd = nullptr;
static QList<QByteArray> m_applicationParams;
static sem_t m_exitSemaphore, m_terminateSemaphore;
-QHash<int, AndroidSurfaceClient *> m_surfaces;
+QHash<int, QAndroidPlatformWindow *> m_surfaces;
Q_CONSTINIT static QBasicMutex m_surfacesMutex;
@@ -323,7 +324,7 @@ namespace QtAndroid
return QJniObject::callStaticMethod<jint>("android/view/View", "generateViewId", "()I");
}
- int createSurface(AndroidSurfaceClient *client, const QRect &geometry, bool onTop, int imageDepth)
+ int createSurface(QAndroidPlatformWindow *window, const QRect &geometry, bool onTop, int imageDepth)
{
QJniEnvironment env;
if (!env.jniEnv())
@@ -331,7 +332,7 @@ namespace QtAndroid
m_surfacesMutex.lock();
jint surfaceId = generateViewId();
- m_surfaces[surfaceId] = client;
+ m_surfaces[surfaceId] = window;
m_surfacesMutex.unlock();
jint x = 0, y = 0, w = -1, h = -1;
@@ -594,8 +595,11 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/)
sem_post(&m_exitSemaphore);
}
-static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface, jint w, jint h)
+static void setSurface(JNIEnv *env, jobject thiz, jint id, jobject jSurface)
{
+ Q_UNUSED(env);
+ Q_UNUSED(thiz);
+
QMutexLocker lock(&m_surfacesMutex);
const auto &it = m_surfaces.find(id);
if (it == m_surfaces.end())
@@ -603,7 +607,7 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface,
auto surfaceClient = it.value();
if (surfaceClient)
- surfaceClient->surfaceChanged(env, jSurface, w, h);
+ surfaceClient->onSurfaceChanged(jSurface);
}
static void setDisplayMetrics(JNIEnv * /*env*/, jclass /*clazz*/, jint screenWidthPixels,
@@ -658,10 +662,6 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
QWindowSystemInterface::handleExposeEvent(w, QRegion(QRect(QPoint(), w->geometry().size())));
}
}
-
- QAndroidPlatformScreen *screen = static_cast<QAndroidPlatformScreen *>(m_androidPlatformIntegration->screen());
- if (screen->rasterSurfaces())
- QMetaObject::invokeMethod(screen, "setDirty", Qt::QueuedConnection, Q_ARG(QRect,screen->geometry()));
}
static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state)
@@ -802,7 +802,7 @@ static JNINativeMethod methods[] = {
{ "quitQtCoreApplication", "()V", (void *)quitQtCoreApplication },
{ "terminateQt", "()V", (void *)terminateQt },
{ "waitForServiceSetup", "()V", (void *)waitForServiceSetup },
- { "setSurface", "(ILjava/lang/Object;II)V", (void *)setSurface },
+ { "setSurface", "(ILjava/lang/Object;)V", (void *)setSurface },
{ "updateWindow", "()V", (void *)updateWindow },
{ "updateApplicationState", "(I)V", (void *)updateApplicationState },
{ "onActivityResult", "(IILandroid/content/Intent;)V", (void *)onActivityResult },
diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h
index 349eba9962..090e87d7f7 100644
--- a/src/plugins/platforms/android/androidjnimain.h
+++ b/src/plugins/platforms/android/androidjnimain.h
@@ -23,7 +23,7 @@ class QAndroidPlatformIntegration;
class QWidget;
class QString;
class QWindow;
-class AndroidSurfaceClient;
+class QAndroidPlatformWindow;
class QBasicMutex;
Q_DECLARE_JNI_CLASS(QtActivityDelegate, "org/qtproject/qt/android/QtActivityDelegate")
@@ -37,7 +37,7 @@ namespace QtAndroid
void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration);
void setQtThread(QThread *thread);
- int createSurface(AndroidSurfaceClient * client, const QRect &geometry, bool onTop, int imageDepth);
+ int createSurface(QAndroidPlatformWindow *window, const QRect &geometry, bool onTop, int imageDepth);
int insertNativeView(QtJniTypes::View view, const QRect &geometry);
void setViewVisibility(jobject view, bool visible);
void setSurfaceGeometry(int surfaceId, const QRect &geometry);
diff --git a/src/plugins/platforms/android/androidsurfaceclient.h b/src/plugins/platforms/android/androidsurfaceclient.h
deleted file mode 100644
index dded9a1f66..0000000000
--- a/src/plugins/platforms/android/androidsurfaceclient.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef ANDROIDSURFACECLIENT_H
-#define ANDROIDSURFACECLIENT_H
-#include <QMutex>
-#include <jni.h>
-
-QT_BEGIN_NAMESPACE
-
-class AndroidSurfaceClient
-{
-public:
- virtual void surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h) = 0;
- void lockSurface() { m_surfaceMutex.lock(); }
- void unlockSurface() { m_surfaceMutex.unlock(); }
-
-protected:
- QMutex m_surfaceMutex;
-};
-
-QT_END_NAMESPACE
-
-#endif // ANDROIDSURFACECLIENT_H
diff --git a/src/plugins/platforms/android/qandroidplatformbackingstore.cpp b/src/plugins/platforms/android/qandroidplatformbackingstore.cpp
deleted file mode 100644
index 09cc9ce8c6..0000000000
--- a/src/plugins/platforms/android/qandroidplatformbackingstore.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "qandroidplatformbackingstore.h"
-#include "qandroidplatformscreen.h"
-#include "qandroidplatformwindow.h"
-#include <qpa/qplatformscreen.h>
-
-QT_BEGIN_NAMESPACE
-
-QAndroidPlatformBackingStore::QAndroidPlatformBackingStore(QWindow *window)
- : QPlatformBackingStore(window)
-{
- if (window->handle())
- setBackingStore(window);
-}
-
-QPaintDevice *QAndroidPlatformBackingStore::paintDevice()
-{
- return &m_image;
-}
-
-void QAndroidPlatformBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(offset);
-
- auto *platformWindow = static_cast<QAndroidPlatformWindow *>(window->handle());
- if (!platformWindow->backingStore())
- setBackingStore(window);
-
- platformWindow->repaint(region);
-}
-
-void QAndroidPlatformBackingStore::resize(const QSize &size, const QRegion &staticContents)
-{
- Q_UNUSED(staticContents);
-
- if (m_image.size() != size)
- m_image = QImage(size, window()->screen()->handle()->format());
-}
-
-void QAndroidPlatformBackingStore::setBackingStore(QWindow *window)
-{
- (static_cast<QAndroidPlatformWindow *>(window->handle()))->setBackingStore(this);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformbackingstore.h b/src/plugins/platforms/android/qandroidplatformbackingstore.h
deleted file mode 100644
index b64a9f27bb..0000000000
--- a/src/plugins/platforms/android/qandroidplatformbackingstore.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef QANDROIDPLATFORMBACKINGSTORE_H
-#define QANDROIDPLATFORMBACKINGSTORE_H
-
-#include <qpa/qplatformbackingstore.h>
-#include <qpa/qwindowsysteminterface.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAndroidPlatformBackingStore : public QPlatformBackingStore
-{
-public:
- explicit QAndroidPlatformBackingStore(QWindow *window);
- QPaintDevice *paintDevice() override;
- void flush(QWindow *window, const QRegion &region, const QPoint &offset) override;
- void resize(const QSize &size, const QRegion &staticContents) override;
- QImage toImage() const override { return m_image; }
- void setBackingStore(QWindow *window);
-protected:
- QImage m_image;
-};
-
-QT_END_NAMESPACE
-
-#endif // QANDROIDPLATFORMBACKINGSTORE_H
diff --git a/src/plugins/platforms/android/qandroidplatformforeignwindow.h b/src/plugins/platforms/android/qandroidplatformforeignwindow.h
index 7b576ecec4..7ddacda17f 100644
--- a/src/plugins/platforms/android/qandroidplatformforeignwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformforeignwindow.h
@@ -4,7 +4,6 @@
#ifndef QANDROIDPLATFORMFOREIGNWINDOW_H
#define QANDROIDPLATFORMFOREIGNWINDOW_H
-#include "androidsurfaceclient.h"
#include "qandroidplatformwindow.h"
#include <QtCore/QJniObject>
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index a31e3c8f69..d6d4ded3f2 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -9,7 +9,6 @@
#include "qabstracteventdispatcher.h"
#include "qandroideventdispatcher.h"
#include "qandroidplatformaccessibility.h"
-#include "qandroidplatformbackingstore.h"
#include "qandroidplatformclipboard.h"
#include "qandroidplatformfontdatabase.h"
#include "qandroidplatformforeignwindow.h"
@@ -29,6 +28,7 @@
#include <QtGui/private/qeglpbuffer_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qoffscreensurface_p.h>
+#include <QtGui/private/qrhibackingstore_p.h>
#include <qpa/qplatformoffscreensurface.h>
#include <qpa/qplatformwindow.h>
#include <qpa/qwindowsysteminterface.h>
@@ -323,6 +323,9 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
case RasterGLSurface: return QtAndroidPrivate::activity().isValid();
case TopStackedNativeChildWindows: return false;
case MaximizeUsingFullscreenGeometry: return true;
+ // FIXME QTBUG-118849 - we do not implement grabWindow() anymore, calling it will return
+ // a null QPixmap also for raster windows - for OpenGL windows this was always true
+ case ScreenWindowGrabbing: return false;
default:
return QPlatformIntegration::hasCapability(cap);
}
@@ -333,7 +336,7 @@ QPlatformBackingStore *QAndroidPlatformIntegration::createPlatformBackingStore(Q
if (!QtAndroidPrivate::activity().isValid())
return nullptr;
- return new QAndroidPlatformBackingStore(window);
+ return new QRhiBackingStore(window);
}
QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
index c1ec2fbdd6..7f2252a4e9 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
@@ -24,41 +24,19 @@ QT_BEGIN_NAMESPACE
QAndroidPlatformOpenGLWindow::QAndroidPlatformOpenGLWindow(QWindow *window, EGLDisplay display)
:QAndroidPlatformWindow(window), m_eglDisplay(display)
{
+ if (window->surfaceType() == QSurface::RasterSurface)
+ window->setSurfaceType(QSurface::OpenGLSurface);
}
QAndroidPlatformOpenGLWindow::~QAndroidPlatformOpenGLWindow()
{
m_surfaceWaitCondition.wakeOne();
lockSurface();
- if (m_nativeSurfaceId != -1)
- QtAndroid::destroySurface(m_nativeSurfaceId);
+ destroySurface();
clearEgl();
unlockSurface();
}
-void QAndroidPlatformOpenGLWindow::repaint(const QRegion &region)
-{
- // This is only for real raster top-level windows. Stop in all other cases.
- if ((window()->surfaceType() == QSurface::RasterGLSurface && qt_window_private(window())->compositing)
- || window()->surfaceType() == QSurface::OpenGLSurface
- || QAndroidPlatformWindow::parent())
- return;
-
- QRect currentGeometry = geometry();
-
- QRect dirtyClient = region.boundingRect();
- QRect dirtyRegion(currentGeometry.left() + dirtyClient.left(),
- currentGeometry.top() + dirtyClient.top(),
- dirtyClient.width(),
- dirtyClient.height());
- QRect mOldGeometryLocal = m_oldGeometry;
- m_oldGeometry = currentGeometry;
- // If this is a move, redraw the previous location
- if (mOldGeometryLocal != currentGeometry)
- platformScreen()->setDirty(mOldGeometryLocal);
- platformScreen()->setDirty(dirtyRegion);
-}
-
void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect)
{
if (rect == geometry())
@@ -67,8 +45,7 @@ void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect)
m_oldGeometry = geometry();
QAndroidPlatformWindow::setGeometry(rect);
- if (m_nativeSurfaceId != -1)
- QtAndroid::setSurfaceGeometry(m_nativeSurfaceId, rect);
+ setSurfaceGeometry(rect);
QRect availableGeometry = screen()->availableGeometry();
if (rect.width() > 0
@@ -77,9 +54,6 @@ void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect)
&& availableGeometry.height() > 0) {
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), rect.size()));
}
-
- if (rect.topLeft() != m_oldGeometry.topLeft())
- repaint(QRegion(rect));
}
EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config)
@@ -94,8 +68,7 @@ EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config)
if (!protector.acquire())
return m_eglSurface;
- const bool windowStaysOnTop = bool(window()->flags() & Qt::WindowStaysOnTopHint);
- m_nativeSurfaceId = QtAndroid::createSurface(this, geometry(), windowStaysOnTop, 32);
+ createSurface();
m_surfaceWaitCondition.wait(&m_surfaceMutex);
}
@@ -127,10 +100,7 @@ void QAndroidPlatformOpenGLWindow::applicationStateChanged(Qt::ApplicationState
QAndroidPlatformWindow::applicationStateChanged(state);
if (state <= Qt::ApplicationHidden) {
lockSurface();
- if (m_nativeSurfaceId != -1) {
- QtAndroid::destroySurface(m_nativeSurfaceId);
- m_nativeSurfaceId = -1;
- }
+ destroySurface();
clearEgl();
unlockSurface();
}
@@ -173,24 +143,4 @@ void QAndroidPlatformOpenGLWindow::clearEgl()
}
}
-void QAndroidPlatformOpenGLWindow::surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h)
-{
- Q_UNUSED(jniEnv);
- Q_UNUSED(w);
- Q_UNUSED(h);
-
- lockSurface();
- m_androidSurfaceObject = surface;
- if (surface) // wait until we have a valid surface to draw into
- m_surfaceWaitCondition.wakeOne();
- unlockSurface();
-
- if (surface) {
- // repaint the window, when we have a valid surface
- 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())));
- }
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.h b/src/plugins/platforms/android/qandroidplatformopenglwindow.h
index 8c31368b65..c1ae57fe85 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.h
@@ -5,7 +5,6 @@
#ifndef QANDROIDPLATFORMOPENGLWINDOW_H
#define QANDROIDPLATFORMOPENGLWINDOW_H
-#include "androidsurfaceclient.h"
#include "qandroidplatformwindow.h"
#include <QWaitCondition>
@@ -16,7 +15,7 @@
QT_BEGIN_NAMESPACE
-class QAndroidPlatformOpenGLWindow : public QAndroidPlatformWindow, public AndroidSurfaceClient
+class QAndroidPlatformOpenGLWindow : public QAndroidPlatformWindow
{
public:
explicit QAndroidPlatformOpenGLWindow(QWindow *window, EGLDisplay display);
@@ -30,10 +29,7 @@ public:
void applicationStateChanged(Qt::ApplicationState) override;
- void repaint(const QRegion &region) override;
-
protected:
- void surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h) override;
void createEgl(EGLConfig config);
void clearEgl();
@@ -42,9 +38,6 @@ private:
EGLSurface m_eglSurface = EGL_NO_SURFACE;
EGLNativeWindowType m_nativeWindow = nullptr;
- int m_nativeSurfaceId = -1;
- QJniObject m_androidSurfaceObject;
- QWaitCondition m_surfaceWaitCondition;
QSurfaceFormat m_format;
QRect m_oldGeometry;
};
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index 20f414b48f..268772e265 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -8,7 +8,6 @@
#include <qpa/qwindowsysteminterface.h>
#include "qandroidplatformscreen.h"
-#include "qandroidplatformbackingstore.h"
#include "qandroidplatformintegration.h"
#include "qandroidplatformwindow.h"
#include "androidjnimain.h"
@@ -131,11 +130,6 @@ QAndroidPlatformScreen::QAndroidPlatformScreen(const QJniObject &displayObject)
QAndroidPlatformScreen::~QAndroidPlatformScreen()
{
- if (m_surfaceId != -1) {
- QtAndroid::destroySurface(m_surfaceId);
- m_surfaceWaitCondition.wakeOne();
- releaseSurface();
- }
}
QWindow *QAndroidPlatformScreen::topWindow() const
@@ -159,16 +153,6 @@ QWindow *QAndroidPlatformScreen::topLevelAt(const QPoint &p) const
return 0;
}
-bool QAndroidPlatformScreen::event(QEvent *event)
-{
- if (event->type() == QEvent::UpdateRequest) {
- doRedraw();
- m_updatePending = false;
- return true;
- }
- return QObject::event(event);
-}
-
void QAndroidPlatformScreen::addWindow(QAndroidPlatformWindow *window)
{
if (window->parent() && window->isRaster())
@@ -178,10 +162,6 @@ void QAndroidPlatformScreen::addWindow(QAndroidPlatformWindow *window)
return;
m_windowStack.prepend(window);
- if (window->isRaster()) {
- m_rasterSurfaces.ref();
- setDirty(window->geometry());
- }
QWindow *w = topWindow();
QWindowSystemInterface::handleFocusWindowChanged(w, Qt::ActiveWindowFocusReason);
@@ -198,11 +178,6 @@ void QAndroidPlatformScreen::removeWindow(QAndroidPlatformWindow *window)
if (m_windowStack.contains(window))
qWarning() << "Failed to remove window";
- if (window->isRaster()) {
- m_rasterSurfaces.deref();
- setDirty(window->geometry());
- }
-
QWindow *w = topWindow();
QWindowSystemInterface::handleFocusWindowChanged(w, Qt::ActiveWindowFocusReason);
topWindowChanged(w);
@@ -210,16 +185,11 @@ void QAndroidPlatformScreen::removeWindow(QAndroidPlatformWindow *window)
void QAndroidPlatformScreen::raise(QAndroidPlatformWindow *window)
{
- if (window->parent() && window->isRaster())
- return;
-
int index = m_windowStack.indexOf(window);
if (index <= 0)
return;
m_windowStack.move(index, 0);
- if (window->isRaster()) {
- setDirty(window->geometry());
- }
+
QWindow *w = topWindow();
QWindowSystemInterface::handleFocusWindowChanged(w, Qt::ActiveWindowFocusReason);
topWindowChanged(w);
@@ -227,36 +197,16 @@ void QAndroidPlatformScreen::raise(QAndroidPlatformWindow *window)
void QAndroidPlatformScreen::lower(QAndroidPlatformWindow *window)
{
- if (window->parent() && window->isRaster())
- return;
-
int index = m_windowStack.indexOf(window);
if (index == -1 || index == (m_windowStack.size() - 1))
return;
m_windowStack.move(index, m_windowStack.size() - 1);
- if (window->isRaster()) {
- setDirty(window->geometry());
- }
+
QWindow *w = topWindow();
QWindowSystemInterface::handleFocusWindowChanged(w, Qt::ActiveWindowFocusReason);
topWindowChanged(w);
}
-void QAndroidPlatformScreen::scheduleUpdate()
-{
- if (!m_updatePending) {
- m_updatePending = true;
- QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
- }
-}
-
-void QAndroidPlatformScreen::setDirty(const QRect &rect)
-{
- QRect intersection = rect.intersected(m_availableGeometry);
- m_dirtyRect |= intersection;
- scheduleUpdate();
-}
-
void QAndroidPlatformScreen::setPhysicalSize(const QSize &size)
{
m_physicalSize = size;
@@ -306,7 +256,6 @@ void QAndroidPlatformScreen::setOrientation(Qt::ScreenOrientation orientation)
void QAndroidPlatformScreen::setAvailableGeometry(const QRect &rect)
{
- QMutexLocker lock(&m_surfaceMutex);
if (m_availableGeometry == rect)
return;
@@ -327,25 +276,12 @@ void QAndroidPlatformScreen::setAvailableGeometry(const QRect &rect)
}
}
}
-
- if (m_surfaceId != -1) {
- releaseSurface();
- QtAndroid::setSurfaceGeometry(m_surfaceId, rect);
- }
}
void QAndroidPlatformScreen::applicationStateChanged(Qt::ApplicationState state)
{
for (QAndroidPlatformWindow *w : std::as_const(m_windowStack))
w->applicationStateChanged(state);
-
- if (state <= Qt::ApplicationHidden) {
- lockSurface();
- QtAndroid::destroySurface(m_surfaceId);
- m_surfaceId = -1;
- releaseSurface();
- unlockSurface();
- }
}
void QAndroidPlatformScreen::topWindowChanged(QWindow *w)
@@ -359,133 +295,6 @@ void QAndroidPlatformScreen::topWindowChanged(QWindow *w)
}
}
-int QAndroidPlatformScreen::rasterSurfaces()
-{
- return m_rasterSurfaces;
-}
-
-void QAndroidPlatformScreen::doRedraw(QImage* screenGrabImage)
-{
- PROFILE_SCOPE;
- if (!QtAndroidPrivate::activity().isValid())
- return;
-
- if (m_dirtyRect.isEmpty())
- return;
-
- // Stop if there are no visible raster windows. If we only have RasterGLSurface
- // windows that have renderToTexture children (i.e. they need the OpenGL path) then
- // we do not need an overlay surface.
- bool hasVisibleRasterWindows = false;
- for (QAndroidPlatformWindow *window : std::as_const(m_windowStack)) {
- if (window->window()->isVisible() && window->isRaster() && !qt_window_private(window->window())->compositing) {
- hasVisibleRasterWindows = true;
- break;
- }
- }
- if (!hasVisibleRasterWindows) {
- lockSurface();
- if (m_surfaceId != -1) {
- QtAndroid::destroySurface(m_surfaceId);
- releaseSurface();
- m_surfaceId = -1;
- }
- unlockSurface();
- return;
- }
- QMutexLocker lock(&m_surfaceMutex);
- if (m_surfaceId == -1 && m_rasterSurfaces) {
- m_surfaceId = QtAndroid::createSurface(this, geometry(), true, m_depth);
- AndroidDeadlockProtector protector;
- if (!protector.acquire())
- return;
- m_surfaceWaitCondition.wait(&m_surfaceMutex);
- }
-
- if (!m_nativeSurface)
- return;
-
- ANativeWindow_Buffer nativeWindowBuffer;
- ARect nativeWindowRect;
- nativeWindowRect.top = m_dirtyRect.top();
- nativeWindowRect.left = m_dirtyRect.left();
- nativeWindowRect.bottom = m_dirtyRect.bottom() + 1; // for some reason that I don't understand the QRect bottom needs to +1 to be the same with ARect bottom
- nativeWindowRect.right = m_dirtyRect.right() + 1; // same for the right
-
- int ret;
- if ((ret = ANativeWindow_lock(m_nativeSurface, &nativeWindowBuffer, &nativeWindowRect)) < 0) {
- qWarning() << "ANativeWindow_lock() failed! error=" << ret;
- return;
- }
-
- int bpp = 4;
- if (nativeWindowBuffer.format == WINDOW_FORMAT_RGB_565) {
- bpp = 2;
- m_pixelFormat = QImage::Format_RGB16;
- }
-
- QImage screenImage(reinterpret_cast<uchar *>(nativeWindowBuffer.bits)
- , nativeWindowBuffer.width, nativeWindowBuffer.height
- , nativeWindowBuffer.stride * bpp , m_pixelFormat);
-
- QPainter compositePainter(&screenImage);
- compositePainter.setCompositionMode(QPainter::CompositionMode_Source);
-
- QRegion visibleRegion(m_dirtyRect);
- for (QAndroidPlatformWindow *window : std::as_const(m_windowStack)) {
- if (!window->window()->isVisible()
- || qt_window_private(window->window())->compositing
- || !window->isRaster())
- continue;
-
- for (const QRect &rect : std::vector<QRect>(visibleRegion.begin(), visibleRegion.end())) {
- QRect targetRect = window->geometry();
- targetRect &= rect;
-
- if (targetRect.isNull())
- continue;
-
- visibleRegion -= targetRect;
- QRect windowRect = targetRect.translated(-window->geometry().topLeft());
- QAndroidPlatformBackingStore *backingStore = static_cast<QAndroidPlatformWindow *>(window)->backingStore();
- if (backingStore)
- compositePainter.drawImage(targetRect.topLeft(), backingStore->toImage(), windowRect);
- }
- }
-
- for (const QRect &rect : visibleRegion)
- compositePainter.fillRect(rect, QColor(Qt::transparent));
-
- ret = ANativeWindow_unlockAndPost(m_nativeSurface);
- if (ret >= 0)
- m_dirtyRect = QRect();
-
- if (screenGrabImage) {
- if (screenGrabImage->size() != screenImage.size()) {
- uchar* bytes = static_cast<uchar*>(malloc(screenImage.height() * screenImage.bytesPerLine()));
- *screenGrabImage = QImage(bytes, screenImage.width(), screenImage.height(),
- screenImage.bytesPerLine(), m_pixelFormat,
- [](void* ptr){ if (ptr) free (ptr);});
- }
- memcpy(screenGrabImage->bits(),
- screenImage.bits(),
- screenImage.bytesPerLine() * screenImage.height());
- }
- m_repaintOccurred = true;
-}
-
-QPixmap QAndroidPlatformScreen::doScreenShot(QRect grabRect)
-{
- if (!m_repaintOccurred)
- return QPixmap::fromImage(m_lastScreenshot.copy(grabRect));
- QRect tmp = m_dirtyRect;
- m_dirtyRect = geometry();
- doRedraw(&m_lastScreenshot);
- m_dirtyRect = tmp;
- m_repaintOccurred = false;
- return QPixmap::fromImage(m_lastScreenshot.copy(grabRect));
-}
-
static const int androidLogicalDpi = 72;
QDpi QAndroidPlatformScreen::logicalDpi() const
@@ -508,67 +317,4 @@ Qt::ScreenOrientation QAndroidPlatformScreen::nativeOrientation() const
{
return QAndroidPlatformIntegration::m_nativeOrientation;
}
-
-void QAndroidPlatformScreen::surfaceChanged(JNIEnv *env, jobject surface, int w, int h)
-{
- lockSurface();
- if (surface && w > 0 && h > 0) {
- releaseSurface();
- m_nativeSurface = ANativeWindow_fromSurface(env, surface);
- QMetaObject::invokeMethod(this, "setDirty", Qt::QueuedConnection, Q_ARG(QRect, QRect(0, 0, w, h)));
- } else {
- releaseSurface();
- }
- unlockSurface();
- m_surfaceWaitCondition.wakeOne();
-}
-
-void QAndroidPlatformScreen::releaseSurface()
-{
- if (m_nativeSurface) {
- ANativeWindow_release(m_nativeSurface);
- m_nativeSurface = 0;
- }
-}
-
-/*!
- This function is called when Qt needs to be able to grab the content of a window.
-
- Returns the content of the window specified with the WId handle within the boundaries of
- QRect(x, y, width, height).
-*/
-QPixmap QAndroidPlatformScreen::grabWindow(WId window, int x, int y, int width, int height) const
-{
- QRectF screenshotRect(x, y, width, height);
- QWindow* wnd = 0;
- if (window)
- {
- const auto windowList = qApp->allWindows();
- for (QWindow *w : windowList)
- if (w->winId() == window) {
- wnd = w;
- break;
- }
- }
- if (wnd) {
- const qreal factor = logicalDpi().first / androidLogicalDpi; //HighDPI factor;
- QRectF wndRect = wnd->geometry();
- if (wnd->parent())
- wndRect.moveTopLeft(wnd->parent()->mapToGlobal(wndRect.topLeft().toPoint()));
- if (!qFuzzyCompare(factor, 1))
- wndRect = QRectF(wndRect.left() * factor, wndRect.top() * factor,
- wndRect.width() * factor, wndRect.height() * factor);
-
- if (!screenshotRect.isEmpty()) {
- screenshotRect.moveTopLeft(wndRect.topLeft() + screenshotRect.topLeft());
- screenshotRect = screenshotRect.intersected(wndRect);
- } else {
- screenshotRect = wndRect;
- }
- } else {
- screenshotRect = screenshotRect.isValid() ? screenshotRect : geometry();
- }
- return const_cast<QAndroidPlatformScreen *>(this)->doScreenShot(screenshotRect.toRect());
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h
index 076530613b..0e2f788886 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.h
+++ b/src/plugins/platforms/android/qandroidplatformscreen.h
@@ -5,8 +5,6 @@
#ifndef QANDROIDPLATFORMSCREEN_H
#define QANDROIDPLATFORMSCREEN_H
-#include "androidsurfaceclient.h"
-
#include <QList>
#include <QPainter>
#include <QTimer>
@@ -15,14 +13,12 @@
#include <qpa/qplatformscreen.h>
#include <qpa/qplatformscreen_p.h>
-#include <android/native_window.h>
-
QT_BEGIN_NAMESPACE
class QAndroidPlatformWindow;
class QAndroidPlatformScreen: public QObject,
- public QPlatformScreen, public AndroidSurfaceClient,
+ public QPlatformScreen,
public QNativeInterface::Private::QAndroidScreen
{
Q_OBJECT
@@ -44,19 +40,15 @@ public:
inline QWindow *topWindow() const;
QWindow *topLevelAt(const QPoint & p) const override;
- // compositor api
void addWindow(QAndroidPlatformWindow *window);
void removeWindow(QAndroidPlatformWindow *window);
void raise(QAndroidPlatformWindow *window);
void lower(QAndroidPlatformWindow *window);
- void scheduleUpdate();
void topWindowChanged(QWindow *w);
- int rasterSurfaces();
int displayId() const override;
public slots:
- void setDirty(const QRect &rect);
void setPhysicalSize(const QSize &size);
void setAvailableGeometry(const QRect &rect);
void setSize(const QSize &size);
@@ -66,12 +58,8 @@ public slots:
void setOrientation(Qt::ScreenOrientation orientation);
protected:
- bool event(QEvent *event) override;
-
typedef QList<QAndroidPlatformWindow *> WindowStackType;
WindowStackType m_windowStack;
- QRect m_dirtyRect;
- bool m_updatePending = false;
QRect m_availableGeometry;
int m_depth;
@@ -88,25 +76,9 @@ private:
QDpi logicalBaseDpi() const override;
Qt::ScreenOrientation orientation() const override;
Qt::ScreenOrientation nativeOrientation() const override;
- QPixmap grabWindow(WId window, int x, int y, int width, int height) const override;
- void surfaceChanged(JNIEnv *env, jobject surface, int w, int h) override;
- void releaseSurface();
void applicationStateChanged(Qt::ApplicationState);
- QPixmap doScreenShot(QRect grabRect = QRect());
-
-private slots:
- void doRedraw(QImage *screenGrabImage = nullptr);
-
private:
- int m_surfaceId = -1;
- QAtomicInt m_rasterSurfaces = 0;
- ANativeWindow* m_nativeSurface = nullptr;
- QWaitCondition m_surfaceWaitCondition;
QSize m_size;
-
- QImage m_lastScreenshot;
- QImage::Format m_pixelFormat = QImage::Format_RGBA8888_Premultiplied;
- bool m_repaintOccurred = false;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformvulkanwindow.cpp b/src/plugins/platforms/android/qandroidplatformvulkanwindow.cpp
index cb6bb6d390..df87240c2b 100644
--- a/src/plugins/platforms/android/qandroidplatformvulkanwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformvulkanwindow.cpp
@@ -18,7 +18,6 @@ QT_BEGIN_NAMESPACE
QAndroidPlatformVulkanWindow::QAndroidPlatformVulkanWindow(QWindow *window)
: QAndroidPlatformWindow(window),
- m_nativeSurfaceId(-1),
m_nativeWindow(nullptr),
m_vkSurface(0),
m_createVkSurface(nullptr),
@@ -29,11 +28,7 @@ QAndroidPlatformVulkanWindow::QAndroidPlatformVulkanWindow(QWindow *window)
QAndroidPlatformVulkanWindow::~QAndroidPlatformVulkanWindow()
{
m_surfaceWaitCondition.wakeOne();
- lockSurface();
- if (m_nativeSurfaceId != -1)
- QtAndroid::destroySurface(m_nativeSurfaceId);
- clearSurface();
- unlockSurface();
+ destroyAndClearSurface();
}
void QAndroidPlatformVulkanWindow::setGeometry(const QRect &rect)
@@ -44,8 +39,7 @@ void QAndroidPlatformVulkanWindow::setGeometry(const QRect &rect)
m_oldGeometry = geometry();
QAndroidPlatformWindow::setGeometry(rect);
- if (m_nativeSurfaceId != -1)
- QtAndroid::setSurfaceGeometry(m_nativeSurfaceId, rect);
+ setSurfaceGeometry(rect);
QRect availableGeometry = screen()->availableGeometry();
if (rect.width() > 0
@@ -54,22 +48,13 @@ void QAndroidPlatformVulkanWindow::setGeometry(const QRect &rect)
&& 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();
+ destroyAndClearSurface();
}
}
@@ -91,27 +76,12 @@ void QAndroidPlatformVulkanWindow::clearSurface()
}
}
-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)
+void QAndroidPlatformVulkanWindow::destroyAndClearSurface()
{
- Q_UNUSED(jniEnv);
- Q_UNUSED(w);
- Q_UNUSED(h);
-
lockSurface();
- m_androidSurfaceObject = surface;
- if (surface)
- m_surfaceWaitCondition.wakeOne();
+ destroySurface();
+ clearSurface();
unlockSurface();
-
- if (surface)
- sendExpose();
}
VkSurfaceKHR *QAndroidPlatformVulkanWindow::vkSurface()
@@ -128,8 +98,7 @@ VkSurfaceKHR *QAndroidPlatformVulkanWindow::vkSurface()
AndroidDeadlockProtector protector;
if (!protector.acquire())
return &m_vkSurface;
- const bool windowStaysOnTop = bool(window()->flags() & Qt::WindowStaysOnTopHint);
- m_nativeSurfaceId = QtAndroid::createSurface(this, geometry(), windowStaysOnTop, 32);
+ createSurface();
m_surfaceWaitCondition.wait(&m_surfaceMutex);
}
diff --git a/src/plugins/platforms/android/qandroidplatformvulkanwindow.h b/src/plugins/platforms/android/qandroidplatformvulkanwindow.h
index 14d5b7fc0e..fa959239d1 100644
--- a/src/plugins/platforms/android/qandroidplatformvulkanwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformvulkanwindow.h
@@ -10,7 +10,6 @@
#define VK_USE_PLATFORM_ANDROID_KHR
-#include "androidsurfaceclient.h"
#include "qandroidplatformvulkaninstance.h"
#include "qandroidplatformwindow.h"
@@ -20,7 +19,7 @@
QT_BEGIN_NAMESPACE
-class QAndroidPlatformVulkanWindow : public QAndroidPlatformWindow, public AndroidSurfaceClient
+class QAndroidPlatformVulkanWindow : public QAndroidPlatformWindow
{
public:
explicit QAndroidPlatformVulkanWindow(QWindow *window);
@@ -32,17 +31,11 @@ public:
VkSurfaceKHR *vkSurface();
-protected:
- void surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h) override;
-
private:
- void sendExpose();
void clearSurface();
+ void destroyAndClearSurface();
- int m_nativeSurfaceId;
ANativeWindow *m_nativeWindow;
- QJniObject m_androidSurfaceObject;
- QWaitCondition m_surfaceWaitCondition;
QSurfaceFormat m_format;
QRect m_oldGeometry;
VkSurfaceKHR m_vkSurface;
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp
index 61d326228c..23b83834d4 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp
@@ -17,10 +17,13 @@ QT_BEGIN_NAMESPACE
Q_CONSTINIT static QBasicAtomicInt winIdGenerator = Q_BASIC_ATOMIC_INITIALIZER(0);
QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
- : QPlatformWindow(window)
+ : QPlatformWindow(window), m_androidSurfaceObject(nullptr)
{
m_windowFlags = Qt::Widget;
m_windowState = Qt::WindowNoState;
+ // the surfaceType is overwritten in QAndroidPlatformOpenGLWindow ctor so let's save
+ // the fact that it's a raster window for now
+ m_isRaster = window->surfaceType() == QSurface::RasterSurface;
m_windowId = winIdGenerator.fetchAndAddRelaxed(1) + 1;
setWindowState(window->windowStates());
@@ -171,4 +174,44 @@ void QAndroidPlatformWindow::applicationStateChanged(Qt::ApplicationState)
QWindowSystemInterface::flushWindowSystemEvents();
}
+void QAndroidPlatformWindow::createSurface()
+{
+ const bool windowStaysOnTop = bool(window()->flags() & Qt::WindowStaysOnTopHint);
+ m_nativeSurfaceId = QtAndroid::createSurface(this, geometry(), windowStaysOnTop, 32);
+}
+
+void QAndroidPlatformWindow::destroySurface()
+{
+ if (m_nativeSurfaceId != -1) {
+ QtAndroid::destroySurface(m_nativeSurfaceId);
+ m_nativeSurfaceId = -1;
+ }
+}
+
+void QAndroidPlatformWindow::setSurfaceGeometry(const QRect &rect)
+{
+ if (m_nativeSurfaceId != -1)
+ QtAndroid::setSurfaceGeometry(m_nativeSurfaceId, rect);
+}
+
+void QAndroidPlatformWindow::sendExpose()
+{
+ QRect availableGeometry = screen()->availableGeometry();
+ if (!geometry().isNull() && !availableGeometry.isNull()) {
+ QWindowSystemInterface::handleExposeEvent(window(),
+ QRegion(QRect(QPoint(), geometry().size())));
+ }
+}
+
+void QAndroidPlatformWindow::onSurfaceChanged(QtJniTypes::Surface surface)
+{
+ lockSurface();
+ m_androidSurfaceObject = surface;
+ if (m_androidSurfaceObject.isValid())
+ m_surfaceWaitCondition.wakeOne();
+ unlockSurface();
+ if (m_androidSurfaceObject.isValid())
+ sendExpose();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h
index 6fccc2e7fe..a676ef1dd3 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformwindow.h
@@ -7,11 +7,19 @@
#include <qobject.h>
#include <qrect.h>
#include <qpa/qplatformwindow.h>
+#include <QtCore/qjnienvironment.h>
+#include <QtCore/qjniobject.h>
+#include <QtCore/qjnitypes.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qwaitcondition.h>
+#include <jni.h>
QT_BEGIN_NAMESPACE
+Q_DECLARE_JNI_CLASS(Surface, "android/view/Surface")
+
class QAndroidPlatformScreen;
-class QAndroidPlatformBackingStore;
class QAndroidPlatformWindow: public QPlatformWindow
{
@@ -39,32 +47,33 @@ public:
void propagateSizeHints() override;
void requestActivateWindow() override;
void updateSystemUiVisibility();
- inline bool isRaster() const {
- if (isForeignWindow())
- return false;
-
- return window()->surfaceType() == QSurface::RasterSurface
- || window()->surfaceType() == QSurface::RasterGLSurface;
- }
+ inline bool isRaster() const { return m_isRaster; }
bool isExposed() const override;
virtual void applicationStateChanged(Qt::ApplicationState);
- void setBackingStore(QAndroidPlatformBackingStore *store) { m_backingStore = store; }
- QAndroidPlatformBackingStore *backingStore() const { return m_backingStore; }
-
- virtual void repaint(const QRegion &) { }
+ void onSurfaceChanged(QtJniTypes::Surface surface);
protected:
void setGeometry(const QRect &rect) override;
+ void lockSurface() { m_surfaceMutex.lock(); }
+ void unlockSurface() { m_surfaceMutex.unlock(); }
+ void createSurface();
+ void destroySurface();
+ void setSurfaceGeometry(const QRect &rect);
+ void sendExpose();
protected:
Qt::WindowFlags m_windowFlags;
Qt::WindowStates m_windowState;
+ bool m_isRaster;
WId m_windowId;
-
- QAndroidPlatformBackingStore *m_backingStore = nullptr;
+ // The Android Surface, accessed from multiple threads, guarded by m_surfaceMutex
+ QtJniTypes::Surface m_androidSurfaceObject;
+ QWaitCondition m_surfaceWaitCondition;
+ int m_nativeSurfaceId = -1;
+ QMutex m_surfaceMutex;
};
QT_END_NAMESPACE