diff options
Diffstat (limited to 'libs/hwui/renderthread/EglManager.cpp')
-rw-r--r-- | libs/hwui/renderthread/EglManager.cpp | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 159cf497384a..5e0471c08d67 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -16,24 +16,21 @@ #include "EglManager.h" +#include <EGL/eglext.h> +#include <GLES/gl.h> #include <cutils/properties.h> #include <log/log.h> -#include <private/gui/SyncFeatures.h> +#include <sync/sync.h> #include <utils/Trace.h> -#include "utils/Color.h" -#include "utils/StringUtils.h" - -#include "Frame.h" -#include "Properties.h" - -#include <EGL/eglext.h> -#include <GLES/gl.h> -#include <gui/Surface.h> -#include <system/window.h> #include <string> #include <vector> +#include "Frame.h" +#include "Properties.h" +#include "utils/Color.h" +#include "utils/StringUtils.h" + #define GLES_VERSION 2 // Android-specific addition that is used to show when frames began in systrace @@ -81,6 +78,9 @@ static struct { bool displayP3 = false; bool contextPriority = false; bool surfacelessContext = false; + bool nativeFenceSync = false; + bool fenceSync = false; + bool waitSync = false; } EglExtensions; EglManager::EglManager() @@ -228,6 +228,9 @@ void EglManager::initExtensions() { EglExtensions.displayP3 = extensions.has("EGL_EXT_gl_colorspace_display_p3_passthrough"); EglExtensions.contextPriority = extensions.has("EGL_IMG_context_priority"); EglExtensions.surfacelessContext = extensions.has("EGL_KHR_surfaceless_context"); + EglExtensions.nativeFenceSync = extensions.has("EGL_ANDROID_native_fence_sync"); + EglExtensions.fenceSync = extensions.has("EGL_KHR_fence_sync"); + EglExtensions.waitSync = extensions.has("EGL_KHR_wait_sync"); } bool EglManager::hasEglContext() { @@ -289,6 +292,10 @@ void EglManager::createPBufferSurface() { if (mPBufferSurface == EGL_NO_SURFACE && !EglExtensions.surfacelessContext) { EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE}; mPBufferSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs); + LOG_ALWAYS_FATAL_IF(mPBufferSurface == EGL_NO_SURFACE, + "Failed to create a pixel buffer display=%p, " + "mEglConfig=%p, error=%s", + mEglDisplay, mEglConfig, eglErrorString()); } } @@ -505,17 +512,30 @@ bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) { return preserved; } -status_t EglManager::fenceWait(sp<Fence>& fence) { +static status_t waitForeverOnFence(int fence, const char* logname) { + ATRACE_CALL(); + if (fence == -1) { + return NO_ERROR; + } + constexpr int warningTimeout = 3000; + int err = sync_wait(fence, warningTimeout); + if (err < 0 && errno == ETIME) { + ALOGE("%s: fence %d didn't signal in %d ms", logname, fence, warningTimeout); + err = sync_wait(fence, -1); + } + return err < 0 ? -errno : status_t(NO_ERROR); +} + +status_t EglManager::fenceWait(int fence) { if (!hasEglContext()) { ALOGE("EglManager::fenceWait: EGLDisplay not initialized"); return INVALID_OPERATION; } - if (SyncFeatures::getInstance().useWaitSync() && - SyncFeatures::getInstance().useNativeFenceSync()) { + if (EglExtensions.waitSync && EglExtensions.nativeFenceSync) { // Block GPU on the fence. // Create an EGLSyncKHR from the current fence. - int fenceFd = fence->dup(); + int fenceFd = ::dup(fence); if (fenceFd == -1) { ALOGE("EglManager::fenceWait: error dup'ing fence fd: %d", errno); return -errno; @@ -540,7 +560,7 @@ status_t EglManager::fenceWait(sp<Fence>& fence) { } } else { // Block CPU on the fence. - status_t err = fence->waitForever("EglManager::fenceWait"); + status_t err = waitForeverOnFence(fence, "EglManager::fenceWait"); if (err != NO_ERROR) { ALOGE("EglManager::fenceWait: error waiting for fence: %d", err); return err; @@ -549,14 +569,14 @@ status_t EglManager::fenceWait(sp<Fence>& fence) { return OK; } -status_t EglManager::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence, - sp<Fence>& nativeFence) { +status_t EglManager::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence, int* nativeFence) { + *nativeFence = -1; if (!hasEglContext()) { ALOGE("EglManager::createReleaseFence: EGLDisplay not initialized"); return INVALID_OPERATION; } - if (SyncFeatures::getInstance().useNativeFenceSync()) { + if (EglExtensions.nativeFenceSync) { EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr); if (sync == EGL_NO_SYNC_KHR) { ALOGE("EglManager::createReleaseFence: error creating EGL fence: %#x", eglGetError()); @@ -571,9 +591,9 @@ status_t EglManager::createReleaseFence(bool useFenceSync, EGLSyncKHR* eglFence, eglGetError()); return UNKNOWN_ERROR; } - nativeFence = new Fence(fenceFd); + *nativeFence = fenceFd; *eglFence = EGL_NO_SYNC_KHR; - } else if (useFenceSync && SyncFeatures::getInstance().useFenceSync()) { + } else if (useFenceSync && EglExtensions.fenceSync) { if (*eglFence != EGL_NO_SYNC_KHR) { // There is already a fence for the current slot. We need to // wait on that before replacing it with another fence to |