summaryrefslogtreecommitdiffstats
path: root/libs/gui/SurfaceTexture.cpp
diff options
context:
space:
mode:
authorJesse Hall <jessehall@google.com>2012-06-14 14:45:17 -0700
committerJesse Hall <jessehall@google.com>2012-06-21 22:21:12 -0700
commitef19414bd8b77a26f5751f3845be79025a8263fe (patch)
tree9624b3d718e065747bedff50cb969151d675a471 /libs/gui/SurfaceTexture.cpp
parenta74cbc06493ed941a8a54f2f1d0074f03fc9aafb (diff)
downloadframeworks_native-ef19414bd8b77a26f5751f3845be79025a8263fe.zip
frameworks_native-ef19414bd8b77a26f5751f3845be79025a8263fe.tar.gz
frameworks_native-ef19414bd8b77a26f5751f3845be79025a8263fe.tar.bz2
Transfer HWC release fences to BufferQueue
After a HWC set, each SurfaceFlinger Layer retrieves the release fence HWC returned and gives it to the layer's SurfaceTexture. The SurfaceTexture accumulates the fences into a merged fence until the next updateTexImage, then passes the merged fence to the BufferQueue in releaseBuffer. In a follow-on change, BufferQueue will return the fence along with the buffer slot in dequeueBuffer. For now, dequeueBuffer waits for the fence to signal before returning. The releaseFence default value for BufferQueue::releaseBuffer() is temporary to avoid transient build breaks with a multi-project checkin. It'll disappear in the next change. Change-Id: Iaa9a0d5775235585d9cbf453d3a64623d08013d9
Diffstat (limited to 'libs/gui/SurfaceTexture.cpp')
-rw-r--r--libs/gui/SurfaceTexture.cpp34
1 files changed, 30 insertions, 4 deletions
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 55be4bc..8ef885b 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -236,8 +236,10 @@ status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) {
// not accept this buffer. this is used by SurfaceFlinger to
// reject buffers which have the wrong size
if (rejecter && rejecter->reject(mEGLSlots[buf].mGraphicBuffer, item)) {
- mBufferQueue->releaseBuffer(buf, dpy, mEGLSlots[buf].mFence);
+ mBufferQueue->releaseBuffer(buf, dpy, mEGLSlots[buf].mFence,
+ mEGLSlots[buf].mReleaseFence);
mEGLSlots[buf].mFence = EGL_NO_SYNC_KHR;
+ mEGLSlots[buf].mReleaseFence.clear();
glBindTexture(mTexTarget, mTexName);
return NO_ERROR;
}
@@ -284,8 +286,10 @@ status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) {
if (err != NO_ERROR) {
// Release the buffer we just acquired. It's not safe to
// release the old buffer, so instead we just drop the new frame.
- mBufferQueue->releaseBuffer(buf, dpy, mEGLSlots[buf].mFence);
+ mBufferQueue->releaseBuffer(buf, dpy, mEGLSlots[buf].mFence,
+ mEGLSlots[buf].mReleaseFence);
mEGLSlots[buf].mFence = EGL_NO_SYNC_KHR;
+ mEGLSlots[buf].mReleaseFence.clear();
return err;
}
@@ -297,9 +301,10 @@ status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) {
// release old buffer
if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
status_t status = mBufferQueue->releaseBuffer(mCurrentTexture, dpy,
- mEGLSlots[mCurrentTexture].mFence);
-
+ mEGLSlots[mCurrentTexture].mFence,
+ mEGLSlots[mCurrentTexture].mReleaseFence);
mEGLSlots[mCurrentTexture].mFence = EGL_NO_SYNC_KHR;
+ mEGLSlots[mCurrentTexture].mReleaseFence.clear();
if (status == BufferQueue::STALE_BUFFER_SLOT) {
freeBufferLocked(mCurrentTexture);
} else if (status != NO_ERROR) {
@@ -328,6 +333,27 @@ status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) {
return err;
}
+void SurfaceTexture::setReleaseFence(int fenceFd) {
+ if (fenceFd == -1)
+ return;
+ sp<Fence> fence(new Fence(fenceFd));
+ if (!mEGLSlots[mCurrentTexture].mReleaseFence.get()) {
+ mEGLSlots[mCurrentTexture].mReleaseFence = fence;
+ } else {
+ sp<Fence> mergedFence = Fence::merge(
+ String8("SurfaceTexture merged release"),
+ mEGLSlots[mCurrentTexture].mReleaseFence, fence);
+ if (mergedFence.get()) {
+ ALOGE("failed to merge release fences");
+ // synchronization is broken, the best we can do is hope fences
+ // signal in order so the new fence will act like a union
+ mEGLSlots[mCurrentTexture].mReleaseFence = fence;
+ } else {
+ mEGLSlots[mCurrentTexture].mReleaseFence = mergedFence;
+ }
+ }
+}
+
status_t SurfaceTexture::detachFromContext() {
ATRACE_CALL();
ST_LOGV("detachFromContext");