Repository: google/filament
File: filament/backend/src/opengl/platforms/PlatformEGLAndroid.cpp (C++)

Code before:
void PlatformEGLAndroid::destroyStream(Stream* stream) noexcept {
    mExternalStreamManager.release(stream);
}

Platform::Sync* PlatformEGLAndroid::createSync() noexcept {
    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();
        }
    }
    return new(std::nothrow) SyncEGLAndroid{ .sync = sync };
}

bool PlatformEGLAndroid::convertSyncToFd(Sync* sync, int* fd) noexcept {
    assert_invariant(sync && fd);

    if (UTILS_UNLIKELY(!ext.egl.ANDROID_native_fence_sync)) {
        return false;
    }

    SyncEGLAndroid const& eglSync = static_cast<SyncEGLAndroid&>(*sync);
    if (eglSync.sync == EGL_NO_SYNC_KHR) {
        LOG(ERROR) << "Cannot convert sync to fd, because the underlying fence "
                      "does not exist - does this display support fences?";
        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.
    if (*fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
        LOG(ERROR) << "Failed to convert sync to fd: " << eglGetError();
        return false;
    }
    return true;
}

void PlatformEGLAndroid::destroySync(Sync* sync) noexcept {
    assert_invariant(sync);
    if (UTILS_LIKELY(ext.egl.ANDROID_native_fence_sync)) {
        SyncEGLAndroid const& eglSync = static_cast<SyncEGLAndroid&>(*sync);
        if (eglSync.sync != EGL_NO_SYNC_KHR) {
            eglDestroySyncKHR(getEglDisplay(), eglSync.sync);
        }
    }
    delete sync;
}

void PlatformEGLAndroid::attach(Stream* stream, intptr_t const tname) noexcept {

Review comment (bug):
I would shorten this message. If `ANDROID_native_fence_sync` is supported, this should not fail here.
so I would do something like:
```
if (sync == NO_SYNC) {
 if (ANDROID_native_fence_sync)
   LOG(ERROR) << "invalid fence"
 else
   LOG(WARNING) << "fences not supported"
}
```

Code after:
void PlatformEGLAndroid::destroyStream(Stream* stream) noexcept {
    mExternalStreamManager.release(stream);
}

Platform::Sync* PlatformEGLAndroid::createSync() noexcept {
    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 };
}

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<SyncEGLAndroid&>(*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.
    if (*fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
        LOG(ERROR) << "Failed to convert sync to fd: " << eglGetError();
        return false;
    }
    return true;
}

void PlatformEGLAndroid::destroySync(Sync* sync) noexcept {
    assert_invariant(sync);
    if (UTILS_LIKELY(ext.egl.ANDROID_native_fence_sync)) {
        SyncEGLAndroid const& eglSync = static_cast<SyncEGLAndroid&>(*sync);
        if (eglSync.sync != EGL_NO_SYNC_KHR) {
            eglDestroySyncKHR(getEglDisplay(), eglSync.sync);
        }
    }
    delete sync;
}