summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.cpp30
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglwindow.cpp19
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.cpp10
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.h11
4 files changed, 47 insertions, 23 deletions
diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
index faccf8b1173..fbfbb625dd2 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
@@ -22,19 +22,41 @@ QAndroidPlatformOpenGLContext::QAndroidPlatformOpenGLContext(const QSurfaceForma
void QAndroidPlatformOpenGLContext::swapBuffers(QPlatformSurface *surface)
{
- if (surface->surface()->surfaceClass() == QSurface::Window &&
- static_cast<QAndroidPlatformOpenGLWindow *>(surface)->checkNativeSurface(eglConfig())) {
- QEGLPlatformContext::makeCurrent(surface);
+ if (surface->surface()->surfaceClass() != QSurface::Window) {
+ QEGLPlatformContext::swapBuffers(surface);
+ return;
}
+ QAndroidPlatformOpenGLWindow *window = static_cast<QAndroidPlatformOpenGLWindow *>(surface);
+ // Since QEGLPlatformContext::makeCurrent() and QEGLPlatformContext::swapBuffers()
+ // will be using the eglSurface of the window, which wraps the Android Surface, we
+ // need to lock here to make sure we don't end up using a Surface already destroyed
+ // by Android
+ window->lockSurface();
+
+ if (window->checkNativeSurface(eglConfig())) {
+ // Call base class implementation directly since we are already locked
+ QEGLPlatformContext::makeCurrent(surface);
+ }
QEGLPlatformContext::swapBuffers(surface);
+
+ window->unlockSurface();
}
bool QAndroidPlatformOpenGLContext::makeCurrent(QPlatformSurface *surface)
{
- return QEGLPlatformContext::makeCurrent(surface);
+ if (surface->surface()->surfaceClass() != QSurface::Window)
+ return QEGLPlatformContext::makeCurrent(surface);
+
+ QAndroidPlatformOpenGLWindow *window = static_cast<QAndroidPlatformOpenGLWindow *>(surface);
+ window->lockSurface();
+ const bool ok = QEGLPlatformContext::makeCurrent(surface);
+ window->unlockSurface();
+ return ok;
}
+// Called from inside QEGLPlatformContext::swapBuffers() and QEGLPlatformContext::makeCurrent(),
+// already locked
EGLSurface QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
{
if (surface->surface()->surfaceClass() == QSurface::Window) {
diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
index c052b004131..77b486cce88 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
@@ -50,6 +50,8 @@ void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect)
}
}
+// Called by QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(),
+// surface is already locked when calling this
EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config)
{
if (QAndroidEventDispatcherStopper::stopped() ||
@@ -57,8 +59,6 @@ EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config)
return m_eglSurface;
}
- QMutexLocker lock(&m_surfaceMutex);
-
if (!m_surfaceCreated) {
AndroidDeadlockProtector protector;
if (!protector.acquire())
@@ -69,25 +69,24 @@ EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config)
}
if (m_eglSurface == EGL_NO_SURFACE) {
- m_surfaceMutex.unlock();
checkNativeSurface(config);
- m_surfaceMutex.lock();
}
return m_eglSurface;
}
+// Only called by eglSurface() and QAndroidPlatformOpenGLContext::swapBuffers(),
+// m_surfaceMutex already locked
bool QAndroidPlatformOpenGLWindow::checkNativeSurface(EGLConfig config)
{
- QMutexLocker lock(&m_surfaceMutex);
+ // Either no surface created, or the m_eglSurface already wraps the active Surface
+ // -> makeCurrent is NOT needed.
if (!m_surfaceCreated || !m_androidSurfaceObject.isValid())
- return false; // makeCurrent is NOT needed.
+ return false;
createEgl(config);
- // we've create another surface, the window should be repainted
- 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())));
+ // we've created another Surface, the window should be repainted
+ sendExpose();
return true; // makeCurrent is needed!
}
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp
index e86e617ca3e..7f43f175079 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp
@@ -304,14 +304,12 @@ void QAndroidPlatformWindow::onSurfaceChanged(QtJniTypes::Surface surface)
{
lockSurface();
m_androidSurfaceObject = surface;
- if (m_androidSurfaceObject.isValid()) // wait until we have a valid surface to draw into
- m_surfaceWaitCondition.wakeOne();
- unlockSurface();
-
if (m_androidSurfaceObject.isValid()) {
- // repaint the window, when we have a valid surface
- sendExpose();
+ // wait until we have a valid surface to draw into
+ m_surfaceWaitCondition.wakeOne();
}
+
+ unlockSurface();
}
void QAndroidPlatformWindow::sendExpose() const
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h
index 221b98fce55..e493875beef 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformwindow.h
@@ -67,10 +67,11 @@ public:
static bool registerNatives(QJniEnvironment &env);
void onSurfaceChanged(QtJniTypes::Surface surface);
-protected:
- void setGeometry(const QRect &rect) override;
void lockSurface() { m_surfaceMutex.lock(); }
void unlockSurface() { m_surfaceMutex.unlock(); }
+
+protected:
+ void setGeometry(const QRect &rect) override;
void createSurface();
void destroySurface();
void sendExpose() const;
@@ -85,7 +86,11 @@ protected:
QtJniTypes::QtWindow m_nativeQtWindow;
SurfaceContainer m_surfaceContainerType = SurfaceContainer::SurfaceView;
QtJniTypes::QtWindow m_nativeParentQtWindow;
- // The Android Surface, accessed from multiple threads, guarded by m_surfaceMutex
+ // The Android Surface, accessed from multiple threads, guarded by m_surfaceMutex.
+ // If the window is using QtSurface, which is a SurfaceView subclass, this Surface will be
+ // automatically created by Android when QtSurface is in a layout and visible. If the
+ // QtSurface is detached or hidden (app goes to background), Android will automatically
+ // destroy the Surface.
QtJniTypes::Surface m_androidSurfaceObject;
QWaitCondition m_surfaceWaitCondition;
bool m_surfaceCreated = false;