Merge "SurfaceFlinger: Move GraphicBufferAlloc to libgui"
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index a8b7d74..ae5d57a 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -243,13 +243,9 @@
status_t releaseAndUpdateLocked(const BufferQueue::BufferItem& item);
// Binds mTexName and the current buffer to mTexTarget. Uses
- // mCurrentTexture if it's set, mCurrentTextureBuf if not.
- status_t bindTextureImage();
-
- // doGLFenceWaitLocked inserts a wait command into the OpenGL ES command
- // stream to ensure that it is safe for future OpenGL ES commands to
- // access the current texture buffer.
- status_t doGLFenceWaitLocked() const;
+ // mCurrentTexture if it's set, mCurrentTextureBuf if not. If the
+ // bind succeeds, this calls doGLFenceWait.
+ status_t bindTextureImageLocked();
// Gets the current EGLDisplay and EGLContext values, and compares them
// to mEglDisplay and mEglContext. If the fields have been previously
@@ -257,6 +253,10 @@
// values.
status_t checkAndUpdateEglStateLocked();
+ // If set, SurfaceTexture 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,
@@ -275,6 +275,11 @@
// mCurrentTextureBuf must not be NULL.
void computeCurrentTransformMatrixLocked();
+ // doGLFenceWaitLocked inserts a wait command into the OpenGL ES command
+ // stream to ensure that it is safe for future OpenGL ES commands to
+ // access the current texture buffer.
+ status_t doGLFenceWaitLocked() const;
+
// syncForReleaseLocked performs the synchronization needed to release the
// current slot from an OpenGL ES context. If needed it will set the
// current slot's fence to guard against a producer accessing the buffer
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) {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 1c5403f..a1d46d9 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -327,17 +327,11 @@
return;
}
- // Bind the current buffer to the GL texture.
+ // Bind the current buffer to the GL texture, and wait for it to be
+ // ready for us to draw into.
status_t err = mSurfaceFlingerConsumer->bindTextureImage();
if (err != NO_ERROR) {
- ALOGW("Layer::onDraw: bindTextureImage failed");
- // keep going
- }
-
- // Wait for the buffer to be ready for us to draw into.
- err = mSurfaceFlingerConsumer->doGLFenceWait();
- if (err != OK) {
- ALOGE("onDraw: failed waiting for fence: %d", err);
+ ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
// Go ahead and draw the buffer anyway; no matter what we do the screen
// is probably going to have something visibly wrong.
}
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index dbe187b..a316896 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -77,12 +77,24 @@
return err;
}
- // Bind the new buffer to the GL texture.
- // TODO: skip this on devices that support explicit sync
- // (glEGLImageTargetTexture2DOES provides required implicit sync;
- // without this we get wedged on older devices, but newer devices
- // don't need it.)
- return bindTextureImage();
+ if (!sUseNativeFenceSync) {
+ // Bind the new buffer to the GL texture.
+ //
+ // Older devices require the "implicit" synchronization provided
+ // by glEGLImageTargetTexture2DOES, which this method calls. Newer
+ // devices will either call this in Layer::onDraw, or (if it's not
+ // a GL-composited layer) not at all.
+ err = bindTextureImageLocked();
+ }
+
+ return err;
+}
+
+status_t SurfaceFlingerConsumer::bindTextureImage()
+{
+ Mutex::Autolock lock(mMutex);
+
+ return bindTextureImageLocked();
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index d91f27e..308a288 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -49,8 +49,8 @@
// texture.
status_t updateTexImage(BufferRejecter* rejecter);
- // Pass-through to SurfaceTexture implementation.
- status_t bindTextureImage() { return SurfaceTexture::bindTextureImage(); }
+ // See SurfaceTexture::bindTextureImageLocked().
+ status_t bindTextureImage();
};
// ----------------------------------------------------------------------------