diff options
author | Dan Stoza <stoza@google.com> | 2014-04-18 16:09:10 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-04-18 16:09:10 +0000 |
commit | 76173383e17a809ac19f0825f23ac80f02c4d5e0 (patch) | |
tree | 27f44b14cba1753ff40984effed5cf80703eded5 /libs | |
parent | dd306d43ed38550cfdbef66402d7fa3de5ba3a23 (diff) | |
parent | d9822a3843017444364899afc3c23fb5be6b9cb9 (diff) | |
download | frameworks_native-76173383e17a809ac19f0825f23ac80f02c4d5e0.zip frameworks_native-76173383e17a809ac19f0825f23ac80f02c4d5e0.tar.gz frameworks_native-76173383e17a809ac19f0825f23ac80f02c4d5e0.tar.bz2 |
Merge "BufferQueueProducer: add detachNextBuffer"
Diffstat (limited to 'libs')
-rw-r--r-- | libs/gui/BufferQueue.cpp | 5 | ||||
-rw-r--r-- | libs/gui/BufferQueueProducer.cpp | 44 | ||||
-rw-r--r-- | libs/gui/IGraphicBufferProducer.cpp | 50 |
3 files changed, 99 insertions, 0 deletions
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index d04b67d..da980a7 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -103,6 +103,11 @@ status_t BufferQueue::detachProducerBuffer(int slot) { return mProducer->detachBuffer(slot); } +status_t BufferQueue::detachNextBuffer(sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence) { + return mProducer->detachNextBuffer(outBuffer, outFence); +} + status_t BufferQueue::attachProducerBuffer(int* slot, const sp<GraphicBuffer>& buffer) { return mProducer->attachBuffer(slot, buffer); diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index ea37309..61846dd 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -393,6 +393,50 @@ status_t BufferQueueProducer::detachBuffer(int slot) { return NO_ERROR; } +status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence) { + ATRACE_CALL(); + + if (outBuffer == NULL) { + BQ_LOGE("detachNextBuffer: outBuffer must not be NULL"); + return BAD_VALUE; + } else if (outFence == NULL) { + BQ_LOGE("detachNextBuffer: outFence must not be NULL"); + return BAD_VALUE; + } + + Mutex::Autolock lock(mCore->mMutex); + + if (mCore->mIsAbandoned) { + BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned"); + return NO_INIT; + } + + // Find the oldest valid slot + int found = BufferQueueCore::INVALID_BUFFER_SLOT; + for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { + if (mSlots[s].mBufferState == BufferSlot::FREE && + mSlots[s].mGraphicBuffer != NULL) { + if (found == BufferQueueCore::INVALID_BUFFER_SLOT || + mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) { + found = s; + } + } + } + + if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { + return NO_MEMORY; + } + + BQ_LOGV("detachNextBuffer detached slot %d", found); + + *outBuffer = mSlots[found].mGraphicBuffer; + *outFence = mSlots[found].mFence; + mCore->freeBufferLocked(found); + + return NO_ERROR; +} + status_t BufferQueueProducer::attachBuffer(int* outSlot, const sp<android::GraphicBuffer>& buffer) { ATRACE_CALL(); diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index c0b08c1..aa6acb9 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -37,6 +37,7 @@ enum { SET_BUFFER_COUNT, DEQUEUE_BUFFER, DETACH_BUFFER, + DETACH_NEXT_BUFFER, ATTACH_BUFFER, QUEUE_BUFFER, CANCEL_BUFFER, @@ -123,6 +124,37 @@ public: return result; } + virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence) { + if (outBuffer == NULL) { + ALOGE("detachNextBuffer: outBuffer must not be NULL"); + return BAD_VALUE; + } else if (outFence == NULL) { + ALOGE("detachNextBuffer: outFence must not be NULL"); + return BAD_VALUE; + } + Parcel data, reply; + data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); + status_t result = remote()->transact(DETACH_NEXT_BUFFER, data, &reply); + if (result != NO_ERROR) { + return result; + } + result = reply.readInt32(); + if (result == NO_ERROR) { + bool nonNull = reply.readInt32(); + if (nonNull) { + *outBuffer = new GraphicBuffer; + reply.read(**outBuffer); + } + nonNull = reply.readInt32(); + if (nonNull) { + *outFence = new Fence; + reply.read(**outFence); + } + } + return result; + } + virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); @@ -274,6 +306,24 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); return NO_ERROR; } break; + case DETACH_NEXT_BUFFER: { + CHECK_INTERFACE(IGraphicBufferProducer, data, reply); + sp<GraphicBuffer> buffer; + sp<Fence> fence; + int32_t result = detachNextBuffer(&buffer, &fence); + reply->writeInt32(result); + if (result == NO_ERROR) { + reply->writeInt32(buffer != NULL); + if (buffer != NULL) { + reply->write(*buffer); + } + reply->writeInt32(fence != NULL); + if (fence != NULL) { + reply->write(*fence); + } + } + return NO_ERROR; + } break; case ATTACH_BUFFER: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); sp<GraphicBuffer> buffer = new GraphicBuffer(); |