Avoid unnecessary texture bind
In SurfaceFlingerConsumer, check to see if native fence sync is
enabled. If so, defer the texture binding step to Layer::onDraw.
Change-Id: I7d4034a31c0143207eea2509dfa13ef3820f9b8c
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 037f5fb..ee3079e 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -39,6 +39,8 @@
#include <utils/String8.h>
#include <utils/Trace.h>
+namespace android {
+
// This compile option makes SurfaceTexture 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
@@ -48,9 +50,9 @@
#ifdef USE_FENCE_SYNC
#error "USE_NATIVE_FENCE_SYNC and USE_FENCE_SYNC are incompatible"
#endif
-static const bool useNativeFenceSync = true;
+const bool SurfaceTexture::sUseNativeFenceSync = true;
#else
-static const bool useNativeFenceSync = false;
+const bool SurfaceTexture::sUseNativeFenceSync = false;
#endif
// This compile option makes SurfaceTexture use the EGL_ANDROID_sync_wait
@@ -70,8 +72,6 @@
#define ST_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
#define ST_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
-namespace android {
-
// Transform matrices
static float mtxIdentity[16] = {
1, 0, 0, 0,
@@ -196,14 +196,8 @@
return err;
}
- // Bind the new buffer to the GL texture.
- err = bindTextureImage();
- if (err != NO_ERROR) {
- return err;
- }
-
- // Wait for the new buffer to be ready.
- return doGLFenceWaitLocked();
+ // Bind the new buffer to the GL texture, and wait until it's ready.
+ return bindTextureImageLocked();
}
status_t SurfaceTexture::acquireBufferLocked(BufferQueue::BufferItem *item) {
@@ -313,7 +307,7 @@
return err;
}
-status_t SurfaceTexture::bindTextureImage() {
+status_t SurfaceTexture::bindTextureImageLocked() {
if (mEglDisplay == EGL_NO_DISPLAY) {
ALOGE("bindTextureImage: invalid display");
return INVALID_OPERATION;
@@ -330,7 +324,10 @@
ST_LOGE("bindTextureImage: no currently-bound texture");
return NO_INIT;
}
- return bindUnslottedBufferLocked(mEglDisplay);
+ status_t err = bindUnslottedBufferLocked(mEglDisplay);
+ if (err != NO_ERROR) {
+ return err;
+ }
} else {
EGLImageKHR image = mEglSlots[mCurrentTexture].mEglImage;
@@ -341,8 +338,11 @@
": %#04x", image, error);
return UNKNOWN_ERROR;
}
- return NO_ERROR;
}
+
+ // Wait for the new buffer to be ready.
+ return doGLFenceWaitLocked();
+
}
status_t SurfaceTexture::checkAndUpdateEglStateLocked() {
@@ -521,7 +521,7 @@
ST_LOGV("syncForReleaseLocked");
if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
- if (useNativeFenceSync) {
+ if (sUseNativeFenceSync) {
EGLSyncKHR sync = eglCreateSyncKHR(dpy,
EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
if (sync == EGL_NO_SYNC_KHR) {