Loading include/gui/BufferQueueCore.h +4 −2 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <list> #include <set> #include <vector> #define BQ_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) #define BQ_LOGD(x, ...) ALOGD("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) Loading Loading @@ -120,8 +121,9 @@ private: void freeAllBuffersLocked(); // If delta is positive, makes more slots available. If negative, takes // away slots. Returns false if the request can't be met. bool adjustAvailableSlotsLocked(int delta); // away slots. Returns false if the request can't be met. Any slots that // were freed will be appended to freedSlots. bool adjustAvailableSlotsLocked(int delta, std::vector<int>* freedSlots); // waitWhileAllocatingLocked blocks until mIsAllocating is false. void waitWhileAllocatingLocked() const; Loading include/gui/IProducerListener.h +3 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,9 @@ public: // This is called without any lock held and can be called concurrently by // multiple threads. virtual void onBufferReleased() = 0; // Asynchronous // onSlotFreed is called when the BufferQueue frees a buffer in a slot. virtual void onSlotFreed(int /*slot*/) {}; // Asynchronous }; class IProducerListener : public ProducerListener, public IInterface Loading libs/gui/BufferQueueConsumer.cpp +82 −47 Original line number Diff line number Diff line Loading @@ -274,6 +274,10 @@ status_t BufferQueueConsumer::detachBuffer(int slot) { ATRACE_CALL(); ATRACE_BUFFER_INDEX(slot); BQ_LOGV("detachBuffer: slot %d", slot); sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; { Mutex::Autolock lock(mCore->mMutex); if (mCore->mIsAbandoned) { Loading Loading @@ -303,6 +307,18 @@ status_t BufferQueueConsumer::detachBuffer(int slot) { mCore->clearBufferSlotLocked(slot); mCore->mDequeueCondition.broadcast(); VALIDATE_CONSISTENCY(); producerListener = mCore->mConnectedProducerListener; consumerListener = mCore->mConsumerListener; } // Call back without lock held if (producerListener != NULL) { producerListener->onSlotFreed(slot); } if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } return NO_ERROR; } Loading Loading @@ -573,8 +589,9 @@ status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) { return BAD_VALUE; } sp<IConsumerListener> listener; { Mutex::Autolock lock(mCore->mMutex); if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { BQ_LOGE("setMaxBufferCount: producer is already connected"); return INVALID_OPERATION; Loading @@ -590,13 +607,22 @@ status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) { int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, mCore->mDequeueBufferCannotBlock, bufferCount) - mCore->getMaxBufferCountLocked(); if (!mCore->adjustAvailableSlotsLocked(delta)) { BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number of " "available slots. Delta = %d", delta); if (!mCore->adjustAvailableSlotsLocked(delta, nullptr)) { BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number" " of available slots. Delta = %d", delta); return BAD_VALUE; } mCore->mMaxBufferCount = bufferCount; if (delta < 0) { listener = mCore->mConsumerListener; } } // Call back without lock held if (listener != NULL) { listener->onBuffersReleased(); } return NO_ERROR; } Loading @@ -611,7 +637,9 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( return BAD_VALUE; } sp<IConsumerListener> listener; sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; std::vector<int> freedSlots; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(); Loading Loading @@ -648,7 +676,7 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( } int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount; if (!mCore->adjustAvailableSlotsLocked(delta)) { if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) { return BAD_VALUE; } Loading @@ -656,12 +684,19 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers; VALIDATE_CONSISTENCY(); if (delta < 0) { listener = mCore->mConsumerListener; consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; } } // Call back without lock held if (listener != NULL) { listener->onBuffersReleased(); if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { for (int i : freedSlots) { producerListener->onSlotFreed(i); } } return NO_ERROR; Loading libs/gui/BufferQueueCore.cpp +8 −1 Original line number Diff line number Diff line Loading @@ -225,7 +225,8 @@ void BufferQueueCore::freeAllBuffersLocked() { VALIDATE_CONSISTENCY(); } bool BufferQueueCore::adjustAvailableSlotsLocked(int delta) { bool BufferQueueCore::adjustAvailableSlotsLocked(int delta, std::vector<int>* freedSlots) { if (delta >= 0) { // If we're going to fail, do so before modifying anything if (delta > static_cast<int>(mUnusedSlots.size())) { Loading @@ -252,11 +253,17 @@ bool BufferQueueCore::adjustAvailableSlotsLocked(int delta) { clearBufferSlotLocked(*slot); mUnusedSlots.push_back(*slot); mFreeSlots.erase(slot); if (freedSlots) { freedSlots->push_back(*slot); } } else if (!mFreeBuffers.empty()) { int slot = mFreeBuffers.back(); clearBufferSlotLocked(slot); mUnusedSlots.push_back(slot); mFreeBuffers.pop_back(); if (freedSlots) { freedSlots->push_back(slot); } } else { return false; } Loading libs/gui/BufferQueueProducer.cpp +248 −143 Original line number Diff line number Diff line Loading @@ -90,7 +90,9 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount( BQ_LOGV("setMaxDequeuedBufferCount: maxDequeuedBuffers = %d", maxDequeuedBuffers); sp<IConsumerListener> listener; sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; std::vector<int> freedSlots; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(); Loading Loading @@ -142,20 +144,26 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount( } int delta = maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount; if (!mCore->adjustAvailableSlotsLocked(delta)) { if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) { return BAD_VALUE; } mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers; VALIDATE_CONSISTENCY(); if (delta < 0) { listener = mCore->mConsumerListener; consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; } mCore->mDequeueCondition.broadcast(); } // Autolock scope // Call back without lock held if (listener != NULL) { listener->onBuffersReleased(); if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { for (int i : freedSlots) { producerListener->onSlotFreed(i); } } return NO_ERROR; Loading @@ -165,7 +173,9 @@ status_t BufferQueueProducer::setAsyncMode(bool async) { ATRACE_CALL(); BQ_LOGV("setAsyncMode: async = %d", async); sp<IConsumerListener> listener; sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; std::vector<int> freedSlots; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(); Loading @@ -191,7 +201,7 @@ status_t BufferQueueProducer::setAsyncMode(bool async) { mCore->mDequeueBufferCannotBlock, mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked(); if (!mCore->adjustAvailableSlotsLocked(delta)) { if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) { BQ_LOGE("setAsyncMode: BufferQueue failed to adjust the number of " "available slots. Delta = %d", delta); return BAD_VALUE; Loading @@ -199,12 +209,20 @@ status_t BufferQueueProducer::setAsyncMode(bool async) { mCore->mAsyncMode = async; VALIDATE_CONSISTENCY(); mCore->mDequeueCondition.broadcast(); listener = mCore->mConsumerListener; if (delta < 0) { consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; } } // Autolock scope // Call back without lock held if (listener != NULL) { listener->onBuffersReleased(); if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { for (int i : freedSlots) { producerListener->onSlotFreed(i); } } return NO_ERROR; } Loading Loading @@ -361,6 +379,9 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; bool attachedByConsumer = false; sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; int found = BufferItem::INVALID_BUFFER_SLOT; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(); Loading @@ -378,7 +399,6 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, height = mCore->mDefaultHeight; } int found = BufferItem::INVALID_BUFFER_SLOT; while (found == BufferItem::INVALID_BUFFER_SLOT) { status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue, &found); Loading Loading @@ -408,6 +428,8 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, mCore->mFreeSlots.insert(found); mCore->clearBufferSlotLocked(found); found = BufferItem::INVALID_BUFFER_SLOT; consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; continue; } } Loading Loading @@ -444,6 +466,10 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, if ((buffer == NULL) || buffer->needsReallocation(width, height, format, usage)) { if (buffer != NULL) { consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; } mSlots[found].mAcquireCalled = false; mSlots[found].mGraphicBuffer = NULL; mSlots[found].mRequestBufferCalled = false; Loading Loading @@ -531,6 +557,14 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, mSlots[*outSlot].mFrameNumber, mSlots[*outSlot].mGraphicBuffer->handle, returnFlags); // Call back without lock held if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { producerListener->onSlotFreed(found); } return returnFlags; } Loading @@ -538,6 +572,10 @@ status_t BufferQueueProducer::detachBuffer(int slot) { ATRACE_CALL(); ATRACE_BUFFER_INDEX(slot); BQ_LOGV("detachBuffer: slot %d", slot); sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; { Mutex::Autolock lock(mCore->mMutex); if (mCore->mIsAbandoned) { Loading @@ -551,7 +589,8 @@ status_t BufferQueueProducer::detachBuffer(int slot) { } if (mCore->mSingleBufferMode || mCore->mSingleBufferSlot == slot) { BQ_LOGE("detachBuffer: cannot detach a buffer in single buffer mode"); BQ_LOGE("detachBuffer: cannot detach a buffer in single buffer " "mode"); return BAD_VALUE; } Loading @@ -575,6 +614,17 @@ status_t BufferQueueProducer::detachBuffer(int slot) { mCore->clearBufferSlotLocked(slot); mCore->mDequeueCondition.broadcast(); VALIDATE_CONSISTENCY(); producerListener = mCore->mConnectedProducerListener; consumerListener = mCore->mConsumerListener; } // Call back without lock held if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { producerListener->onSlotFreed(slot); } return NO_ERROR; } Loading @@ -591,8 +641,11 @@ status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, return BAD_VALUE; } sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; int found = BufferQueueCore::INVALID_BUFFER_SLOT; { Mutex::Autolock lock(mCore->mMutex); if (mCore->mIsAbandoned) { BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned"); return NO_INIT; Loading @@ -615,7 +668,7 @@ status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, return NO_MEMORY; } int found = mCore->mFreeBuffers.front(); found = mCore->mFreeBuffers.front(); mCore->mFreeBuffers.remove(found); mCore->mFreeSlots.insert(found); Loading @@ -625,6 +678,17 @@ status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, *outFence = mSlots[found].mFence; mCore->clearBufferSlotLocked(found); VALIDATE_CONSISTENCY(); consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; } // Call back without lock held if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { producerListener->onSlotFreed(found); } return NO_ERROR; } Loading Loading @@ -1020,6 +1084,11 @@ int BufferQueueProducer::query(int what, int *outValue) { status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, int api, bool producerControlledByApp, QueueBufferOutput *output) { ATRACE_CALL(); int status = NO_ERROR; sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; std::vector<int> freedSlots; { Mutex::Autolock lock(mCore->mMutex); mConsumerName = mCore->mConsumerName; BQ_LOGV("connect: api=%d producerControlledByApp=%s", api, Loading @@ -1046,18 +1115,19 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, return BAD_VALUE; } bool dequeueBufferCannotBlock = mDequeueTimeout < 0 ? mCore->mConsumerControlledByApp && producerControlledByApp : false; int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, mDequeueTimeout < 0 ? mCore->mConsumerControlledByApp && producerControlledByApp : false, mCore->mMaxBufferCount) - dequeueBufferCannotBlock, mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked(); if (!mCore->adjustAvailableSlotsLocked(delta)) { BQ_LOGE("connect: BufferQueue failed to adjust the number of available " "slots. Delta = %d", delta); if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) { BQ_LOGE("connect: BufferQueue failed to adjust the number of " "available slots. Delta = %d", delta); return BAD_VALUE; } int status = NO_ERROR; switch (api) { case NATIVE_WINDOW_API_EGL: case NATIVE_WINDOW_API_CPU: Loading @@ -1071,7 +1141,8 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, // Set up a death notification so that we can disconnect // automatically if the remote producer dies if (listener != NULL && IInterface::asBinder(listener)->remoteBinder() != NULL) { IInterface::asBinder(listener)->remoteBinder() != NULL) { status = IInterface::asBinder(listener)->linkToDeath( static_cast<IBinder::DeathRecipient*>(this)); if (status != NO_ERROR) { Loading @@ -1088,14 +1159,27 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, } mCore->mBufferHasBeenQueued = false; mCore->mDequeueBufferCannotBlock = false; if (mDequeueTimeout < 0) { mCore->mDequeueBufferCannotBlock = mCore->mConsumerControlledByApp && producerControlledByApp; } mCore->mDequeueBufferCannotBlock = dequeueBufferCannotBlock; mCore->mAllowAllocation = true; VALIDATE_CONSISTENCY(); if (delta < 0) { consumerListener = mCore->mConsumerListener; producerListener = listener; } } // Call back without lock held if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { for (int i : freedSlots) { producerListener->onSlotFreed(i); } } return status; } Loading Loading @@ -1313,12 +1397,16 @@ status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) { ATRACE_CALL(); BQ_LOGV("setDequeueTimeout: %" PRId64, timeout); sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; std::vector<int> freedSlots; { Mutex::Autolock lock(mCore->mMutex); int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false, mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked(); if (!mCore->adjustAvailableSlotsLocked(delta)) { BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of " "available slots. Delta = %d", delta); if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) { BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number" " of available slots. Delta = %d", delta); return BAD_VALUE; } Loading @@ -1326,6 +1414,23 @@ status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) { mCore->mDequeueBufferCannotBlock = false; VALIDATE_CONSISTENCY(); if (delta < 0) { consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; } } // Call back without lock held if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { for (int i : freedSlots) { producerListener->onSlotFreed(i); } } return NO_ERROR; } Loading Loading
include/gui/BufferQueueCore.h +4 −2 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <list> #include <set> #include <vector> #define BQ_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) #define BQ_LOGD(x, ...) ALOGD("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) Loading Loading @@ -120,8 +121,9 @@ private: void freeAllBuffersLocked(); // If delta is positive, makes more slots available. If negative, takes // away slots. Returns false if the request can't be met. bool adjustAvailableSlotsLocked(int delta); // away slots. Returns false if the request can't be met. Any slots that // were freed will be appended to freedSlots. bool adjustAvailableSlotsLocked(int delta, std::vector<int>* freedSlots); // waitWhileAllocatingLocked blocks until mIsAllocating is false. void waitWhileAllocatingLocked() const; Loading
include/gui/IProducerListener.h +3 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,9 @@ public: // This is called without any lock held and can be called concurrently by // multiple threads. virtual void onBufferReleased() = 0; // Asynchronous // onSlotFreed is called when the BufferQueue frees a buffer in a slot. virtual void onSlotFreed(int /*slot*/) {}; // Asynchronous }; class IProducerListener : public ProducerListener, public IInterface Loading
libs/gui/BufferQueueConsumer.cpp +82 −47 Original line number Diff line number Diff line Loading @@ -274,6 +274,10 @@ status_t BufferQueueConsumer::detachBuffer(int slot) { ATRACE_CALL(); ATRACE_BUFFER_INDEX(slot); BQ_LOGV("detachBuffer: slot %d", slot); sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; { Mutex::Autolock lock(mCore->mMutex); if (mCore->mIsAbandoned) { Loading Loading @@ -303,6 +307,18 @@ status_t BufferQueueConsumer::detachBuffer(int slot) { mCore->clearBufferSlotLocked(slot); mCore->mDequeueCondition.broadcast(); VALIDATE_CONSISTENCY(); producerListener = mCore->mConnectedProducerListener; consumerListener = mCore->mConsumerListener; } // Call back without lock held if (producerListener != NULL) { producerListener->onSlotFreed(slot); } if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } return NO_ERROR; } Loading Loading @@ -573,8 +589,9 @@ status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) { return BAD_VALUE; } sp<IConsumerListener> listener; { Mutex::Autolock lock(mCore->mMutex); if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { BQ_LOGE("setMaxBufferCount: producer is already connected"); return INVALID_OPERATION; Loading @@ -590,13 +607,22 @@ status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) { int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, mCore->mDequeueBufferCannotBlock, bufferCount) - mCore->getMaxBufferCountLocked(); if (!mCore->adjustAvailableSlotsLocked(delta)) { BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number of " "available slots. Delta = %d", delta); if (!mCore->adjustAvailableSlotsLocked(delta, nullptr)) { BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number" " of available slots. Delta = %d", delta); return BAD_VALUE; } mCore->mMaxBufferCount = bufferCount; if (delta < 0) { listener = mCore->mConsumerListener; } } // Call back without lock held if (listener != NULL) { listener->onBuffersReleased(); } return NO_ERROR; } Loading @@ -611,7 +637,9 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( return BAD_VALUE; } sp<IConsumerListener> listener; sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; std::vector<int> freedSlots; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(); Loading Loading @@ -648,7 +676,7 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( } int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount; if (!mCore->adjustAvailableSlotsLocked(delta)) { if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) { return BAD_VALUE; } Loading @@ -656,12 +684,19 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers; VALIDATE_CONSISTENCY(); if (delta < 0) { listener = mCore->mConsumerListener; consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; } } // Call back without lock held if (listener != NULL) { listener->onBuffersReleased(); if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { for (int i : freedSlots) { producerListener->onSlotFreed(i); } } return NO_ERROR; Loading
libs/gui/BufferQueueCore.cpp +8 −1 Original line number Diff line number Diff line Loading @@ -225,7 +225,8 @@ void BufferQueueCore::freeAllBuffersLocked() { VALIDATE_CONSISTENCY(); } bool BufferQueueCore::adjustAvailableSlotsLocked(int delta) { bool BufferQueueCore::adjustAvailableSlotsLocked(int delta, std::vector<int>* freedSlots) { if (delta >= 0) { // If we're going to fail, do so before modifying anything if (delta > static_cast<int>(mUnusedSlots.size())) { Loading @@ -252,11 +253,17 @@ bool BufferQueueCore::adjustAvailableSlotsLocked(int delta) { clearBufferSlotLocked(*slot); mUnusedSlots.push_back(*slot); mFreeSlots.erase(slot); if (freedSlots) { freedSlots->push_back(*slot); } } else if (!mFreeBuffers.empty()) { int slot = mFreeBuffers.back(); clearBufferSlotLocked(slot); mUnusedSlots.push_back(slot); mFreeBuffers.pop_back(); if (freedSlots) { freedSlots->push_back(slot); } } else { return false; } Loading
libs/gui/BufferQueueProducer.cpp +248 −143 Original line number Diff line number Diff line Loading @@ -90,7 +90,9 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount( BQ_LOGV("setMaxDequeuedBufferCount: maxDequeuedBuffers = %d", maxDequeuedBuffers); sp<IConsumerListener> listener; sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; std::vector<int> freedSlots; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(); Loading Loading @@ -142,20 +144,26 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount( } int delta = maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount; if (!mCore->adjustAvailableSlotsLocked(delta)) { if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) { return BAD_VALUE; } mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers; VALIDATE_CONSISTENCY(); if (delta < 0) { listener = mCore->mConsumerListener; consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; } mCore->mDequeueCondition.broadcast(); } // Autolock scope // Call back without lock held if (listener != NULL) { listener->onBuffersReleased(); if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { for (int i : freedSlots) { producerListener->onSlotFreed(i); } } return NO_ERROR; Loading @@ -165,7 +173,9 @@ status_t BufferQueueProducer::setAsyncMode(bool async) { ATRACE_CALL(); BQ_LOGV("setAsyncMode: async = %d", async); sp<IConsumerListener> listener; sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; std::vector<int> freedSlots; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(); Loading @@ -191,7 +201,7 @@ status_t BufferQueueProducer::setAsyncMode(bool async) { mCore->mDequeueBufferCannotBlock, mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked(); if (!mCore->adjustAvailableSlotsLocked(delta)) { if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) { BQ_LOGE("setAsyncMode: BufferQueue failed to adjust the number of " "available slots. Delta = %d", delta); return BAD_VALUE; Loading @@ -199,12 +209,20 @@ status_t BufferQueueProducer::setAsyncMode(bool async) { mCore->mAsyncMode = async; VALIDATE_CONSISTENCY(); mCore->mDequeueCondition.broadcast(); listener = mCore->mConsumerListener; if (delta < 0) { consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; } } // Autolock scope // Call back without lock held if (listener != NULL) { listener->onBuffersReleased(); if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { for (int i : freedSlots) { producerListener->onSlotFreed(i); } } return NO_ERROR; } Loading Loading @@ -361,6 +379,9 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; bool attachedByConsumer = false; sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; int found = BufferItem::INVALID_BUFFER_SLOT; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(); Loading @@ -378,7 +399,6 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, height = mCore->mDefaultHeight; } int found = BufferItem::INVALID_BUFFER_SLOT; while (found == BufferItem::INVALID_BUFFER_SLOT) { status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue, &found); Loading Loading @@ -408,6 +428,8 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, mCore->mFreeSlots.insert(found); mCore->clearBufferSlotLocked(found); found = BufferItem::INVALID_BUFFER_SLOT; consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; continue; } } Loading Loading @@ -444,6 +466,10 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, if ((buffer == NULL) || buffer->needsReallocation(width, height, format, usage)) { if (buffer != NULL) { consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; } mSlots[found].mAcquireCalled = false; mSlots[found].mGraphicBuffer = NULL; mSlots[found].mRequestBufferCalled = false; Loading Loading @@ -531,6 +557,14 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot, mSlots[*outSlot].mFrameNumber, mSlots[*outSlot].mGraphicBuffer->handle, returnFlags); // Call back without lock held if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { producerListener->onSlotFreed(found); } return returnFlags; } Loading @@ -538,6 +572,10 @@ status_t BufferQueueProducer::detachBuffer(int slot) { ATRACE_CALL(); ATRACE_BUFFER_INDEX(slot); BQ_LOGV("detachBuffer: slot %d", slot); sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; { Mutex::Autolock lock(mCore->mMutex); if (mCore->mIsAbandoned) { Loading @@ -551,7 +589,8 @@ status_t BufferQueueProducer::detachBuffer(int slot) { } if (mCore->mSingleBufferMode || mCore->mSingleBufferSlot == slot) { BQ_LOGE("detachBuffer: cannot detach a buffer in single buffer mode"); BQ_LOGE("detachBuffer: cannot detach a buffer in single buffer " "mode"); return BAD_VALUE; } Loading @@ -575,6 +614,17 @@ status_t BufferQueueProducer::detachBuffer(int slot) { mCore->clearBufferSlotLocked(slot); mCore->mDequeueCondition.broadcast(); VALIDATE_CONSISTENCY(); producerListener = mCore->mConnectedProducerListener; consumerListener = mCore->mConsumerListener; } // Call back without lock held if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { producerListener->onSlotFreed(slot); } return NO_ERROR; } Loading @@ -591,8 +641,11 @@ status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, return BAD_VALUE; } sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; int found = BufferQueueCore::INVALID_BUFFER_SLOT; { Mutex::Autolock lock(mCore->mMutex); if (mCore->mIsAbandoned) { BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned"); return NO_INIT; Loading @@ -615,7 +668,7 @@ status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, return NO_MEMORY; } int found = mCore->mFreeBuffers.front(); found = mCore->mFreeBuffers.front(); mCore->mFreeBuffers.remove(found); mCore->mFreeSlots.insert(found); Loading @@ -625,6 +678,17 @@ status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, *outFence = mSlots[found].mFence; mCore->clearBufferSlotLocked(found); VALIDATE_CONSISTENCY(); consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; } // Call back without lock held if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { producerListener->onSlotFreed(found); } return NO_ERROR; } Loading Loading @@ -1020,6 +1084,11 @@ int BufferQueueProducer::query(int what, int *outValue) { status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, int api, bool producerControlledByApp, QueueBufferOutput *output) { ATRACE_CALL(); int status = NO_ERROR; sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; std::vector<int> freedSlots; { Mutex::Autolock lock(mCore->mMutex); mConsumerName = mCore->mConsumerName; BQ_LOGV("connect: api=%d producerControlledByApp=%s", api, Loading @@ -1046,18 +1115,19 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, return BAD_VALUE; } bool dequeueBufferCannotBlock = mDequeueTimeout < 0 ? mCore->mConsumerControlledByApp && producerControlledByApp : false; int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, mDequeueTimeout < 0 ? mCore->mConsumerControlledByApp && producerControlledByApp : false, mCore->mMaxBufferCount) - dequeueBufferCannotBlock, mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked(); if (!mCore->adjustAvailableSlotsLocked(delta)) { BQ_LOGE("connect: BufferQueue failed to adjust the number of available " "slots. Delta = %d", delta); if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) { BQ_LOGE("connect: BufferQueue failed to adjust the number of " "available slots. Delta = %d", delta); return BAD_VALUE; } int status = NO_ERROR; switch (api) { case NATIVE_WINDOW_API_EGL: case NATIVE_WINDOW_API_CPU: Loading @@ -1071,7 +1141,8 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, // Set up a death notification so that we can disconnect // automatically if the remote producer dies if (listener != NULL && IInterface::asBinder(listener)->remoteBinder() != NULL) { IInterface::asBinder(listener)->remoteBinder() != NULL) { status = IInterface::asBinder(listener)->linkToDeath( static_cast<IBinder::DeathRecipient*>(this)); if (status != NO_ERROR) { Loading @@ -1088,14 +1159,27 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, } mCore->mBufferHasBeenQueued = false; mCore->mDequeueBufferCannotBlock = false; if (mDequeueTimeout < 0) { mCore->mDequeueBufferCannotBlock = mCore->mConsumerControlledByApp && producerControlledByApp; } mCore->mDequeueBufferCannotBlock = dequeueBufferCannotBlock; mCore->mAllowAllocation = true; VALIDATE_CONSISTENCY(); if (delta < 0) { consumerListener = mCore->mConsumerListener; producerListener = listener; } } // Call back without lock held if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { for (int i : freedSlots) { producerListener->onSlotFreed(i); } } return status; } Loading Loading @@ -1313,12 +1397,16 @@ status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) { ATRACE_CALL(); BQ_LOGV("setDequeueTimeout: %" PRId64, timeout); sp<IConsumerListener> consumerListener; sp<IProducerListener> producerListener; std::vector<int> freedSlots; { Mutex::Autolock lock(mCore->mMutex); int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false, mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked(); if (!mCore->adjustAvailableSlotsLocked(delta)) { BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of " "available slots. Delta = %d", delta); if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) { BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number" " of available slots. Delta = %d", delta); return BAD_VALUE; } Loading @@ -1326,6 +1414,23 @@ status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) { mCore->mDequeueBufferCannotBlock = false; VALIDATE_CONSISTENCY(); if (delta < 0) { consumerListener = mCore->mConsumerListener; producerListener = mCore->mConnectedProducerListener; } } // Call back without lock held if (consumerListener != NULL) { consumerListener->onBuffersReleased(); } if (producerListener != NULL) { for (int i : freedSlots) { producerListener->onSlotFreed(i); } } return NO_ERROR; } Loading