Skip to content

Commit 10fcdbe

Browse files
Jim ShargoAndroid (Google) Code Review
authored andcommitted
Merge changes I374aa204,I0df872b9 into main
* changes: libgui: Add unlimited slot support to Surfaces and Consumers libgui: Add support for unlimited slot BufferQueues
2 parents 8703fd8 + 4f9c275 commit 10fcdbe

30 files changed

Lines changed: 1121 additions & 86 deletions

libs/gui/BufferQueue.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,15 @@ void BufferQueue::ProxyConsumerListener::onSetFrameRate(float frameRate, int8_t
108108
}
109109
#endif
110110

111+
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
112+
void BufferQueue::ProxyConsumerListener::onSlotCountChanged(int slotCount) {
113+
sp<ConsumerListener> listener(mConsumerListener.promote());
114+
if (listener != nullptr) {
115+
listener->onSlotCountChanged(slotCount);
116+
}
117+
}
118+
#endif
119+
111120
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
112121
sp<IGraphicBufferConsumer>* outConsumer,
113122
bool consumerIsSurfaceFlinger) {

libs/gui/BufferQueueConsumer.cpp

Lines changed: 90 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -341,9 +341,9 @@ status_t BufferQueueConsumer::detachBuffer(int slot) {
341341
return BAD_VALUE;
342342
}
343343

344-
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
345-
BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
346-
slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
344+
const int totalSlotCount = mCore->getTotalSlotCountLocked();
345+
if (slot < 0 || slot >= totalSlotCount) {
346+
BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount);
347347
return BAD_VALUE;
348348
} else if (!mSlots[slot].mBufferState.isAcquired()) {
349349
BQ_LOGE("detachBuffer: slot %d is not owned by the consumer "
@@ -483,10 +483,13 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
483483
ATRACE_CALL();
484484
ATRACE_BUFFER_INDEX(slot);
485485

486-
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS ||
487-
releaseFence == nullptr) {
488-
BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot,
489-
releaseFence.get());
486+
const int totalSlotCount = mCore->getTotalSlotCountLocked();
487+
if (slot < 0 || slot >= totalSlotCount) {
488+
BQ_LOGE("releaseBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount);
489+
return BAD_VALUE;
490+
}
491+
if (releaseFence == nullptr) {
492+
BQ_LOGE("releaseBuffer: slot %d fence %p NULL", slot, releaseFence.get());
490493
return BAD_VALUE;
491494
}
492495

@@ -515,6 +518,13 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
515518
{ // Autolock scope
516519
std::lock_guard<std::mutex> lock(mCore->mMutex);
517520

521+
const int totalSlotCount = mCore->getTotalSlotCountLocked();
522+
if (slot < 0 || slot >= totalSlotCount || releaseFence == nullptr) {
523+
BQ_LOGE("releaseBuffer: slot %d out of range [0, %d) or fence %p NULL", slot,
524+
totalSlotCount, releaseFence.get());
525+
return BAD_VALUE;
526+
}
527+
518528
// If the frame number has changed because the buffer has been reallocated,
519529
// we can ignore this releaseBuffer for the old buffer.
520530
// Ignore this for the shared buffer where the frame number can easily
@@ -661,6 +671,43 @@ status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) {
661671
return NO_ERROR;
662672
}
663673

674+
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
675+
status_t BufferQueueConsumer::getReleasedBuffersExtended(std::vector<bool>* outSlotMask) {
676+
ATRACE_CALL();
677+
678+
if (outSlotMask == nullptr) {
679+
BQ_LOGE("getReleasedBuffersExtended: outSlotMask may not be NULL");
680+
return BAD_VALUE;
681+
}
682+
683+
std::lock_guard<std::mutex> lock(mCore->mMutex);
684+
685+
if (mCore->mIsAbandoned) {
686+
BQ_LOGE("getReleasedBuffersExtended: BufferQueue has been abandoned");
687+
return NO_INIT;
688+
}
689+
690+
const int totalSlotCount = mCore->getTotalSlotCountLocked();
691+
outSlotMask->resize(totalSlotCount);
692+
for (int s = 0; s < totalSlotCount; ++s) {
693+
(*outSlotMask)[s] = !mSlots[s].mAcquireCalled;
694+
}
695+
696+
// Remove from the mask queued buffers for which acquire has been called,
697+
// since the consumer will not receive their buffer addresses and so must
698+
// retain their cached information
699+
BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
700+
while (current != mCore->mQueue.end()) {
701+
if (current->mAcquireCalled) {
702+
(*outSlotMask)[current->mSlot] = false;
703+
}
704+
++current;
705+
}
706+
707+
return NO_ERROR;
708+
}
709+
#endif
710+
664711
status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width,
665712
uint32_t height) {
666713
ATRACE_CALL();
@@ -679,6 +726,28 @@ status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width,
679726
return NO_ERROR;
680727
}
681728

729+
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
730+
status_t BufferQueueConsumer::allowUnlimitedSlots(bool allowUnlimitedSlots) {
731+
ATRACE_CALL();
732+
BQ_LOGV("allowUnlimitedSlots: %d", allowUnlimitedSlots);
733+
std::lock_guard<std::mutex> lock(mCore->mMutex);
734+
735+
if (mCore->mIsAbandoned) {
736+
BQ_LOGE("allowUnlimitedSlots: BufferQueue has been abandoned");
737+
return NO_INIT;
738+
}
739+
740+
if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
741+
BQ_LOGE("allowUnlimitedSlots: BufferQueue already connected");
742+
return INVALID_OPERATION;
743+
}
744+
745+
mCore->mAllowExtendedSlotCount = allowUnlimitedSlots;
746+
747+
return OK;
748+
}
749+
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
750+
682751
status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) {
683752
ATRACE_CALL();
684753

@@ -718,16 +787,23 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
718787
int maxAcquiredBuffers) {
719788
ATRACE_FORMAT("%s(%d)", __func__, maxAcquiredBuffers);
720789

721-
if (maxAcquiredBuffers < 1 ||
722-
maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) {
723-
BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d",
724-
maxAcquiredBuffers);
725-
return BAD_VALUE;
726-
}
727-
728790
sp<IConsumerListener> listener;
729791
{ // Autolock scope
730792
std::unique_lock<std::mutex> lock(mCore->mMutex);
793+
794+
// We reserve two slots in order to guarantee that the producer and
795+
// consumer can run asynchronously.
796+
int maxMaxAcquiredBuffers =
797+
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
798+
mCore->getTotalSlotCountLocked() - 2;
799+
#else
800+
BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS;
801+
#endif
802+
if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > maxMaxAcquiredBuffers) {
803+
BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d", maxAcquiredBuffers);
804+
return BAD_VALUE;
805+
}
806+
731807
mCore->waitWhileAllocatingLocked(lock);
732808

