SyncFeatures::SyncFeatures() : Singleton<SyncFeatures>(), mHasNativeFenceSync(false), mHasFenceSync(false), mHasWaitSync(false) { EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); // This can only be called after EGL has been initialized; otherwise the // check below will abort. const char* exts = eglQueryStringImplementationANDROID(dpy, EGL_EXTENSIONS); LOG_ALWAYS_FATAL_IF(exts == NULL, "eglQueryStringImplementationANDROID failed"); if (strstr(exts, "EGL_ANDROID_native_fence_sync")) { // This makes GLConsumer use the EGL_ANDROID_native_fence_sync // extension to create Android native fences to signal when all // GLES reads for a given buffer have completed. mHasNativeFenceSync = true; } if (strstr(exts, "EGL_KHR_fence_sync")) { mHasFenceSync = true; } if (strstr(exts, "EGL_KHR_wait_sync")) { mHasWaitSync = true; } mString.append("[using:"); if (useNativeFenceSync()) { mString.append(" EGL_ANDROID_native_fence_sync"); } if (useFenceSync()) { mString.append(" EGL_KHR_fence_sync"); } if (useWaitSync()) { mString.append(" EGL_KHR_wait_sync"); } mString.append("]"); }
static bool hasEglAndroidImageCropImpl() { EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); const char* exts = eglQueryStringImplementationANDROID(dpy, EGL_EXTENSIONS); size_t cropExtLen = strlen(CROP_EXT_STR); size_t extsLen = strlen(exts); bool equal = !strcmp(CROP_EXT_STR, exts); bool atStart = !strncmp(CROP_EXT_STR " ", exts, cropExtLen+1); bool atEnd = (cropExtLen+1) < extsLen && !strcmp(" " CROP_EXT_STR, exts + extsLen - (cropExtLen+1)); bool inMiddle = strstr(exts, " " CROP_EXT_STR " "); return equal || atStart || atEnd || inMiddle; }