diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2013-11-22 11:20:20 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2013-11-22 11:20:20 -0800 |
commit | fc3cdb936e6b34257a3bfaf30e89db8f11667cc5 (patch) | |
tree | 4eb3500004e152440074ae85e31d61148fb51cd8 /libs/gui/ConsumerBase.cpp | |
parent | f2f74ca65f34ae0cae6f0cca40f1c18aa771739d (diff) | |
parent | afd0debe4bdf47dc0f968282ca1261842bb65d60 (diff) | |
download | frameworks_native-fc3cdb936e6b34257a3bfaf30e89db8f11667cc5.zip frameworks_native-fc3cdb936e6b34257a3bfaf30e89db8f11667cc5.tar.gz frameworks_native-fc3cdb936e6b34257a3bfaf30e89db8f11667cc5.tar.bz2 |
Merge commit 'afd0debe4bdf47dc0f968282ca1261842bb65d60' into HEAD
Change-Id: Ic9aed2c57bdfeb250ce2dd7f0e9289ba5b6e936a
Diffstat (limited to 'libs/gui/ConsumerBase.cpp')
-rw-r--r-- | libs/gui/ConsumerBase.cpp | 94 |
1 files changed, 56 insertions, 38 deletions
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp index 4937b17..c4ec857 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -51,9 +51,9 @@ static int32_t createProcessUniqueId() { return android_atomic_inc(&globalCounter); } -ConsumerBase::ConsumerBase(const sp<BufferQueue>& bufferQueue) : +ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) : mAbandoned(false), - mBufferQueue(bufferQueue) { + mConsumer(bufferQueue) { // Choose a name using the PID and a process-unique ID. mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); @@ -61,17 +61,15 @@ ConsumerBase::ConsumerBase(const sp<BufferQueue>& bufferQueue) : // reference once the ctor ends, as that would cause the refcount of 'this' // dropping to 0 at the end of the ctor. Since all we need is a wp<...> // that's what we create. - wp<BufferQueue::ConsumerListener> listener; - sp<BufferQueue::ConsumerListener> proxy; - listener = static_cast<BufferQueue::ConsumerListener*>(this); - proxy = new BufferQueue::ProxyConsumerListener(listener); + wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this); + sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener); - status_t err = mBufferQueue->consumerConnect(proxy); + status_t err = mConsumer->consumerConnect(proxy, controlledByApp); if (err != NO_ERROR) { CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)", strerror(-err), err); } else { - mBufferQueue->setConsumerName(mName); + mConsumer->setConsumerName(mName); } } @@ -95,12 +93,7 @@ void ConsumerBase::freeBufferLocked(int slotIndex) { CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); mSlots[slotIndex].mGraphicBuffer = 0; mSlots[slotIndex].mFence = Fence::NO_FENCE; -} - -// Used for refactoring, should not be in final interface -sp<BufferQueue> ConsumerBase::getBufferQueue() const { - Mutex::Autolock lock(mMutex); - return mBufferQueue; + mSlots[slotIndex].mFrameNumber = 0; } void ConsumerBase::onFrameAvailable() { @@ -129,7 +122,7 @@ void ConsumerBase::onBuffersReleased() { } uint32_t mask = 0; - mBufferQueue->getReleasedBuffers(&mask); + mConsumer->getReleasedBuffers(&mask); for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { if (mask & (1 << i)) { freeBufferLocked(i); @@ -153,8 +146,8 @@ void ConsumerBase::abandonLocked() { freeBufferLocked(i); } // disconnect from the BufferQueue - mBufferQueue->consumerDisconnect(); - mBufferQueue.clear(); + mConsumer->consumerDisconnect(); + mConsumer.clear(); } void ConsumerBase::setFrameAvailableListener( @@ -165,28 +158,25 @@ void ConsumerBase::setFrameAvailableListener( } void ConsumerBase::dump(String8& result) const { - char buffer[1024]; - dump(result, "", buffer, 1024); + dump(result, ""); } -void ConsumerBase::dump(String8& result, const char* prefix, - char* buffer, size_t size) const { +void ConsumerBase::dump(String8& result, const char* prefix) const { Mutex::Autolock _l(mMutex); - dumpLocked(result, prefix, buffer, size); + dumpLocked(result, prefix); } -void ConsumerBase::dumpLocked(String8& result, const char* prefix, - char* buffer, size_t SIZE) const { - snprintf(buffer, SIZE, "%smAbandoned=%d\n", prefix, int(mAbandoned)); - result.append(buffer); +void ConsumerBase::dumpLocked(String8& result, const char* prefix) const { + result.appendFormat("%smAbandoned=%d\n", prefix, int(mAbandoned)); if (!mAbandoned) { - mBufferQueue->dump(result, prefix, buffer, SIZE); + mConsumer->dump(result, prefix); } } -status_t ConsumerBase::acquireBufferLocked(BufferQueue::BufferItem *item) { - status_t err = mBufferQueue->acquireBuffer(item); +status_t ConsumerBase::acquireBufferLocked(BufferQueue::BufferItem *item, + nsecs_t presentWhen) { + status_t err = mConsumer->acquireBuffer(item, presentWhen); if (err != NO_ERROR) { return err; } @@ -195,21 +185,31 @@ status_t ConsumerBase::acquireBufferLocked(BufferQueue::BufferItem *item) { mSlots[item->mBuf].mGraphicBuffer = item->mGraphicBuffer; } + mSlots[item->mBuf].mFrameNumber = item->mFrameNumber; mSlots[item->mBuf].mFence = item->mFence; - CB_LOGV("acquireBufferLocked: -> slot=%d", item->mBuf); + CB_LOGV("acquireBufferLocked: -> slot=%d/%llu", + item->mBuf, item->mFrameNumber); return OK; } -status_t ConsumerBase::addReleaseFence(int slot, const sp<Fence>& fence) { +status_t ConsumerBase::addReleaseFence(int slot, + const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence) { Mutex::Autolock lock(mMutex); - return addReleaseFenceLocked(slot, fence); + return addReleaseFenceLocked(slot, graphicBuffer, fence); } -status_t ConsumerBase::addReleaseFenceLocked(int slot, const sp<Fence>& fence) { +status_t ConsumerBase::addReleaseFenceLocked(int slot, + const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence) { CB_LOGV("addReleaseFenceLocked: slot=%d", slot); + // If consumer no longer tracks this graphicBuffer, we can safely + // drop this fence, as it will never be received by the producer. + if (!stillTracking(slot, graphicBuffer)) { + return OK; + } + if (!mSlots[slot].mFence.get()) { mSlots[slot].mFence = fence; } else { @@ -229,11 +229,20 @@ status_t ConsumerBase::addReleaseFenceLocked(int slot, const sp<Fence>& fence) { return OK; } -status_t ConsumerBase::releaseBufferLocked(int slot, EGLDisplay display, - EGLSyncKHR eglFence) { - CB_LOGV("releaseBufferLocked: slot=%d", slot); - status_t err = mBufferQueue->releaseBuffer(slot, display, eglFence, - mSlots[slot].mFence); +status_t ConsumerBase::releaseBufferLocked( + int slot, const sp<GraphicBuffer> graphicBuffer, + EGLDisplay display, EGLSyncKHR eglFence) { + // If consumer no longer tracks this graphicBuffer (we received a new + // buffer on the same slot), the buffer producer is definitely no longer + // tracking it. + if (!stillTracking(slot, graphicBuffer)) { + return OK; + } + + CB_LOGV("releaseBufferLocked: slot=%d/%llu", + slot, mSlots[slot].mFrameNumber); + status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber, + display, eglFence, mSlots[slot].mFence); if (err == BufferQueue::STALE_BUFFER_SLOT) { freeBufferLocked(slot); } @@ -243,4 +252,13 @@ status_t ConsumerBase::releaseBufferLocked(int slot, EGLDisplay display, return err; } +bool ConsumerBase::stillTracking(int slot, + const sp<GraphicBuffer> graphicBuffer) { + if (slot < 0 || slot >= BufferQueue::NUM_BUFFER_SLOTS) { + return false; + } + return (mSlots[slot].mGraphicBuffer != NULL && + mSlots[slot].mGraphicBuffer->handle == graphicBuffer->handle); +} + } // namespace android |