summaryrefslogtreecommitdiff
path: root/libs/hwui/renderthread/EglManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/renderthread/EglManager.cpp')
-rw-r--r--libs/hwui/renderthread/EglManager.cpp62
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