From 804ee87356cfcc5d041e6205b62b70bc5f2bc279 Mon Sep 17 00:00:00 2001 From: Anish Goyal Date: Mon, 3 Nov 2025 14:28:15 -0500 Subject: [PATCH] Check for null fences to avoid segfault in tests (#9389) * Check for null fences to avoid segfault in tests In some test environments, creating a sync or fence backed by an Android fence returns null. In order to avoid NPEs, cover this scenario with a null check. * Address PR - add log statement Log that native fences are not supported when unable to create a native sync fence. --- .../opengl/platforms/PlatformEGLAndroid.cpp | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/filament/backend/src/opengl/platforms/PlatformEGLAndroid.cpp b/filament/backend/src/opengl/platforms/PlatformEGLAndroid.cpp index c11422fb11..aceefe685c 100644 --- a/filament/backend/src/opengl/platforms/PlatformEGLAndroid.cpp +++ b/filament/backend/src/opengl/platforms/PlatformEGLAndroid.cpp @@ -545,7 +545,15 @@ void PlatformEGLAndroid::destroyStream(Stream* stream) noexcept { } Platform::Sync* PlatformEGLAndroid::createSync() noexcept { - auto const sync = eglCreateSyncKHR(getEglDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr); + EGLSyncKHR sync = EGL_NO_SYNC_KHR; + if (UTILS_LIKELY(ext.egl.ANDROID_native_fence_sync)) { + sync = eglCreateSyncKHR(getEglDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr); + if (sync == EGL_NO_SYNC_KHR) { + LOG(ERROR) << "Failed to create sync: " << eglGetError(); + } + } else { + LOG(WARNING) << "Native fences not supported on this device."; + } return new(std::nothrow) SyncEGLAndroid{ .sync = sync }; } @@ -553,10 +561,16 @@ bool PlatformEGLAndroid::convertSyncToFd(Sync* sync, int* fd) noexcept { assert_invariant(sync && fd); if (UTILS_UNLIKELY(!ext.egl.ANDROID_native_fence_sync)) { + LOG(WARNING) << "Native fences not supported, cannot convert to fd."; return false; } SyncEGLAndroid const& eglSync = static_cast(*sync); + if (eglSync.sync == EGL_NO_SYNC_KHR) { + LOG(ERROR) << "Invalid fence, cannot convert to fd."; + return false; + } + *fd = eglDupNativeFenceFDANDROID(getEglDisplay(), eglSync.sync); // In the case where there was no native FD, -1 is returned. Return false // to indicate there was an error in this case. @@ -569,8 +583,12 @@ bool PlatformEGLAndroid::convertSyncToFd(Sync* sync, int* fd) noexcept { void PlatformEGLAndroid::destroySync(Sync* sync) noexcept { assert_invariant(sync); - SyncEGLAndroid const& eglSync = static_cast(*sync); - eglDestroySyncKHR(getEglDisplay(), eglSync.sync); + if (UTILS_LIKELY(ext.egl.ANDROID_native_fence_sync)) { + SyncEGLAndroid const& eglSync = static_cast(*sync); + if (eglSync.sync != EGL_NO_SYNC_KHR) { + eglDestroySyncKHR(getEglDisplay(), eglSync.sync); + } + } delete sync; }