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 EGL_EGLEXT_PROTOTYPES
20 
21 #include <EGL/egl.h>
22 #include <EGL/eglext.h>
23 
24 #include <utils/Log.h>
25 #include <utils/Singleton.h>
26 #include <utils/String8.h>
27 
28 #include <private/gui/SyncFeatures.h>
29 
30 namespace android {
31 
32 ANDROID_SINGLETON_STATIC_INSTANCE(SyncFeatures);
33 
SyncFeatures()34 SyncFeatures::SyncFeatures() : Singleton<SyncFeatures>(),
35         mHasNativeFenceSync(false),
36         mHasFenceSync(false),
37         mHasWaitSync(false) {
38     EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
39     // eglQueryString can only be called after EGL has been initialized;
40     // otherwise the check below will abort.  If RenderEngine is using SkiaVk,
41     // EGL will not have been initialized.  There's no problem with initializing
42     // it again here (it is ref counted), and then terminating it later.
43     EGLBoolean initialized = eglInitialize(dpy, nullptr, nullptr);
44     LOG_ALWAYS_FATAL_IF(!initialized, "eglInitialize failed");
45     const char* exts = eglQueryString(dpy, EGL_EXTENSIONS);
46     LOG_ALWAYS_FATAL_IF(exts == nullptr, "eglQueryString failed");
47     if (strstr(exts, "EGL_ANDROID_native_fence_sync")) {
48         // This makes GLConsumer use the EGL_ANDROID_native_fence_sync
49         // extension to create Android native fences to signal when all
50         // GLES reads for a given buffer have completed.
51         mHasNativeFenceSync = true;
52     }
53     if (strstr(exts, "EGL_KHR_fence_sync")) {
54         mHasFenceSync = true;
55     }
56     if (strstr(exts, "EGL_KHR_wait_sync")) {
57         mHasWaitSync = true;
58     }
59     mString.append("[using:");
60     if (useNativeFenceSync()) {
61         mString.append(" EGL_ANDROID_native_fence_sync");
62     }
63     if (useFenceSync()) {
64         mString.append(" EGL_KHR_fence_sync");
65     }
66     if (useWaitSync()) {
67         mString.append(" EGL_KHR_wait_sync");
68     }
69     mString.append("]");
70     // Terminate EGL to match the eglInitialize above
71     eglTerminate(dpy);
72 }
73 
useNativeFenceSync() const74 bool SyncFeatures::useNativeFenceSync() const {
75     // EGL_ANDROID_native_fence_sync is not compatible with using the
76     // EGL_KHR_fence_sync extension for the same purpose.
77     return mHasNativeFenceSync;
78 }
useFenceSync() const79 bool SyncFeatures::useFenceSync() const {
80     return !mHasNativeFenceSync && mHasFenceSync;
81 }
useWaitSync() const82 bool SyncFeatures::useWaitSync() const {
83     return (useNativeFenceSync() || useFenceSync()) && mHasWaitSync;
84 }
85 
toString() const86 String8 SyncFeatures::toString() const {
87     return mString;
88 }
89 
90 } // namespace android
91