summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
diff options
context:
space:
mode:
authorTinja Paavoseppä <tinja.paavoseppa@qt.io>2024-04-09 16:03:15 +0300
committerPetri Virkkunen <petri.virkkunen@qt.io>2024-10-02 09:12:43 +0300
commite5513a9447771dc722ca27e553fd3e966ee7d44a (patch)
tree9c30083d6ebce74ee3687512de3913c151cc9639 /src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
parentcc0629a4877ff7609094a29e4a18252c0de057b0 (diff)
Android: Guard EGLSurface with a mutex
QAndroidPlatformOpenGlWindow creates an EGLSurface to wrap the native Android Surface. Once this EGLSurface is returned to QPlatformEglContext, nothing is guarding it anymore, and Android can freely destroy the underlying Surface. This leads to failed EGL operations when leaving from the app or returning to it, as that is when Android destroys/recreates the Surface. Use the mutex from QAndroidPlatformWindow to guard setting the Surface, and during the makeCurrent() and swapBuffers() calls. Locking until returning from these functions ensures Android cannot destroy the Surface in the middle of them. Task-number: QTBUG-118231 Pick-to: 6.8 Change-Id: I614575c42f7f0c2c17022994d3bc542726ebf039 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Diffstat (limited to 'src/plugins/platforms/android/qandroidplatformopenglcontext.cpp')
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.cpp30
1 files changed, 26 insertions, 4 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) {