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
This commit is contained in:
parent
8171aece3d
commit
ca08833d5e
@ -267,10 +267,6 @@ protected:
|
||||
// values.
|
||||
status_t checkAndUpdateEglStateLocked();
|
||||
|
||||
// If set, GLConsumer will use the EGL_ANDROID_native_fence_sync
|
||||
// extension to create Android native fences for GLES activity.
|
||||
static const bool sUseNativeFenceSync;
|
||||
|
||||
private:
|
||||
// createImage creates a new EGLImage from a GraphicBuffer.
|
||||
EGLImageKHR createImage(EGLDisplay dpy,
|
||||
|
45
include/private/gui/SyncFeatures.h
Normal file
45
include/private/gui/SyncFeatures.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_GUI_SYNC_FEATURES_H
|
||||
#define ANDROID_GUI_SYNC_FEATURES_H
|
||||
|
||||
#include <utils/Singleton.h>
|
||||
#include <utils/String8.h>
|
||||
|
||||
|
||||
namespace android {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class SyncFeatures : public Singleton<SyncFeatures> {
|
||||
friend class Singleton<SyncFeatures>;
|
||||
bool mHasNativeFenceSync;
|
||||
bool mHasFenceSync;
|
||||
bool mHasWaitSync;
|
||||
String8 mString;
|
||||
SyncFeatures();
|
||||
|
||||
public:
|
||||
bool useNativeFenceSync() const;
|
||||
bool useFenceSync() const;
|
||||
bool useWaitSync() const;
|
||||
String8 toString() const;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_GUI_SYNC_FEATURES_H
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
94
libs/gui/SyncFeatures.cpp
Normal file
94
libs/gui/SyncFeatures.cpp
Normal file
@ -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
|
@ -52,8 +52,6 @@ using namespace android;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define EGL_VERSION_HW_ANDROID 0x3143
|
||||
|
||||
namespace android {
|
||||
|
||||
struct extention_map_t {
|
||||
@ -1021,12 +1019,29 @@ const char* eglQueryString(EGLDisplay dpy, EGLint name)
|
||||
return dp->getExtensionString();
|
||||
case EGL_CLIENT_APIS:
|
||||
return dp->getClientApiString();
|
||||
case EGL_VERSION_HW_ANDROID:
|
||||
return dp->disp.queryString.version;
|
||||
}
|
||||
return setError(EGL_BAD_PARAMETER, (const char *)0);
|
||||
}
|
||||
|
||||
EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name)
|
||||
{
|
||||
clearError();
|
||||
|
||||
const egl_display_ptr dp = validate_display(dpy);
|
||||
if (!dp) return (const char *) NULL;
|
||||
|
||||
switch (name) {
|
||||
case EGL_VENDOR:
|
||||
return dp->disp.queryString.vendor;
|
||||
case EGL_VERSION:
|
||||
return dp->disp.queryString.version;
|
||||
case EGL_EXTENSIONS:
|
||||
return dp->disp.queryString.extensions;
|
||||
case EGL_CLIENT_APIS:
|
||||
return dp->disp.queryString.clientApi;
|
||||
}
|
||||
return setError(EGL_BAD_PARAMETER, (const char *)0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// EGL 1.1
|
||||
|
@ -80,7 +80,7 @@ void GLExtensions::initWithGLStrings(
|
||||
mHaveDirectTexture = true;
|
||||
}
|
||||
#else
|
||||
#warning "EGL_ANDROID_image_native_buffer not supported"
|
||||
#error "EGL_ANDROID_image_native_buffer not supported"
|
||||
#endif
|
||||
|
||||
if (hasExtension("GL_ARB_texture_non_power_of_two")) {
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <private/android_filesystem_config.h>
|
||||
#include <private/gui/SyncFeatures.h>
|
||||
|
||||
#include "clz.h"
|
||||
#include "DdmConnection.h"
|
||||
@ -68,11 +69,10 @@
|
||||
#include "DisplayHardware/HWComposer.h"
|
||||
#include "DisplayHardware/VirtualDisplaySurface.h"
|
||||
|
||||
|
||||
#define EGL_VERSION_HW_ANDROID 0x3143
|
||||
|
||||
#define DISPLAY_COUNT 1
|
||||
|
||||
EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
|
||||
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@ -2280,6 +2280,10 @@ void SurfaceFlinger::dumpAllLocked(
|
||||
appendGuiConfigString(result);
|
||||
result.append("\n");
|
||||
|
||||
result.append("Sync configuration: ");
|
||||
result.append(SyncFeatures::getInstance().toString());
|
||||
result.append("\n");
|
||||
|
||||
/*
|
||||
* Dump the visible layer list
|
||||
*/
|
||||
@ -2313,17 +2317,20 @@ void SurfaceFlinger::dumpAllLocked(
|
||||
HWComposer& hwc(getHwComposer());
|
||||
sp<const DisplayDevice> hw(getDefaultDisplayDevice());
|
||||
const GLExtensions& extensions(GLExtensions::getInstance());
|
||||
|
||||
snprintf(buffer, SIZE, "EGL implementation : %s\n",
|
||||
eglQueryStringImplementationANDROID(mEGLDisplay, EGL_VERSION));
|
||||
result.append(buffer);
|
||||
snprintf(buffer, SIZE, "%s\n",
|
||||
eglQueryStringImplementationANDROID(mEGLDisplay, EGL_EXTENSIONS));
|
||||
result.append(buffer);
|
||||
|
||||
snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
|
||||
extensions.getVendor(),
|
||||
extensions.getRenderer(),
|
||||
extensions.getVersion());
|
||||
result.append(buffer);
|
||||
|
||||
snprintf(buffer, SIZE, "EGL : %s\n",
|
||||
eglQueryString(mEGLDisplay, EGL_VERSION_HW_ANDROID));
|
||||
result.append(buffer);
|
||||
|
||||
snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
|
||||
snprintf(buffer, SIZE, "%s\n", extensions.getExtension());
|
||||
result.append(buffer);
|
||||
|
||||
hw->undefinedRegion.dump(result, "undefinedRegion");
|
||||
|
@ -19,10 +19,11 @@
|
||||
|
||||
#include "SurfaceFlingerConsumer.h"
|
||||
|
||||
#include <private/gui/SyncFeatures.h>
|
||||
|
||||
#include <utils/Trace.h>
|
||||
#include <utils/Errors.h>
|
||||
|
||||
|
||||
namespace android {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -78,7 +79,7 @@ status_t SurfaceFlingerConsumer::updateTexImage(BufferRejecter* rejecter)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!sUseNativeFenceSync) {
|
||||
if (!SyncFeatures::getInstance().useNativeFenceSync()) {
|
||||
// Bind the new buffer to the GL texture.
|
||||
//
|
||||
// Older devices require the "implicit" synchronization provided
|
||||
|
Loading…
Reference in New Issue
Block a user