733809
if (mCore->mIsAbandoned) {

libs/gui/BufferQueueCore.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838

3939
#include <system/window.h>
4040

41+
#include <ui/BufferQueueDefs.h>
42+
4143
namespace android {
4244

4345
// Macros for include BufferQueueCore information in log messages
@@ -97,7 +99,11 @@ BufferQueueCore::BufferQueueCore()
9799
mConnectedProducerListener(),
98100
mBufferReleasedCbEnabled(false),
99101
mBufferAttachedCbEnabled(false),
102+
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
103+
mSlots(BufferQueueDefs::NUM_BUFFER_SLOTS),
104+
#else
100105
mSlots(),
106+
#endif
101107
mQueue(),
102108
mFreeSlots(),
103109
mFreeBuffers(),
@@ -111,6 +117,9 @@ BufferQueueCore::BufferQueueCore()
111117
mDefaultWidth(1),
112118
mDefaultHeight(1),
113119
mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN),
120+
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
121+
mAllowExtendedSlotCount(false),
122+
#endif
114123
mMaxBufferCount(BufferQueueDefs::NUM_BUFFER_SLOTS),
115124
mMaxAcquiredBufferCount(1),
116125
mMaxDequeuedBufferCount(1),
@@ -221,6 +230,14 @@ void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const
221230
}
222231
}
223232

