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
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 @@
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);
}