diff options
| author | Tinja Paavoseppä <tinja.paavoseppa@qt.io> | 2024-04-09 16:03:15 +0300 |
|---|---|---|
| committer | Petri Virkkunen <petri.virkkunen@qt.io> | 2024-10-02 09:12:43 +0300 |
| commit | e5513a9447771dc722ca27e553fd3e966ee7d44a (patch) | |
| tree | 9c30083d6ebce74ee3687512de3913c151cc9639 /src/plugins/platforms/android/qandroidplatformopenglwindow.cpp | |
| parent | cc0629a4877ff7609094a29e4a18252c0de057b0 (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/qandroidplatformopenglwindow.cpp')
| -rw-r--r-- | src/plugins/platforms/android/qandroidplatformopenglwindow.cpp | 19 |
1 files changed, 9 insertions, 10 deletions
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! } |
