diff options
author | Mathias Agopian <mathias@google.com> | 2013-03-28 17:44:13 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2013-03-29 15:33:47 -0700 |
commit | ca08833d5ea99130797e10ad68a651b50e99da74 (patch) | |
tree | bcb05693b2bc34a0c7467d95a85b19df9af5dc1e /libs/gui | |
parent | 8171aece3d89a2107eda02c0e9daf79518b40174 (diff) | |
download | frameworks_native-ca08833d5ea99130797e10ad68a651b50e99da74.zip frameworks_native-ca08833d5ea99130797e10ad68a651b50e99da74.tar.gz frameworks_native-ca08833d5ea99130797e10ad68a651b50e99da74.tar.bz2 |
don't use compile-time configuration of libgui as much as possible
We now detect at runtime which sync features to use, which
allows us to remove a lot of the compile-time configuration
options. There is still one option though, to disable
KHR_fence_sync on some devices (which are more efficient
without it).
- added a backdoor to get the vendor's EGL strings
the new logic is:
- use always ANDROID_native_fence_sync if available
- fallback to KHR_fence_sync if available and not disabled
by the compile-time option
- use KHR_wait_sync if available and either of the above is
enabled
Change-Id: I9c4b49d9ff1151faf902cc93bd53ea5f205aaabf
Diffstat (limited to 'libs/gui')
-rw-r--r-- | libs/gui/Android.mk | 21 | ||||
-rw-r--r-- | libs/gui/ConsumerBase.cpp | 1 | ||||
-rw-r--r-- | libs/gui/GLConsumer.cpp | 49 | ||||
-rw-r--r-- | libs/gui/GuiConfig.cpp | 10 | ||||
-rw-r--r-- | libs/gui/SyncFeatures.cpp | 94 |
5 files changed, 106 insertions, 69 deletions
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk index 5c7bb4c..8fcfa7d 100644 --- a/libs/gui/Android.mk +++ b/libs/gui/Android.mk @@ -26,6 +26,7 @@ LOCAL_SRC_FILES:= \ Surface.cpp \ SurfaceControl.cpp \ SurfaceComposerClient.cpp \ + SyncFeatures.cpp \ LOCAL_SHARED_LIBRARIES := \ libbinder \ @@ -39,23 +40,11 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_MODULE:= libgui -ifeq ($(TARGET_BOARD_PLATFORM), omap4) - LOCAL_CFLAGS += -DUSE_FENCE_SYNC +ifeq ($(TARGET_BOARD_PLATFORM), tegra) + LOCAL_CFLAGS += -DDONT_USE_FENCE_SYNC endif -ifeq ($(TARGET_BOARD_PLATFORM), s5pc110) - LOCAL_CFLAGS += -DUSE_FENCE_SYNC -endif -ifeq ($(TARGET_BOARD_PLATFORM), exynos5) - LOCAL_CFLAGS += -DUSE_NATIVE_FENCE_SYNC - LOCAL_CFLAGS += -DUSE_WAIT_SYNC -endif -ifneq ($(filter generic%,$(TARGET_DEVICE)),) - # Emulator build - LOCAL_CFLAGS += -DUSE_FENCE_SYNC -endif - -ifeq ($(TARGET_BOARD_PLATFORM), msm8960) - LOCAL_CFLAGS += -DUSE_NATIVE_FENCE_SYNC +ifeq ($(TARGET_BOARD_PLATFORM), tegra3) + LOCAL_CFLAGS += -DDONT_USE_FENCE_SYNC endif include $(BUILD_SHARED_LIBRARY) diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp index fb6ba7d..8694d21 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -18,7 +18,6 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS //#define LOG_NDEBUG 0 -#define GL_GLEXT_PROTOTYPES #define EGL_EGLEXT_PROTOTYPES #include <EGL/egl.h> diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp index 1ce75ea..f8f1241 100644 --- a/libs/gui/GLConsumer.cpp +++ b/libs/gui/GLConsumer.cpp @@ -28,12 +28,13 @@ #include <hardware/hardware.h> +#include <gui/GLConsumer.h> #include <gui/IGraphicBufferAlloc.h> #include <gui/ISurfaceComposer.h> #include <gui/SurfaceComposerClient.h> -#include <gui/GLConsumer.h> #include <private/gui/ComposerService.h> +#include <private/gui/SyncFeatures.h> #include <utils/Log.h> #include <utils/String8.h> @@ -41,30 +42,6 @@ namespace android { -// This compile option 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. It is not -// compatible with using the EGL_KHR_fence_sync extension for the same -// purpose. -#ifdef USE_NATIVE_FENCE_SYNC -#ifdef USE_FENCE_SYNC -#error "USE_NATIVE_FENCE_SYNC and USE_FENCE_SYNC are incompatible" -#endif -const bool GLConsumer::sUseNativeFenceSync = true; -#else -const bool GLConsumer::sUseNativeFenceSync = false; -#endif - -// This compile option makes GLConsumer use the EGL_KHR_wait_sync -// extension to insert server-side waits into the GLES command stream. This -// feature requires the EGL_ANDROID_native_fence_sync and -// EGL_KHR_wait_sync extensions. -#ifdef USE_WAIT_SYNC -static const bool useWaitSync = true; -#else -static const bool useWaitSync = false; -#endif - // Macros for including the GLConsumer name in log messages #define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__) #define ST_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__) @@ -97,18 +74,6 @@ static float mtxRot90[16] = { 0, 0, 1, 0, 1, 0, 0, 1, }; -static float mtxRot180[16] = { - -1, 0, 0, 0, - 0, -1, 0, 0, - 0, 0, 1, 0, - 1, 1, 0, 1, -}; -static float mtxRot270[16] = { - 0, -1, 0, 0, - 1, 0, 0, 0, - 0, 0, 1, 0, - 0, 1, 0, 1, -}; static void mtxMul(float out[16], const float a[16], const float b[16]); @@ -121,11 +86,7 @@ GLConsumer::GLConsumer(GLuint tex, bool allowSynchronousMode, mCurrentTimestamp(0), mFilteringEnabled(true), mTexName(tex), -#ifdef USE_FENCE_SYNC mUseFenceSync(useFenceSync), -#else - mUseFenceSync(false), -#endif mTexTarget(texTarget), mEglDisplay(EGL_NO_DISPLAY), mEglContext(EGL_NO_CONTEXT), @@ -522,7 +483,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { ST_LOGV("syncForReleaseLocked"); if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { - if (sUseNativeFenceSync) { + if (SyncFeatures::getInstance().useNativeFenceSync()) { EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); if (sync == EGL_NO_SYNC_KHR) { @@ -545,7 +506,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { "%s (%d)", strerror(-err), err); return err; } - } else if (mUseFenceSync) { + } else if (mUseFenceSync && SyncFeatures::getInstance().useFenceSync()) { EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence; if (fence != EGL_NO_SYNC_KHR) { // There is already a fence for the current slot. We need to @@ -825,7 +786,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const { } if (mCurrentFence->isValid()) { - if (useWaitSync) { + if (SyncFeatures::getInstance().useWaitSync()) { // Create an EGLSyncKHR from the current fence. int fenceFd = mCurrentFence->dup(); if (fenceFd == -1) { diff --git a/libs/gui/GuiConfig.cpp b/libs/gui/GuiConfig.cpp index bafd21a..bc0c83c 100644 --- a/libs/gui/GuiConfig.cpp +++ b/libs/gui/GuiConfig.cpp @@ -22,14 +22,8 @@ void appendGuiConfigString(String8& configStr) { static const char* config = " [libgui" -#ifdef USE_FENCE_SYNC - " USE_FENCE_SYNC" -#endif -#ifdef USE_NATIVE_FENCE_SYNC - " USE_NATIVE_FENCE_SYNC" -#endif -#ifdef USE_WAIT_SYNC - " USE_WAIT_SYNC" +#ifdef DONT_USE_FENCE_SYNC + " DONT_USE_FENCE_SYNC" #endif "]"; configStr.append(config); diff --git a/libs/gui/SyncFeatures.cpp b/libs/gui/SyncFeatures.cpp new file mode 100644 index 0000000..e5804a7 --- /dev/null +++ b/libs/gui/SyncFeatures.cpp @@ -0,0 +1,94 @@ +/* + ** 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 GL_GLEXT_PROTOTYPES +#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> + +EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name); + +namespace android { + +ANDROID_SINGLETON_STATIC_INSTANCE(SyncFeatures); + +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("]"); +} + +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 { +#ifdef DONT_USE_FENCE_SYNC + // on some devices it's better to not use EGL_KHR_fence_sync + // even if they have it + return false; +#endif + // currently we shall only attempt to use EGL_KHR_fence_sync if + // USE_FENCE_SYNC is set in our makefile + return !mHasNativeFenceSync && mHasFenceSync; +} +bool SyncFeatures::useWaitSync() const { + return (useNativeFenceSync() || useFenceSync()) && mHasWaitSync; +} + +String8 SyncFeatures::toString() const { + return mString; +} + +} // namespace android |