Loading include/android/system_health.h +23 −25 Original line number Diff line number Diff line Loading @@ -81,10 +81,10 @@ typedef struct AGpuHeadroomParams AGpuHeadroomParams; * * @return A new instance of ACpuHeadroomParams. */ ACpuHeadroomParams *_Nonnull ACpuHeadroomParams_create() ACpuHeadroomParams* _Nonnull ACpuHeadroomParams_create(void) __INTRODUCED_IN(36); enum ACpuHeadroomCalculationType { typedef enum ACpuHeadroomCalculationType : int32_t { /** * Use the minimum headroom value within the calculation window. * Introduced in API level 36. Loading @@ -95,10 +95,9 @@ enum ACpuHeadroomCalculationType { * Introduced in API level 36. */ ACPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1, }; typedef enum ACpuHeadroomCalculationType ACpuHeadroomCalculationType; } ACpuHeadroomCalculationType; enum AGpuHeadroomCalculationType { typedef enum AGpuHeadroomCalculationType : int32_t { /** * Use the minimum headroom value within the calculation window. * Introduced in API level 36. Loading @@ -109,8 +108,7 @@ enum AGpuHeadroomCalculationType { * Introduced in API level 36. */ AGPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1, }; typedef enum AGpuHeadroomCalculationType AGpuHeadroomCalculationType; } AGpuHeadroomCalculationType; /** * Sets the headroom calculation window size in ACpuHeadroomParams. Loading Loading @@ -238,7 +236,7 @@ __INTRODUCED_IN(36); * * @return A new instance of AGpuHeadroomParams. */ AGpuHeadroomParams *_Nonnull AGpuHeadroomParams_create() AGpuHeadroomParams* _Nonnull AGpuHeadroomParams_create(void) __INTRODUCED_IN(36); /** Loading libs/gui/BufferQueue.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,15 @@ void BufferQueue::ProxyConsumerListener::onSetFrameRate(float frameRate, int8_t } #endif #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) void BufferQueue::ProxyConsumerListener::onSlotCountChanged(int slotCount) { sp<ConsumerListener> listener(mConsumerListener.promote()); if (listener != nullptr) { listener->onSlotCountChanged(slotCount); } } #endif void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer, sp<IGraphicBufferConsumer>* outConsumer, bool consumerIsSurfaceFlinger) { Loading libs/gui/BufferQueueConsumer.cpp +90 −14 Original line number Diff line number Diff line Loading @@ -341,9 +341,9 @@ status_t BufferQueueConsumer::detachBuffer(int slot) { return BAD_VALUE; } if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", slot, BufferQueueDefs::NUM_BUFFER_SLOTS); const int totalSlotCount = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= totalSlotCount) { BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isAcquired()) { BQ_LOGE("detachBuffer: slot %d is not owned by the consumer " Loading Loading @@ -483,10 +483,13 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, ATRACE_CALL(); ATRACE_BUFFER_INDEX(slot); if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS || releaseFence == nullptr) { BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot, releaseFence.get()); const int totalSlotCount = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= totalSlotCount) { BQ_LOGE("releaseBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } if (releaseFence == nullptr) { BQ_LOGE("releaseBuffer: slot %d fence %p NULL", slot, releaseFence.get()); return BAD_VALUE; } Loading Loading @@ -515,6 +518,13 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, { // Autolock scope std::lock_guard<std::mutex> lock(mCore->mMutex); const int totalSlotCount = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= totalSlotCount || releaseFence == nullptr) { BQ_LOGE("releaseBuffer: slot %d out of range [0, %d) or fence %p NULL", slot, totalSlotCount, releaseFence.get()); return BAD_VALUE; } // If the frame number has changed because the buffer has been reallocated, // we can ignore this releaseBuffer for the old buffer. // Ignore this for the shared buffer where the frame number can easily Loading Loading @@ -661,6 +671,43 @@ status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) { return NO_ERROR; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) status_t BufferQueueConsumer::getReleasedBuffersExtended(std::vector<bool>* outSlotMask) { ATRACE_CALL(); if (outSlotMask == nullptr) { BQ_LOGE("getReleasedBuffersExtended: outSlotMask may not be NULL"); return BAD_VALUE; } std::lock_guard<std::mutex> lock(mCore->mMutex); if (mCore->mIsAbandoned) { BQ_LOGE("getReleasedBuffersExtended: BufferQueue has been abandoned"); return NO_INIT; } const int totalSlotCount = mCore->getTotalSlotCountLocked(); outSlotMask->resize(totalSlotCount); for (int s = 0; s < totalSlotCount; ++s) { (*outSlotMask)[s] = !mSlots[s].mAcquireCalled; } // Remove from the mask queued buffers for which acquire has been called, // since the consumer will not receive their buffer addresses and so must // retain their cached information BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin()); while (current != mCore->mQueue.end()) { if (current->mAcquireCalled) { (*outSlotMask)[current->mSlot] = false; } ++current; } return NO_ERROR; } #endif status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width, uint32_t height) { ATRACE_CALL(); Loading @@ -679,6 +726,28 @@ status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width, return NO_ERROR; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) status_t BufferQueueConsumer::allowUnlimitedSlots(bool allowUnlimitedSlots) { ATRACE_CALL(); BQ_LOGV("allowUnlimitedSlots: %d", allowUnlimitedSlots); std::lock_guard<std::mutex> lock(mCore->mMutex); if (mCore->mIsAbandoned) { BQ_LOGE("allowUnlimitedSlots: BufferQueue has been abandoned"); return NO_INIT; } if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { BQ_LOGE("allowUnlimitedSlots: BufferQueue already connected"); return INVALID_OPERATION; } mCore->mAllowExtendedSlotCount = allowUnlimitedSlots; return OK; } #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) { ATRACE_CALL(); Loading Loading @@ -718,16 +787,23 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( int maxAcquiredBuffers) { ATRACE_FORMAT("%s(%d)", __func__, maxAcquiredBuffers); if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) { BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d", maxAcquiredBuffers); return BAD_VALUE; } sp<IConsumerListener> listener; { // Autolock scope std::unique_lock<std::mutex> lock(mCore->mMutex); // We reserve two slots in order to guarantee that the producer and // consumer can run asynchronously. int maxMaxAcquiredBuffers = #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) mCore->getTotalSlotCountLocked() - 2; #else BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS; #endif if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > maxMaxAcquiredBuffers) { BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d", maxAcquiredBuffers); return BAD_VALUE; } mCore->waitWhileAllocatingLocked(lock); if (mCore->mIsAbandoned) { Loading libs/gui/BufferQueueCore.cpp +38 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ #include <system/window.h> #include <ui/BufferQueueDefs.h> namespace android { // Macros for include BufferQueueCore information in log messages Loading Loading @@ -97,7 +99,11 @@ BufferQueueCore::BufferQueueCore() mConnectedProducerListener(), mBufferReleasedCbEnabled(false), mBufferAttachedCbEnabled(false), #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) mSlots(BufferQueueDefs::NUM_BUFFER_SLOTS), #else mSlots(), #endif mQueue(), mFreeSlots(), mFreeBuffers(), Loading @@ -111,6 +117,9 @@ BufferQueueCore::BufferQueueCore() mDefaultWidth(1), mDefaultHeight(1), mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN), #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) mAllowExtendedSlotCount(false), #endif mMaxBufferCount(BufferQueueDefs::NUM_BUFFER_SLOTS), mMaxAcquiredBufferCount(1), mMaxDequeuedBufferCount(1), Loading Loading @@ -221,6 +230,14 @@ void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const } } int BufferQueueCore::getTotalSlotCountLocked() const { #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) return mAllowExtendedSlotCount ? mMaxBufferCount : BufferQueueDefs::NUM_BUFFER_SLOTS; #else return BufferQueueDefs::NUM_BUFFER_SLOTS; #endif } int BufferQueueCore::getMinUndequeuedBufferCountLocked() const { // If dequeueBuffer is allowed to error out, we don't have to add an // extra buffer. Loading Loading @@ -253,6 +270,26 @@ int BufferQueueCore::getMaxBufferCountLocked() const { return maxBufferCount; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) status_t BufferQueueCore::extendSlotCountLocked(int size) { int previousSize = (int)mSlots.size(); if (previousSize > size) { return BAD_VALUE; } if (previousSize == size) { return NO_ERROR; } mSlots.resize(size); for (int i = previousSize; i < size; i++) { mUnusedSlots.push_back(i); } mMaxBufferCount = size; return NO_ERROR; } #endif void BufferQueueCore::clearBufferSlotLocked(int slot) { BQ_LOGV("clearBufferSlotLocked: slot %d", slot); Loading Loading @@ -383,7 +420,7 @@ void BufferQueueCore::notifyBufferReleased() const { void BufferQueueCore::validateConsistencyLocked() const { static const useconds_t PAUSE_TIME = 0; int allocatedSlots = 0; for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) { for (int slot = 0; slot < getTotalSlotCountLocked(); ++slot) { bool isInFreeSlots = mFreeSlots.count(slot) != 0; bool isInFreeBuffers = std::find(mFreeBuffers.cbegin(), mFreeBuffers.cend(), slot) != Loading libs/gui/BufferQueueProducer.cpp +62 −14 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include <gui/TraceUtils.h> #include <private/gui/BufferQueueThreadState.h> #include <utils/Errors.h> #include <utils/Log.h> #include <utils/Trace.h> Loading Loading @@ -108,9 +109,9 @@ status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { return NO_INIT; } if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", slot, BufferQueueDefs::NUM_BUFFER_SLOTS); int maxSlot = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= maxSlot) { BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", slot, maxSlot); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { BQ_LOGE("requestBuffer: slot %d is not owned by the producer " Loading @@ -123,6 +124,49 @@ status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { return NO_ERROR; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) status_t BufferQueueProducer::extendSlotCount(int size) { ATRACE_CALL(); sp<IConsumerListener> listener; { std::lock_guard<std::mutex> lock(mCore->mMutex); BQ_LOGV("extendSlotCount: size %d", size); if (mCore->mIsAbandoned) { BQ_LOGE("extendSlotCount: BufferQueue has been abandoned"); return NO_INIT; } if (!mCore->mAllowExtendedSlotCount) { BQ_LOGE("extendSlotCount: Consumer did not allow unlimited slots"); return INVALID_OPERATION; } int maxBeforeExtension = mCore->mMaxBufferCount; if (size == maxBeforeExtension) { return NO_ERROR; } if (size < maxBeforeExtension) { return BAD_VALUE; } if (status_t ret = mCore->extendSlotCountLocked(size); ret != OK) { return ret; } listener = mCore->mConsumerListener; } if (listener) { listener->onSlotCountChanged(size); } return NO_ERROR; } #endif status_t BufferQueueProducer::setMaxDequeuedBufferCount( int maxDequeuedBuffers) { int maxBufferCount; Loading Loading @@ -170,9 +214,10 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount(int maxDequeuedBuffers, int bufferCount = mCore->getMinUndequeuedBufferCountLocked(); bufferCount += maxDequeuedBuffers; if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) { if (bufferCount > mCore->getTotalSlotCountLocked()) { BQ_LOGE("setMaxDequeuedBufferCount: bufferCount %d too large " "(max %d)", bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS); "(max %d)", bufferCount, mCore->getTotalSlotCountLocked()); return BAD_VALUE; } Loading Loading @@ -756,9 +801,9 @@ status_t BufferQueueProducer::detachBuffer(int slot) { return BAD_VALUE; } if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", slot, BufferQueueDefs::NUM_BUFFER_SLOTS); const int totalSlotCount = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= totalSlotCount) { BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { // TODO(http://b/140581935): This message is BQ_LOGW because it Loading Loading @@ -993,9 +1038,9 @@ status_t BufferQueueProducer::queueBuffer(int slot, return NO_INIT; } if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", slot, BufferQueueDefs::NUM_BUFFER_SLOTS); const int totalSlotCount = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= totalSlotCount) { BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { BQ_LOGE("queueBuffer: slot %d is not owned by the producer " Loading Loading @@ -1239,9 +1284,9 @@ status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { return BAD_VALUE; } if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, BufferQueueDefs::NUM_BUFFER_SLOTS); const int totalSlotCount = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= totalSlotCount) { BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " Loading Loading @@ -1409,6 +1454,9 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, output->nextFrameNumber = mCore->mFrameCounter + 1; output->bufferReplaced = false; output->maxBufferCount = mCore->mMaxBufferCount; #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) output->isSlotExpansionAllowed = mCore->mAllowExtendedSlotCount; #endif if (listener != nullptr) { // Set up a death notification so that we can disconnect Loading Loading
include/android/system_health.h +23 −25 Original line number Diff line number Diff line Loading @@ -81,10 +81,10 @@ typedef struct AGpuHeadroomParams AGpuHeadroomParams; * * @return A new instance of ACpuHeadroomParams. */ ACpuHeadroomParams *_Nonnull ACpuHeadroomParams_create() ACpuHeadroomParams* _Nonnull ACpuHeadroomParams_create(void) __INTRODUCED_IN(36); enum ACpuHeadroomCalculationType { typedef enum ACpuHeadroomCalculationType : int32_t { /** * Use the minimum headroom value within the calculation window. * Introduced in API level 36. Loading @@ -95,10 +95,9 @@ enum ACpuHeadroomCalculationType { * Introduced in API level 36. */ ACPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1, }; typedef enum ACpuHeadroomCalculationType ACpuHeadroomCalculationType; } ACpuHeadroomCalculationType; enum AGpuHeadroomCalculationType { typedef enum AGpuHeadroomCalculationType : int32_t { /** * Use the minimum headroom value within the calculation window. * Introduced in API level 36. Loading @@ -109,8 +108,7 @@ enum AGpuHeadroomCalculationType { * Introduced in API level 36. */ AGPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1, }; typedef enum AGpuHeadroomCalculationType AGpuHeadroomCalculationType; } AGpuHeadroomCalculationType; /** * Sets the headroom calculation window size in ACpuHeadroomParams. Loading Loading @@ -238,7 +236,7 @@ __INTRODUCED_IN(36); * * @return A new instance of AGpuHeadroomParams. */ AGpuHeadroomParams *_Nonnull AGpuHeadroomParams_create() AGpuHeadroomParams* _Nonnull AGpuHeadroomParams_create(void) __INTRODUCED_IN(36); /** Loading
libs/gui/BufferQueue.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,15 @@ void BufferQueue::ProxyConsumerListener::onSetFrameRate(float frameRate, int8_t } #endif #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) void BufferQueue::ProxyConsumerListener::onSlotCountChanged(int slotCount) { sp<ConsumerListener> listener(mConsumerListener.promote()); if (listener != nullptr) { listener->onSlotCountChanged(slotCount); } } #endif void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer, sp<IGraphicBufferConsumer>* outConsumer, bool consumerIsSurfaceFlinger) { Loading
libs/gui/BufferQueueConsumer.cpp +90 −14 Original line number Diff line number Diff line Loading @@ -341,9 +341,9 @@ status_t BufferQueueConsumer::detachBuffer(int slot) { return BAD_VALUE; } if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", slot, BufferQueueDefs::NUM_BUFFER_SLOTS); const int totalSlotCount = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= totalSlotCount) { BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isAcquired()) { BQ_LOGE("detachBuffer: slot %d is not owned by the consumer " Loading Loading @@ -483,10 +483,13 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, ATRACE_CALL(); ATRACE_BUFFER_INDEX(slot); if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS || releaseFence == nullptr) { BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot, releaseFence.get()); const int totalSlotCount = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= totalSlotCount) { BQ_LOGE("releaseBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } if (releaseFence == nullptr) { BQ_LOGE("releaseBuffer: slot %d fence %p NULL", slot, releaseFence.get()); return BAD_VALUE; } Loading Loading @@ -515,6 +518,13 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, { // Autolock scope std::lock_guard<std::mutex> lock(mCore->mMutex); const int totalSlotCount = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= totalSlotCount || releaseFence == nullptr) { BQ_LOGE("releaseBuffer: slot %d out of range [0, %d) or fence %p NULL", slot, totalSlotCount, releaseFence.get()); return BAD_VALUE; } // If the frame number has changed because the buffer has been reallocated, // we can ignore this releaseBuffer for the old buffer. // Ignore this for the shared buffer where the frame number can easily Loading Loading @@ -661,6 +671,43 @@ status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) { return NO_ERROR; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) status_t BufferQueueConsumer::getReleasedBuffersExtended(std::vector<bool>* outSlotMask) { ATRACE_CALL(); if (outSlotMask == nullptr) { BQ_LOGE("getReleasedBuffersExtended: outSlotMask may not be NULL"); return BAD_VALUE; } std::lock_guard<std::mutex> lock(mCore->mMutex); if (mCore->mIsAbandoned) { BQ_LOGE("getReleasedBuffersExtended: BufferQueue has been abandoned"); return NO_INIT; } const int totalSlotCount = mCore->getTotalSlotCountLocked(); outSlotMask->resize(totalSlotCount); for (int s = 0; s < totalSlotCount; ++s) { (*outSlotMask)[s] = !mSlots[s].mAcquireCalled; } // Remove from the mask queued buffers for which acquire has been called, // since the consumer will not receive their buffer addresses and so must // retain their cached information BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin()); while (current != mCore->mQueue.end()) { if (current->mAcquireCalled) { (*outSlotMask)[current->mSlot] = false; } ++current; } return NO_ERROR; } #endif status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width, uint32_t height) { ATRACE_CALL(); Loading @@ -679,6 +726,28 @@ status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width, return NO_ERROR; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) status_t BufferQueueConsumer::allowUnlimitedSlots(bool allowUnlimitedSlots) { ATRACE_CALL(); BQ_LOGV("allowUnlimitedSlots: %d", allowUnlimitedSlots); std::lock_guard<std::mutex> lock(mCore->mMutex); if (mCore->mIsAbandoned) { BQ_LOGE("allowUnlimitedSlots: BufferQueue has been abandoned"); return NO_INIT; } if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { BQ_LOGE("allowUnlimitedSlots: BufferQueue already connected"); return INVALID_OPERATION; } mCore->mAllowExtendedSlotCount = allowUnlimitedSlots; return OK; } #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) { ATRACE_CALL(); Loading Loading @@ -718,16 +787,23 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount( int maxAcquiredBuffers) { ATRACE_FORMAT("%s(%d)", __func__, maxAcquiredBuffers); if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) { BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d", maxAcquiredBuffers); return BAD_VALUE; } sp<IConsumerListener> listener; { // Autolock scope std::unique_lock<std::mutex> lock(mCore->mMutex); // We reserve two slots in order to guarantee that the producer and // consumer can run asynchronously. int maxMaxAcquiredBuffers = #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) mCore->getTotalSlotCountLocked() - 2; #else BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS; #endif if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > maxMaxAcquiredBuffers) { BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d", maxAcquiredBuffers); return BAD_VALUE; } mCore->waitWhileAllocatingLocked(lock); if (mCore->mIsAbandoned) { Loading
libs/gui/BufferQueueCore.cpp +38 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ #include <system/window.h> #include <ui/BufferQueueDefs.h> namespace android { // Macros for include BufferQueueCore information in log messages Loading Loading @@ -97,7 +99,11 @@ BufferQueueCore::BufferQueueCore() mConnectedProducerListener(), mBufferReleasedCbEnabled(false), mBufferAttachedCbEnabled(false), #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) mSlots(BufferQueueDefs::NUM_BUFFER_SLOTS), #else mSlots(), #endif mQueue(), mFreeSlots(), mFreeBuffers(), Loading @@ -111,6 +117,9 @@ BufferQueueCore::BufferQueueCore() mDefaultWidth(1), mDefaultHeight(1), mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN), #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) mAllowExtendedSlotCount(false), #endif mMaxBufferCount(BufferQueueDefs::NUM_BUFFER_SLOTS), mMaxAcquiredBufferCount(1), mMaxDequeuedBufferCount(1), Loading Loading @@ -221,6 +230,14 @@ void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const } } int BufferQueueCore::getTotalSlotCountLocked() const { #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) return mAllowExtendedSlotCount ? mMaxBufferCount : BufferQueueDefs::NUM_BUFFER_SLOTS; #else return BufferQueueDefs::NUM_BUFFER_SLOTS; #endif } int BufferQueueCore::getMinUndequeuedBufferCountLocked() const { // If dequeueBuffer is allowed to error out, we don't have to add an // extra buffer. Loading Loading @@ -253,6 +270,26 @@ int BufferQueueCore::getMaxBufferCountLocked() const { return maxBufferCount; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) status_t BufferQueueCore::extendSlotCountLocked(int size) { int previousSize = (int)mSlots.size(); if (previousSize > size) { return BAD_VALUE; } if (previousSize == size) { return NO_ERROR; } mSlots.resize(size); for (int i = previousSize; i < size; i++) { mUnusedSlots.push_back(i); } mMaxBufferCount = size; return NO_ERROR; } #endif void BufferQueueCore::clearBufferSlotLocked(int slot) { BQ_LOGV("clearBufferSlotLocked: slot %d", slot); Loading Loading @@ -383,7 +420,7 @@ void BufferQueueCore::notifyBufferReleased() const { void BufferQueueCore::validateConsistencyLocked() const { static const useconds_t PAUSE_TIME = 0; int allocatedSlots = 0; for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) { for (int slot = 0; slot < getTotalSlotCountLocked(); ++slot) { bool isInFreeSlots = mFreeSlots.count(slot) != 0; bool isInFreeBuffers = std::find(mFreeBuffers.cbegin(), mFreeBuffers.cend(), slot) != Loading
libs/gui/BufferQueueProducer.cpp +62 −14 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include <gui/TraceUtils.h> #include <private/gui/BufferQueueThreadState.h> #include <utils/Errors.h> #include <utils/Log.h> #include <utils/Trace.h> Loading Loading @@ -108,9 +109,9 @@ status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { return NO_INIT; } if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", slot, BufferQueueDefs::NUM_BUFFER_SLOTS); int maxSlot = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= maxSlot) { BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", slot, maxSlot); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { BQ_LOGE("requestBuffer: slot %d is not owned by the producer " Loading @@ -123,6 +124,49 @@ status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { return NO_ERROR; } #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) status_t BufferQueueProducer::extendSlotCount(int size) { ATRACE_CALL(); sp<IConsumerListener> listener; { std::lock_guard<std::mutex> lock(mCore->mMutex); BQ_LOGV("extendSlotCount: size %d", size); if (mCore->mIsAbandoned) { BQ_LOGE("extendSlotCount: BufferQueue has been abandoned"); return NO_INIT; } if (!mCore->mAllowExtendedSlotCount) { BQ_LOGE("extendSlotCount: Consumer did not allow unlimited slots"); return INVALID_OPERATION; } int maxBeforeExtension = mCore->mMaxBufferCount; if (size == maxBeforeExtension) { return NO_ERROR; } if (size < maxBeforeExtension) { return BAD_VALUE; } if (status_t ret = mCore->extendSlotCountLocked(size); ret != OK) { return ret; } listener = mCore->mConsumerListener; } if (listener) { listener->onSlotCountChanged(size); } return NO_ERROR; } #endif status_t BufferQueueProducer::setMaxDequeuedBufferCount( int maxDequeuedBuffers) { int maxBufferCount; Loading Loading @@ -170,9 +214,10 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount(int maxDequeuedBuffers, int bufferCount = mCore->getMinUndequeuedBufferCountLocked(); bufferCount += maxDequeuedBuffers; if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) { if (bufferCount > mCore->getTotalSlotCountLocked()) { BQ_LOGE("setMaxDequeuedBufferCount: bufferCount %d too large " "(max %d)", bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS); "(max %d)", bufferCount, mCore->getTotalSlotCountLocked()); return BAD_VALUE; } Loading Loading @@ -756,9 +801,9 @@ status_t BufferQueueProducer::detachBuffer(int slot) { return BAD_VALUE; } if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", slot, BufferQueueDefs::NUM_BUFFER_SLOTS); const int totalSlotCount = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= totalSlotCount) { BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { // TODO(http://b/140581935): This message is BQ_LOGW because it Loading Loading @@ -993,9 +1038,9 @@ status_t BufferQueueProducer::queueBuffer(int slot, return NO_INIT; } if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", slot, BufferQueueDefs::NUM_BUFFER_SLOTS); const int totalSlotCount = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= totalSlotCount) { BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { BQ_LOGE("queueBuffer: slot %d is not owned by the producer " Loading Loading @@ -1239,9 +1284,9 @@ status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { return BAD_VALUE; } if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, BufferQueueDefs::NUM_BUFFER_SLOTS); const int totalSlotCount = mCore->getTotalSlotCountLocked(); if (slot < 0 || slot >= totalSlotCount) { BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " Loading Loading @@ -1409,6 +1454,9 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, output->nextFrameNumber = mCore->mFrameCounter + 1; output->bufferReplaced = false; output->maxBufferCount = mCore->mMaxBufferCount; #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS) output->isSlotExpansionAllowed = mCore->mAllowExtendedSlotCount; #endif if (listener != nullptr) { // Set up a death notification so that we can disconnect Loading