Bug 1903810 - Leak EGLDisplays on all Samsung Xclipse GPUs. r=gfx-reviewers,nical

In bug 1868825 we encountered crashes on a specific device when
calling eglTerminate. As a workaround, we avoided calling eglTerminate
and instead deliberately leaked the EGLDisplay. As we had only
encountered this crash on a specific device, we limited the workaround
to just that device.

We are now seeing the same crash on a range of devices, all with
Samsung Xclipse GPUs. This patch therefore makes us leak the
EGLDisplays on all devices with an Xclipse GPU.

As the GPU model is not available in EglDisplay code, we instead set a
flag on the EglDisplay object when the GLContext is initialized. Prior
to terminating the display we check whether this flag has been set.
Terminating a display which has not had a context created does not
reproduce the crash, so this is sufficient.

Differential Revision: https://phabricator.services.mozilla.com/D214539
This commit is contained in:
Jamie Nicol 2024-06-21 20:24:47 +00:00
parent 72cca751d7
commit 3dcab39a55
2 changed files with 17 additions and 17 deletions

View File

@ -30,6 +30,7 @@
# ifdef MOZ_WIDGET_ANDROID
# include <android/native_window.h>
# include <android/native_window_jni.h>
# include "mozilla/jni/Utils.h"
# include "mozilla/widget/AndroidCompositorWidget.h"
# endif
@ -418,6 +419,15 @@ bool GLContextEGL::Init() {
mEgl->IsExtensionSupported(EGLExtension::KHR_gl_texture_2D_image) &&
IsExtensionSupported(OES_EGL_image);
#if MOZ_WIDGET_ANDROID
// We see crashes in eglTerminate on devices with Xclipse GPUs running
// Android 14. Choose to leak the EGLDisplays in order to avoid the crashes.
// See bug 1868825 and bug 1903810.
if (Renderer() == GLRenderer::SamsungXclipse && jni::GetAPIVersion() >= 34) {
mEgl->SetShouldLeakEGLDisplay();
}
#endif
return true;
}

View File

@ -695,21 +695,6 @@ class GLLibraryEGL final {
} mSymbols = {};
};
static bool ShouldLeakEglDisplay() {
// We are seeing crashes in eglTerminate on the Samsung S22 family of devices
// running Android 14, so we leak the EGLDisplay rather than call
// eglTerminate.
#ifdef MOZ_WIDGET_ANDROID
if (jni::GetAPIVersion() >= 34) {
const auto board = java::sdk::Build::BOARD()->ToString();
if (board.EqualsASCII("s5e9925")) {
return true;
}
}
#endif
return false;
}
class EglDisplay final {
public:
const RefPtr<GLLibraryEGL> mLib;
@ -719,6 +704,8 @@ class EglDisplay final {
private:
std::bitset<UnderlyingValue(EGLExtension::Max)> mAvailableExtensions;
bool mShouldLeakEGLDisplay = false;
struct PrivateUseOnly final {};
public:
@ -743,6 +730,10 @@ class EglDisplay final {
void DumpEGLConfig(EGLConfig) const;
void DumpEGLConfigs() const;
// When called, ensure we deliberately leak the EGLDisplay rather than call
// eglTerminate. Used as a workaround on buggy drivers.
void SetShouldLeakEGLDisplay() { mShouldLeakEGLDisplay = true; }
void Shutdown();
// -
@ -760,8 +751,7 @@ class EglDisplay final {
// -
EGLBoolean fTerminate() {
static const bool shouldLeak = ShouldLeakEglDisplay();
if (shouldLeak) {
if (mShouldLeakEGLDisplay) {
return LOCAL_EGL_TRUE;
}
return mLib->fTerminate(mDisplay);