1 /* 2 ** Copyright 2013, The Android Open Source Project 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 17 #define LOG_TAG "GLConsumer" 18 19 #define GL_GLEXT_PROTOTYPES 20 #define EGL_EGLEXT_PROTOTYPES 21 22 #include <EGL/egl.h> 23 #include <EGL/eglext.h> 24 25 #include <utils/Log.h> 26 #include <utils/Singleton.h> 27 #include <utils/String8.h> 28 29 #include <private/gui/SyncFeatures.h> 30 31 EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name); 32 33 namespace android { 34 35 ANDROID_SINGLETON_STATIC_INSTANCE(SyncFeatures); 36 37 SyncFeatures::SyncFeatures() : Singleton<SyncFeatures>(), 38 mHasNativeFenceSync(false), 39 mHasFenceSync(false), 40 mHasWaitSync(false) { 41 EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 42 // This can only be called after EGL has been initialized; otherwise the 43 // check below will abort. 44 const char* exts = eglQueryStringImplementationANDROID(dpy, EGL_EXTENSIONS); 45 LOG_ALWAYS_FATAL_IF(exts == NULL, "eglQueryStringImplementationANDROID failed"); 46 if (strstr(exts, "EGL_ANDROID_native_fence_sync")) { 47 // This makes GLConsumer use the EGL_ANDROID_native_fence_sync 48 // extension to create Android native fences to signal when all 49 // GLES reads for a given buffer have completed. 50 mHasNativeFenceSync = true; 51 } 52 if (strstr(exts, "EGL_KHR_fence_sync")) { 53 mHasFenceSync = true; 54 } 55 if (strstr(exts, "EGL_KHR_wait_sync")) { 56 mHasWaitSync = true; 57 } 58 mString.append("[using:"); 59 if (useNativeFenceSync()) { 60 mString.append(" EGL_ANDROID_native_fence_sync"); 61 } 62 if (useFenceSync()) { 63 mString.append(" EGL_KHR_fence_sync"); 64 } 65 if (useWaitSync()) { 66 mString.append(" EGL_KHR_wait_sync"); 67 } 68 mString.append("]"); 69 } 70 71 bool SyncFeatures::useNativeFenceSync() const { 72 // EGL_ANDROID_native_fence_sync is not compatible with using the 73 // EGL_KHR_fence_sync extension for the same purpose. 74 return mHasNativeFenceSync; 75 } 76 bool SyncFeatures::useFenceSync() const { 77 #ifdef DONT_USE_FENCE_SYNC 78 // on some devices it's better to not use EGL_KHR_fence_sync 79 // even if they have it 80 return false; 81 #endif 82 // currently we shall only attempt to use EGL_KHR_fence_sync if 83 // USE_FENCE_SYNC is set in our makefile 84 return !mHasNativeFenceSync && mHasFenceSync; 85 } 86 bool SyncFeatures::useWaitSync() const { 87 return (useNativeFenceSync() || useFenceSync()) && mHasWaitSync; 88 } 89 90 String8 SyncFeatures::toString() const { 91 return mString; 92 } 93 94 } // namespace android 95