| /* |
| ** Copyright 2013, The Android Open Source Project |
| ** |
| ** Licensed under the Apache License, Version 2.0 (the "License"); |
| ** you may not use this file except in compliance with the License. |
| ** You may obtain a copy of the License at |
| ** |
| ** http://www.apache.org/licenses/LICENSE-2.0 |
| ** |
| ** Unless required by applicable law or agreed to in writing, software |
| ** distributed under the License is distributed on an "AS IS" BASIS, |
| ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| ** See the License for the specific language governing permissions and |
| ** limitations under the License. |
| */ |
| |
| #define LOG_TAG "GLConsumer" |
| |
| #define EGL_EGLEXT_PROTOTYPES |
| |
| #include <EGL/egl.h> |
| #include <EGL/eglext.h> |
| |
| #include <utils/Log.h> |
| #include <utils/Singleton.h> |
| #include <utils/String8.h> |
| |
| #include <private/gui/SyncFeatures.h> |
| |
| namespace android { |
| |
| ANDROID_SINGLETON_STATIC_INSTANCE(SyncFeatures); |
| |
| SyncFeatures::SyncFeatures() : Singleton<SyncFeatures>(), |
| mHasNativeFenceSync(false), |
| mHasFenceSync(false), |
| mHasWaitSync(false) { |
| EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| // eglQueryString can only be called after EGL has been initialized; |
| // otherwise the check below will abort. If RenderEngine is using SkiaVk, |
| // EGL will not have been initialized. There's no problem with initializing |
| // it again here (it is ref counted), and then terminating it later. |
| EGLBoolean initialized = eglInitialize(dpy, nullptr, nullptr); |
| LOG_ALWAYS_FATAL_IF(!initialized, "eglInitialize failed"); |
| const char* exts = eglQueryString(dpy, EGL_EXTENSIONS); |
| LOG_ALWAYS_FATAL_IF(exts == nullptr, "eglQueryString 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("]"); |
| // Terminate EGL to match the eglInitialize above |
| eglTerminate(dpy); |
| } |
| |
| bool SyncFeatures::useNativeFenceSync() const { |
| // EGL_ANDROID_native_fence_sync is not compatible with using the |
| // EGL_KHR_fence_sync extension for the same purpose. |
| return mHasNativeFenceSync; |
| } |
| bool SyncFeatures::useFenceSync() const { |
| return !mHasNativeFenceSync && mHasFenceSync; |
| } |
| bool SyncFeatures::useWaitSync() const { |
| return (useNativeFenceSync() || useFenceSync()) && mHasWaitSync; |
| } |
| |
| String8 SyncFeatures::toString() const { |
| return mString; |
| } |
| |
| } // namespace android |