233+
int BufferQueueCore::getTotalSlotCountLocked() const {
234+
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
235+
return mAllowExtendedSlotCount ? mMaxBufferCount : BufferQueueDefs::NUM_BUFFER_SLOTS;
236+
#else
237+
return BufferQueueDefs::NUM_BUFFER_SLOTS;
238+
#endif
239+
}
240+
224241
int BufferQueueCore::getMinUndequeuedBufferCountLocked() const {
225242
// If dequeueBuffer is allowed to error out, we don't have to add an
226243
// extra buffer.
@@ -253,6 +270,26 @@ int BufferQueueCore::getMaxBufferCountLocked() const {
253270
return maxBufferCount;
254271
}
255272

273+
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
274+
status_t BufferQueueCore::extendSlotCountLocked(int size) {
275+
int previousSize = (int)mSlots.size();
276+
if (previousSize > size) {
277+
return BAD_VALUE;
278+
}
279+
if (previousSize == size) {
280+
return NO_ERROR;
281+
}
282+
283+
mSlots.resize(size);
284+
for (int i = previousSize; i < size; i++) {
285+
mUnusedSlots.push_back(i);
286+
}
287+
288+
mMaxBufferCount = size;
289+
return NO_ERROR;
290+
}
291+
#endif
292+
256293
void BufferQueueCore::clearBufferSlotLocked(int slot) {
257294
BQ_LOGV("clearBufferSlotLocked: slot %d", slot);
258295

@@ -383,7 +420,7 @@ void BufferQueueCore::notifyBufferReleased() const {
383420
void BufferQueueCore::validateConsistencyLocked() const {
384421
static const useconds_t PAUSE_TIME = 0;
385422
int allocatedSlots = 0;
386-
for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
423+
for (int slot = 0; slot < getTotalSlotCountLocked(); ++slot) {
387424
bool isInFreeSlots = mFreeSlots.count(slot) != 0;
388425
bool isInFreeBuffers =
389426
std::find(mFreeBuffers.cbegin(), mFreeBuffers.cend(), slot) !=

libs/gui/BufferQueueProducer.cpp

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <gui/TraceUtils.h>
4141
#include <private/gui/BufferQueueThreadState.h>
4242

43+
#include <utils/Errors.h>
4344
#include <utils/Log.h>
4445
#include <utils/Trace.h>
4546

@@ -108,9 +109,9 @@ status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
108109
return NO_INIT;
109110
}
110111

111-
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
112-
BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)",
113-
slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
112+
int maxSlot = mCore->getTotalSlotCountLocked();
113+
if (slot < 0 || slot >= maxSlot) {
114+
BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", slot, maxSlot);
114115
return BAD_VALUE;
115116
} else if (!mSlots[slot].mBufferState.isDequeued()) {
116117
BQ_LOGE("requestBuffer: slot %d is not owned by the producer "
@@ -123,6 +124,49 @@ status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
123124
return NO_ERROR;
124125
}
125126

127+
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
128+
status_t BufferQueueProducer::extendSlotCount(int size) {
129+
ATRACE_CALL();
130+
131+
sp<IConsumerListener> listener;
132+
{
133+
std::lock_guard<std::mutex> lock(mCore->mMutex);
134+
BQ_LOGV("extendSlotCount: size %d", size);
135+
136+
if (mCore->mIsAbandoned) {
137+
BQ_LOGE("extendSlotCount: BufferQueue has been abandoned");
138+
return NO_INIT;
139+
}
140+
141+
if (!mCore->mAllowExtendedSlotCount) {
142+
BQ_LOGE("extendSlotCount: Consumer did not allow unlimited slots");
143+
return INVALID_OPERATION;
144+
}
145+
146+
int maxBeforeExtension = mCore->mMaxBufferCount;
147+
148+
if (size == maxBeforeExtension) {
149+
return NO_ERROR;
150+
}
151+
152+
if (size < maxBeforeExtension) {
153+
return BAD_VALUE;
154+
}
155+
156+
if (status_t ret = mCore->extendSlotCountLocked(size); ret != OK) {
157+
return ret;
158+
}
159+
listener = mCore->mConsumerListener;
160+
}
161+
162+
if (listener) {
163+
listener->onSlotCountChanged(size);
164+
}
165+
166+
return NO_ERROR;
167+
}
168+
#endif
169+
126170
status_t BufferQueueProducer::setMaxDequeuedBufferCount(
127171
int maxDequeuedBuffers) {
128172
int maxBufferCount;
@@ -170,9 +214,10 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount(int maxDequeuedBuffers,
170214
int bufferCount = mCore->getMinUndequeuedBufferCountLocked();
171215
bufferCount += maxDequeuedBuffers;
172216

173-
if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
217+
if (bufferCount > mCore->getTotalSlotCountLocked()) {
174218
BQ_LOGE("setMaxDequeuedBufferCount: bufferCount %d too large "
175-
"(max %d)", bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS);
219+
"(max %d)",
220+
bufferCount, mCore->getTotalSlotCountLocked());
176221
return BAD_VALUE;
177222
}
178223

@@ -756,9 +801,9 @@ status_t BufferQueueProducer::detachBuffer(int slot) {
756801
return BAD_VALUE;
757802
}
758803

759-
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
760-
BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
761-
slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
804+
const int totalSlotCount = mCore->getTotalSlotCountLocked();
805+
if (slot < 0 || slot >= totalSlotCount) {
806+
BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount);
762807
return BAD_VALUE;
763808
} else if (!mSlots[slot].mBufferState.isDequeued()) {
764809
// TODO(http://b/140581935): This message is BQ_LOGW because it
@@ -993,9 +1038,9 @@ status_t BufferQueueProducer::queueBuffer(int slot,
9931038
return NO_INIT;
9941039
}
9951040

996-
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
997-
BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)",
998-
slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
1041+
const int totalSlotCount = mCore->getTotalSlotCountLocked();
1042+
if (slot < 0 || slot >= totalSlotCount) {
1043+
BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount);
9991044
return BAD_VALUE;
10001045
} else if (!mSlots[slot].mBufferState.isDequeued()) {
10011046
BQ_LOGE("queueBuffer: slot %d is not owned by the producer "
@@ -1239,9 +1284,9 @@ status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
12391284
return BAD_VALUE;
12401285
}
12411286

1242-
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
1243-
BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", slot,
1244-
BufferQueueDefs::NUM_BUFFER_SLOTS);
1287+
const int totalSlotCount = mCore->getTotalSlotCountLocked();
1288+
if (slot < 0 || slot >= totalSlotCount) {
1289+
BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, totalSlotCount);
12451290
return BAD_VALUE;
12461291
} else if (!mSlots[slot].mBufferState.isDequeued()) {
12471292
BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
@@ -1409,6 +1454,9 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
14091454
output->nextFrameNumber = mCore->mFrameCounter + 1;
14101455
output->bufferReplaced = false;
14111456
output->maxBufferCount = mCore->mMaxBufferCount;
1457+
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
1458+
output->isSlotExpansionAllowed = mCore->mAllowExtendedSlotCount;
1459+
#endif
14121460

14131461
if (listener != nullptr) {
14141462
// Set up a death notification so that we can disconnect

0 commit comments

Comments
 (0)