diff options
author | Jamie Gennis <jgennis@google.com> | 2012-09-05 20:09:05 -0700 |
---|---|---|
committer | Jamie Gennis <jgennis@google.com> | 2012-09-06 17:54:53 -0700 |
commit | b27254154642575dfb4bbfa79fbedde7d7ee23dd (patch) | |
tree | 20f11812c640baf475d46d04f6c3ac88e47d1829 /libs/gui | |
parent | 331841b96b92646c93c87627c03f77b892f711cd (diff) | |
download | frameworks_native-b27254154642575dfb4bbfa79fbedde7d7ee23dd.zip frameworks_native-b27254154642575dfb4bbfa79fbedde7d7ee23dd.tar.gz frameworks_native-b27254154642575dfb4bbfa79fbedde7d7ee23dd.tar.bz2 |
libgui: move fence handling into ConsumerBase
This change moves some common fence handling code into the base class for
BufferQueue consumer classes. It also makes the ConsumerBase class initialize
a buffer slot's fence with the acquire fence every time a buffer is acquired.
Change-Id: I0bd88bc269e919653b659bfb3ebfb04dd61692a0
Diffstat (limited to 'libs/gui')
-rw-r--r-- | libs/gui/BufferItemConsumer.cpp | 4 | ||||
-rw-r--r-- | libs/gui/ConsumerBase.cpp | 29 | ||||
-rw-r--r-- | libs/gui/CpuConsumer.cpp | 2 | ||||
-rw-r--r-- | libs/gui/SurfaceTexture.cpp | 29 |
4 files changed, 40 insertions, 24 deletions
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp index 57df39c..74b684f 100644 --- a/libs/gui/BufferItemConsumer.cpp +++ b/libs/gui/BufferItemConsumer.cpp @@ -82,8 +82,10 @@ status_t BufferItemConsumer::releaseBuffer(const BufferItem &item, Mutex::Autolock _l(mMutex); + err = addReleaseFence(item.mBuf, releaseFence); + err = releaseBufferLocked(item.mBuf, EGL_NO_DISPLAY, - EGL_NO_SYNC_KHR, releaseFence); + EGL_NO_SYNC_KHR); if (err != OK) { BI_LOGE("Failed to release buffer: %s (%d)", strerror(-err), err); diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp index 17bbfd1..fd2d1cc 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -185,15 +185,40 @@ status_t ConsumerBase::acquireBufferLocked(BufferQueue::BufferItem *item) { mSlots[item->mBuf].mGraphicBuffer = item->mGraphicBuffer; } + mSlots[item->mBuf].mFence = item->mFence; + CB_LOGV("acquireBufferLocked: -> slot=%d", item->mBuf); return OK; } +status_t ConsumerBase::addReleaseFence(int slot, const sp<Fence>& fence) { + CB_LOGV("addReleaseFence: slot=%d", slot); + + if (!mSlots[slot].mFence.get()) { + mSlots[slot].mFence = fence; + } else { + sp<Fence> mergedFence = Fence::merge( + String8("ConsumerBase merged release"), + mSlots[slot].mFence, fence); + if (!mergedFence.get()) { + CB_LOGE("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 + mSlots[slot].mFence = fence; + return BAD_VALUE; + } + mSlots[slot].mFence = mergedFence; + } + + return OK; +} + status_t ConsumerBase::releaseBufferLocked(int slot, EGLDisplay display, - EGLSyncKHR eglFence, const sp<Fence>& fence) { + EGLSyncKHR eglFence) { CB_LOGV("releaseBufferLocked: slot=%d", slot); - status_t err = mBufferQueue->releaseBuffer(slot, display, eglFence, fence); + status_t err = mBufferQueue->releaseBuffer(slot, display, eglFence, + mSlots[slot].mFence); if (err == BufferQueue::STALE_BUFFER_SLOT) { freeBufferLocked(slot); } diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp index fc4a854..e1a2838 100644 --- a/libs/gui/CpuConsumer.cpp +++ b/libs/gui/CpuConsumer.cpp @@ -134,7 +134,7 @@ status_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) { CC_LOGE("%s: Unable to unlock graphic buffer %d", __FUNCTION__, slotIndex); return err; } - releaseBufferLocked(slotIndex, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE); + releaseBufferLocked(slotIndex, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); mCurrentLockedBuffers--; diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp index 975eb23..b5872b8 100644 --- a/libs/gui/SurfaceTexture.cpp +++ b/libs/gui/SurfaceTexture.cpp @@ -172,9 +172,9 @@ status_t SurfaceTexture::acquireBufferLocked(BufferQueue::BufferItem *item) { } status_t SurfaceTexture::releaseBufferLocked(int buf, EGLDisplay display, - EGLSyncKHR eglFence, const sp<Fence>& fence) { + EGLSyncKHR eglFence) { status_t err = ConsumerBase::releaseBufferLocked(buf, mEglDisplay, - eglFence, fence); + eglFence); mEglSlots[mCurrentTexture].mEglFence = EGL_NO_SYNC_KHR; @@ -229,7 +229,7 @@ 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(mSlots[buf].mGraphicBuffer, item)) { - releaseBufferLocked(buf, dpy, EGL_NO_SYNC_KHR, item.mFence); + releaseBufferLocked(buf, dpy, EGL_NO_SYNC_KHR); glBindTexture(mTexTarget, mTexName); return NO_ERROR; } @@ -256,7 +256,7 @@ 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. - releaseBufferLocked(buf, dpy, EGL_NO_SYNC_KHR, item.mFence); + releaseBufferLocked(buf, dpy, EGL_NO_SYNC_KHR); return err; } @@ -268,8 +268,7 @@ status_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) { // release old buffer if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { status_t status = releaseBufferLocked(mCurrentTexture, dpy, - mEglSlots[mCurrentTexture].mEglFence, - mSlots[mCurrentTexture].mFence); + mEglSlots[mCurrentTexture].mEglFence); if (status != NO_ERROR && status != BufferQueue::STALE_BUFFER_SLOT) { ST_LOGE("updateTexImage: failed to release buffer: %s (%d)", strerror(-status), status); @@ -304,20 +303,10 @@ void SurfaceTexture::setReleaseFence(int fenceFd) { sp<Fence> fence(new Fence(fenceFd)); if (fenceFd == -1 || mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT) return; - if (!mSlots[mCurrentTexture].mFence.get()) { - mSlots[mCurrentTexture].mFence = fence; - } else { - sp<Fence> mergedFence = Fence::merge( - String8("SurfaceTexture merged release"), - mSlots[mCurrentTexture].mFence, fence); - if (!mergedFence.get()) { - ST_LOGE("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 - mSlots[mCurrentTexture].mFence = fence; - return; - } - mSlots[mCurrentTexture].mFence = mergedFence; + status_t err = addReleaseFence(mCurrentTexture, fence); + if (err != OK) { + ST_LOGE("setReleaseFence: failed to add the fence: %s (%d)", + strerror(-err), err); } } |