diff options
author | Jesse Hall <jessehall@google.com> | 2012-06-14 14:45:17 -0700 |
---|---|---|
committer | Jesse Hall <jessehall@google.com> | 2012-06-21 22:21:12 -0700 |
commit | ef19414bd8b77a26f5751f3845be79025a8263fe (patch) | |
tree | 9624b3d718e065747bedff50cb969151d675a471 /libs/gui/SurfaceTexture.cpp | |
parent | a74cbc06493ed941a8a54f2f1d0074f03fc9aafb (diff) | |
download | frameworks_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.cpp | 34 |
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"); |