libgui: Plumb attach/detach through CpuConsumer
Adds CpuConsumer::{detachNextBuffer,attachAndReleaseBuffer}, which can be used to more carefully manage the ownership of GraphicBuffers. Bug: 19628705 Change-Id: Ia7aa1ac59c2f768f2d8a0f35ad23067936a7427c
This commit is contained in:
parent
54716317b5
commit
43078e2827
|
@ -114,6 +114,20 @@ class CpuConsumer : public ConsumerBase
|
||||||
// lockNextBuffer.
|
// lockNextBuffer.
|
||||||
status_t unlockBuffer(const LockedBuffer &nativeBuffer);
|
status_t unlockBuffer(const LockedBuffer &nativeBuffer);
|
||||||
|
|
||||||
|
// Gets the next buffer from the producer (if any), and transfers ownership
|
||||||
|
// of it from the queue to the caller.
|
||||||
|
//
|
||||||
|
// See IGraphicBufferConsumer::{acquireBuffer,detachBuffer} for possible
|
||||||
|
// error codes.
|
||||||
|
status_t detachNextBuffer(BufferItem* outItem);
|
||||||
|
|
||||||
|
// Transfers ownership of the buffer from the caller to the queue, and
|
||||||
|
// releases the buffer for use by the producer.
|
||||||
|
//
|
||||||
|
// See IGraphicBufferConsumer::{attachBuffer,releaseBuffer} for possible
|
||||||
|
// error codes.
|
||||||
|
status_t attachAndReleaseBuffer(const sp<GraphicBuffer>& buffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Maximum number of buffers that can be locked at a time
|
// Maximum number of buffers that can be locked at a time
|
||||||
size_t mMaxLockedBuffers;
|
size_t mMaxLockedBuffers;
|
||||||
|
|
|
@ -247,12 +247,16 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot,
|
||||||
ATRACE_BUFFER_INDEX(*outSlot);
|
ATRACE_BUFFER_INDEX(*outSlot);
|
||||||
BQ_LOGV("attachBuffer(C): returning slot %d", *outSlot);
|
BQ_LOGV("attachBuffer(C): returning slot %d", *outSlot);
|
||||||
|
|
||||||
|
// If these are modified, they also need to be modified in
|
||||||
|
// CpuConsumer::attachAndReleaseBuffer
|
||||||
mSlots[*outSlot].mGraphicBuffer = buffer;
|
mSlots[*outSlot].mGraphicBuffer = buffer;
|
||||||
|
mSlots[*outSlot].mFence = Fence::NO_FENCE;
|
||||||
|
mSlots[*outSlot].mFrameNumber = 0;
|
||||||
|
|
||||||
|
// Changes to these do not need to be propagated to CpuConsumer
|
||||||
mSlots[*outSlot].mBufferState = BufferSlot::ACQUIRED;
|
mSlots[*outSlot].mBufferState = BufferSlot::ACQUIRED;
|
||||||
mSlots[*outSlot].mAttachedByConsumer = true;
|
mSlots[*outSlot].mAttachedByConsumer = true;
|
||||||
mSlots[*outSlot].mNeedsCleanupOnRelease = false;
|
mSlots[*outSlot].mNeedsCleanupOnRelease = false;
|
||||||
mSlots[*outSlot].mFence = Fence::NO_FENCE;
|
|
||||||
mSlots[*outSlot].mFrameNumber = 0;
|
|
||||||
|
|
||||||
// mAcquireCalled tells BufferQueue that it doesn't need to send a valid
|
// mAcquireCalled tells BufferQueue that it doesn't need to send a valid
|
||||||
// GraphicBuffer pointer on the next acquireBuffer call, which decreases
|
// GraphicBuffer pointer on the next acquireBuffer call, which decreases
|
||||||
|
|
|
@ -277,4 +277,59 @@ void CpuConsumer::freeBufferLocked(int slotIndex) {
|
||||||
ConsumerBase::freeBufferLocked(slotIndex);
|
ConsumerBase::freeBufferLocked(slotIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t CpuConsumer::detachNextBuffer(BufferItem* outItem) {
|
||||||
|
if (outItem == NULL) {
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mutex::Autolock lock(mMutex);
|
||||||
|
|
||||||
|
BufferItem item;
|
||||||
|
status_t result = acquireBufferLocked(&item, 0);
|
||||||
|
if (result != NO_ERROR) {
|
||||||
|
CC_LOGE("%s: Failed to acquire buffer (%d)", __FUNCTION__, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = mConsumer->detachBuffer(item.mSlot);
|
||||||
|
if (result != NO_ERROR) {
|
||||||
|
CC_LOGE("%s: Failed to detach buffer (%d)", __FUNCTION__, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeBufferLocked(item.mSlot);
|
||||||
|
|
||||||
|
*outItem = item;
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t CpuConsumer::attachAndReleaseBuffer(const sp<GraphicBuffer>& buffer) {
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mutex::Autolock lock(mMutex);
|
||||||
|
|
||||||
|
int slot = -1;
|
||||||
|
status_t result = mConsumer->attachBuffer(&slot, buffer);
|
||||||
|
if (result != NO_ERROR) {
|
||||||
|
CC_LOGE("%s: Failed to attach buffer (%d)", __FUNCTION__, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These behaviors must be kept in sync with
|
||||||
|
// BufferQueueConsumer::attachBuffer
|
||||||
|
mSlots[slot].mGraphicBuffer = buffer;
|
||||||
|
mSlots[slot].mFence = Fence::NO_FENCE;
|
||||||
|
mSlots[slot].mFrameNumber = 0;
|
||||||
|
|
||||||
|
result = releaseBufferLocked(slot, buffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
|
||||||
|
if (result != NO_ERROR) {
|
||||||
|
CC_LOGE("%s: Failed to release buffer (%d)", __FUNCTION__, result);
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
Loading…
Reference in New Issue