Loading include/gui/IGraphicBufferConsumer.h +11 −2 Original line number Diff line number Diff line Loading @@ -206,17 +206,26 @@ public: virtual status_t setMaxBufferCount(int bufferCount) = 0; // setMaxAcquiredBufferCount sets the maximum number of buffers that can // be acquired by the consumer at one time (default 1). This call will // fail if a producer is connected to the BufferQueue. // be acquired by the consumer at one time (default 1). If this method // succeeds, any new buffer slots will be both unallocated and owned by the // BufferQueue object (i.e. they are not owned by the producer or consumer). // Calling this may also cause some buffer slots to be emptied. // // This function should not be called with a value of maxAcquiredBuffers // that is less than the number of currently acquired buffer slots. Doing so // will result in a BAD_VALUE error. // // maxAcquiredBuffers must be (inclusive) between 1 and // MAX_MAX_ACQUIRED_BUFFERS. It also cannot cause the maxBufferCount value // to be exceeded. // // Return of a value other than NO_ERROR means an error has occurred: // * NO_INIT - the buffer queue has been abandoned // * BAD_VALUE - one of the below conditions occurred: // * maxAcquiredBuffers was out of range (see above). // * failure to adjust the number of available slots. // * client would have more than the requested number of // acquired buffers after this call // * INVALID_OPERATION - attempting to call this after a producer connected. virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) = 0; Loading include/gui/IGraphicBufferProducer.h +11 −9 Original line number Diff line number Diff line Loading @@ -82,15 +82,16 @@ public: virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0; // setMaxDequeuedBufferCount sets the maximum number of buffers that can be // dequeued by the producer at one time. If this method succeeds, buffer // slots will be both unallocated and owned by the BufferQueue object (i.e. // they are not owned by the producer or consumer). Calling this will also // cause all buffer slots to be emptied. If the caller is caching the // dequeued by the producer at one time. If this method succeeds, any new // buffer slots will be both unallocated and owned by the BufferQueue object // (i.e. they are not owned by the producer or consumer). Calling this may // also cause some buffer slots to be emptied. If the caller is caching the // contents of the buffer slots, it should empty that cache after calling // this method. // // This function should not be called when there are any currently dequeued // buffer slots. Doing so will result in a BAD_VALUE error. // This function should not be called with a value of maxDequeuedBuffers // that is less than the number of currently dequeued buffer slots. Doing so // will result in a BAD_VALUE error. // // The buffer count should be at least 1 (inclusive), but at most // (NUM_BUFFER_SLOTS - the minimum undequeued buffer count) (exclusive). The Loading @@ -100,9 +101,10 @@ public: // Return of a value other than NO_ERROR means an error has occurred: // * NO_INIT - the buffer queue has been abandoned. // * BAD_VALUE - one of the below conditions occurred: // * bufferCount was out of range (see above) // * client has too many buffers dequeued // * this call would cause the maxBufferCount value to be exceeded // * bufferCount was out of range (see above). // * client would have more than the requested number of dequeued // buffers after this call. // * this call would cause the maxBufferCount value to be exceeded. // * failure to adjust the number of available slots. virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) = 0; Loading libs/gui/BufferQueueConsumer.cpp +48 −24 Original line number Diff line number Diff line Loading @@ -611,35 +611,59 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( return BAD_VALUE; } sp<IConsumerListener> listener; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(); if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { BQ_LOGE("setMaxAcquiredBufferCount: producer is already connected"); return INVALID_OPERATION; if (mCore->mIsAbandoned) { BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned"); return NO_INIT; } // The new maxAcquiredBuffers count should not be violated by the number // of currently acquired buffers int acquiredCount = 0; for (int slot : mCore->mActiveBuffers) { if (mSlots[slot].mBufferState.isAcquired()) { acquiredCount++; } } if (acquiredCount > maxAcquiredBuffers) { BQ_LOGE("setMaxAcquiredBufferCount: the requested maxAcquiredBuffer" "count (%d) exceeds the current acquired buffer count (%d)", maxAcquiredBuffers, acquiredCount); return BAD_VALUE; } if ((maxAcquiredBuffers + mCore->mMaxDequeuedBufferCount + (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 1 : 0)) > mCore->mMaxBufferCount) { BQ_LOGE("setMaxAcquiredBufferCount: %d acquired buffers would exceed " "the maxBufferCount (%d) (maxDequeued %d async %d)", (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 1 : 0)) > mCore->mMaxBufferCount) { BQ_LOGE("setMaxAcquiredBufferCount: %d acquired buffers would " "exceed the maxBufferCount (%d) (maxDequeued %d async %d)", maxAcquiredBuffers, mCore->mMaxBufferCount, mCore->mMaxDequeuedBufferCount, mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock); return BAD_VALUE; } if (!mCore->adjustAvailableSlotsLocked( maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount)) { BQ_LOGE("setMaxAcquiredBufferCount: BufferQueue failed to adjust the " "number of available slots. Delta = %d", maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount); int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount; if (!mCore->adjustAvailableSlotsLocked(delta)) { return BAD_VALUE; } BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers); mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers; VALIDATE_CONSISTENCY(); if (delta < 0) { listener = mCore->mConsumerListener; } } // Call back without lock held if (listener != NULL) { listener->onBuffersReleased(); } return NO_ERROR; } Loading libs/gui/BufferQueueCore.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,10 @@ void BufferQueueCore::freeAllBuffersLocked() { bool BufferQueueCore::adjustAvailableSlotsLocked(int delta) { if (delta >= 0) { // If we're going to fail, do so before modifying anything if (delta > static_cast<int>(mUnusedSlots.size())) { return false; } while (delta > 0) { if (mUnusedSlots.empty()) { return false; Loading @@ -237,6 +241,11 @@ bool BufferQueueCore::adjustAvailableSlotsLocked(int delta) { delta--; } } else { // If we're going to fail, do so before modifying anything if (-delta > static_cast<int>(mFreeSlots.size() + mFreeBuffers.size())) { return false; } while (delta < 0) { if (!mFreeSlots.empty()) { auto slot = mFreeSlots.begin(); Loading libs/gui/BufferQueueProducer.cpp +15 −13 Original line number Diff line number Diff line Loading @@ -101,13 +101,20 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount( return NO_INIT; } // There must be no dequeued buffers when changing the buffer count. // The new maxDequeuedBuffer count should not be violated by the number // of currently dequeued buffers int dequeuedCount = 0; for (int s : mCore->mActiveBuffers) { if (mSlots[s].mBufferState.isDequeued()) { BQ_LOGE("setMaxDequeuedBufferCount: buffer owned by producer"); return BAD_VALUE; dequeuedCount++; } } if (dequeuedCount > maxDequeuedBuffers) { BQ_LOGE("setMaxDequeuedBufferCount: the requested maxDequeuedBuffer" "count (%d) exceeds the current dequeued buffer count (%d)", maxDequeuedBuffers, dequeuedCount); return BAD_VALUE; } int bufferCount = mCore->getMinUndequeuedBufferCountLocked(); bufferCount += maxDequeuedBuffers; Loading @@ -134,21 +141,16 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount( return BAD_VALUE; } // Here we are guaranteed that the producer doesn't have any dequeued // buffers and will release all of its buffer references. We don't // clear the queue, however, so that currently queued buffers still // get displayed. if (!mCore->adjustAvailableSlotsLocked( maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount)) { BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue failed to adjust " "the number of available slots. Delta = %d", maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount); int delta = maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount; if (!mCore->adjustAvailableSlotsLocked(delta)) { return BAD_VALUE; } mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers; VALIDATE_CONSISTENCY(); mCore->mDequeueCondition.broadcast(); if (delta < 0) { listener = mCore->mConsumerListener; } mCore->mDequeueCondition.broadcast(); } // Autolock scope // Call back without lock held Loading Loading
include/gui/IGraphicBufferConsumer.h +11 −2 Original line number Diff line number Diff line Loading @@ -206,17 +206,26 @@ public: virtual status_t setMaxBufferCount(int bufferCount) = 0; // setMaxAcquiredBufferCount sets the maximum number of buffers that can // be acquired by the consumer at one time (default 1). This call will // fail if a producer is connected to the BufferQueue. // be acquired by the consumer at one time (default 1). If this method // succeeds, any new buffer slots will be both unallocated and owned by the // BufferQueue object (i.e. they are not owned by the producer or consumer). // Calling this may also cause some buffer slots to be emptied. // // This function should not be called with a value of maxAcquiredBuffers // that is less than the number of currently acquired buffer slots. Doing so // will result in a BAD_VALUE error. // // maxAcquiredBuffers must be (inclusive) between 1 and // MAX_MAX_ACQUIRED_BUFFERS. It also cannot cause the maxBufferCount value // to be exceeded. // // Return of a value other than NO_ERROR means an error has occurred: // * NO_INIT - the buffer queue has been abandoned // * BAD_VALUE - one of the below conditions occurred: // * maxAcquiredBuffers was out of range (see above). // * failure to adjust the number of available slots. // * client would have more than the requested number of // acquired buffers after this call // * INVALID_OPERATION - attempting to call this after a producer connected. virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) = 0; Loading
include/gui/IGraphicBufferProducer.h +11 −9 Original line number Diff line number Diff line Loading @@ -82,15 +82,16 @@ public: virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0; // setMaxDequeuedBufferCount sets the maximum number of buffers that can be // dequeued by the producer at one time. If this method succeeds, buffer // slots will be both unallocated and owned by the BufferQueue object (i.e. // they are not owned by the producer or consumer). Calling this will also // cause all buffer slots to be emptied. If the caller is caching the // dequeued by the producer at one time. If this method succeeds, any new // buffer slots will be both unallocated and owned by the BufferQueue object // (i.e. they are not owned by the producer or consumer). Calling this may // also cause some buffer slots to be emptied. If the caller is caching the // contents of the buffer slots, it should empty that cache after calling // this method. // // This function should not be called when there are any currently dequeued // buffer slots. Doing so will result in a BAD_VALUE error. // This function should not be called with a value of maxDequeuedBuffers // that is less than the number of currently dequeued buffer slots. Doing so // will result in a BAD_VALUE error. // // The buffer count should be at least 1 (inclusive), but at most // (NUM_BUFFER_SLOTS - the minimum undequeued buffer count) (exclusive). The Loading @@ -100,9 +101,10 @@ public: // Return of a value other than NO_ERROR means an error has occurred: // * NO_INIT - the buffer queue has been abandoned. // * BAD_VALUE - one of the below conditions occurred: // * bufferCount was out of range (see above) // * client has too many buffers dequeued // * this call would cause the maxBufferCount value to be exceeded // * bufferCount was out of range (see above). // * client would have more than the requested number of dequeued // buffers after this call. // * this call would cause the maxBufferCount value to be exceeded. // * failure to adjust the number of available slots. virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) = 0; Loading
libs/gui/BufferQueueConsumer.cpp +48 −24 Original line number Diff line number Diff line Loading @@ -611,35 +611,59 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( return BAD_VALUE; } sp<IConsumerListener> listener; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(); if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { BQ_LOGE("setMaxAcquiredBufferCount: producer is already connected"); return INVALID_OPERATION; if (mCore->mIsAbandoned) { BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned"); return NO_INIT; } // The new maxAcquiredBuffers count should not be violated by the number // of currently acquired buffers int acquiredCount = 0; for (int slot : mCore->mActiveBuffers) { if (mSlots[slot].mBufferState.isAcquired()) { acquiredCount++; } } if (acquiredCount > maxAcquiredBuffers) { BQ_LOGE("setMaxAcquiredBufferCount: the requested maxAcquiredBuffer" "count (%d) exceeds the current acquired buffer count (%d)", maxAcquiredBuffers, acquiredCount); return BAD_VALUE; } if ((maxAcquiredBuffers + mCore->mMaxDequeuedBufferCount + (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 1 : 0)) > mCore->mMaxBufferCount) { BQ_LOGE("setMaxAcquiredBufferCount: %d acquired buffers would exceed " "the maxBufferCount (%d) (maxDequeued %d async %d)", (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 1 : 0)) > mCore->mMaxBufferCount) { BQ_LOGE("setMaxAcquiredBufferCount: %d acquired buffers would " "exceed the maxBufferCount (%d) (maxDequeued %d async %d)", maxAcquiredBuffers, mCore->mMaxBufferCount, mCore->mMaxDequeuedBufferCount, mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock); return BAD_VALUE; } if (!mCore->adjustAvailableSlotsLocked( maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount)) { BQ_LOGE("setMaxAcquiredBufferCount: BufferQueue failed to adjust the " "number of available slots. Delta = %d", maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount); int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount; if (!mCore->adjustAvailableSlotsLocked(delta)) { return BAD_VALUE; } BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers); mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers; VALIDATE_CONSISTENCY(); if (delta < 0) { listener = mCore->mConsumerListener; } } // Call back without lock held if (listener != NULL) { listener->onBuffersReleased(); } return NO_ERROR; } Loading
libs/gui/BufferQueueCore.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,10 @@ void BufferQueueCore::freeAllBuffersLocked() { bool BufferQueueCore::adjustAvailableSlotsLocked(int delta) { if (delta >= 0) { // If we're going to fail, do so before modifying anything if (delta > static_cast<int>(mUnusedSlots.size())) { return false; } while (delta > 0) { if (mUnusedSlots.empty()) { return false; Loading @@ -237,6 +241,11 @@ bool BufferQueueCore::adjustAvailableSlotsLocked(int delta) { delta--; } } else { // If we're going to fail, do so before modifying anything if (-delta > static_cast<int>(mFreeSlots.size() + mFreeBuffers.size())) { return false; } while (delta < 0) { if (!mFreeSlots.empty()) { auto slot = mFreeSlots.begin(); Loading
libs/gui/BufferQueueProducer.cpp +15 −13 Original line number Diff line number Diff line Loading @@ -101,13 +101,20 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount( return NO_INIT; } // There must be no dequeued buffers when changing the buffer count. // The new maxDequeuedBuffer count should not be violated by the number // of currently dequeued buffers int dequeuedCount = 0; for (int s : mCore->mActiveBuffers) { if (mSlots[s].mBufferState.isDequeued()) { BQ_LOGE("setMaxDequeuedBufferCount: buffer owned by producer"); return BAD_VALUE; dequeuedCount++; } } if (dequeuedCount > maxDequeuedBuffers) { BQ_LOGE("setMaxDequeuedBufferCount: the requested maxDequeuedBuffer" "count (%d) exceeds the current dequeued buffer count (%d)", maxDequeuedBuffers, dequeuedCount); return BAD_VALUE; } int bufferCount = mCore->getMinUndequeuedBufferCountLocked(); bufferCount += maxDequeuedBuffers; Loading @@ -134,21 +141,16 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount( return BAD_VALUE; } // Here we are guaranteed that the producer doesn't have any dequeued // buffers and will release all of its buffer references. We don't // clear the queue, however, so that currently queued buffers still // get displayed. if (!mCore->adjustAvailableSlotsLocked( maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount)) { BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue failed to adjust " "the number of available slots. Delta = %d", maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount); int delta = maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount; if (!mCore->adjustAvailableSlotsLocked(delta)) { return BAD_VALUE; } mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers; VALIDATE_CONSISTENCY(); mCore->mDequeueCondition.broadcast(); if (delta < 0) { listener = mCore->mConsumerListener; } mCore->mDequeueCondition.broadcast(); } // Autolock scope // Call back without lock held Loading