Cache NATIVE_WINDOW_MAX_BUFFER_COUNT in Surface
To avoid the sync binder call to BufferQueue everytime
vkGetPhysicalDeviceSurfaceCapabilitiesKHR and
GetPhysicalDeviceSurfacePresentModesKHR are called, we cache the
NATIVE_WINDOW_MAX_BUFFER_COUNT at the Surface each time the client
connects.
Bug: 133187007
Test: dEQP-VK.wsi.android.surface#query_present_modes,
libgui_test:BufferQueueTest#GetMaxBufferCountInQueueBufferOutput_Succeeds
Change-Id: I7c1a0e99d73151cd451a2f3cb173f843efd57ce1
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 9c311a3..b9a4749 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -1132,9 +1132,6 @@
case NATIVE_WINDOW_CONSUMER_IS_PROTECTED:
value = static_cast<int32_t>(mCore->mConsumerIsProtected);
break;
- case NATIVE_WINDOW_MAX_BUFFER_COUNT:
- value = static_cast<int32_t>(mCore->mMaxBufferCount);
- break;
default:
return BAD_VALUE;
}
@@ -1199,6 +1196,7 @@
static_cast<uint32_t>(mCore->mQueue.size());
output->nextFrameNumber = mCore->mFrameCounter + 1;
output->bufferReplaced = false;
+ output->maxBufferCount = mCore->mMaxBufferCount;
if (listener != nullptr) {
// Set up a death notification so that we can disconnect
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 0e03b7d..9db0a7c 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -1141,12 +1141,8 @@
// ----------------------------------------------------------------------------
constexpr size_t IGraphicBufferProducer::QueueBufferOutput::minFlattenedSize() {
- return sizeof(width) +
- sizeof(height) +
- sizeof(transformHint) +
- sizeof(numPendingBuffers) +
- sizeof(nextFrameNumber) +
- sizeof(bufferReplaced);
+ return sizeof(width) + sizeof(height) + sizeof(transformHint) + sizeof(numPendingBuffers) +
+ sizeof(nextFrameNumber) + sizeof(bufferReplaced) + sizeof(maxBufferCount);
}
size_t IGraphicBufferProducer::QueueBufferOutput::getFlattenedSize() const {
@@ -1170,6 +1166,7 @@
FlattenableUtils::write(buffer, size, numPendingBuffers);
FlattenableUtils::write(buffer, size, nextFrameNumber);
FlattenableUtils::write(buffer, size, bufferReplaced);
+ FlattenableUtils::write(buffer, size, maxBufferCount);
return frameTimestamps.flatten(buffer, size, fds, count);
}
@@ -1187,6 +1184,7 @@
FlattenableUtils::read(buffer, size, numPendingBuffers);
FlattenableUtils::read(buffer, size, nextFrameNumber);
FlattenableUtils::read(buffer, size, bufferReplaced);
+ FlattenableUtils::read(buffer, size, maxBufferCount);
return frameTimestamps.unflatten(buffer, size, fds, count);
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index e6eb327..2e8a5d0 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -96,6 +96,7 @@
mConnectedToCpu = false;
mProducerControlledByApp = controlledByApp;
mSwapIntervalZero = false;
+ mMaxBufferCount = 0;
}
Surface::~Surface() {
@@ -961,6 +962,10 @@
*value = static_cast<int>(mDataSpace);
return NO_ERROR;
}
+ case NATIVE_WINDOW_MAX_BUFFER_COUNT: {
+ *value = mMaxBufferCount;
+ return NO_ERROR;
+ }
}
}
return mGraphicBufferProducer->query(what, value);
@@ -1298,6 +1303,7 @@
mDefaultWidth = output.width;
mDefaultHeight = output.height;
mNextFrameNumber = output.nextFrameNumber;
+ mMaxBufferCount = output.maxBufferCount;
// Ignore transform hint if sticky transform is set or transform to display inverse flag is
// set. Transform hint should be ignored if the client is expected to always submit buffers
diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h
index 3dde8c8..6e002dd 100644
--- a/libs/gui/include/gui/IGraphicBufferProducer.h
+++ b/libs/gui/include/gui/IGraphicBufferProducer.h
@@ -412,6 +412,7 @@
uint64_t nextFrameNumber{0};
FrameEventHistoryDelta frameTimestamps;
bool bufferReplaced{false};
+ int maxBufferCount{0};
};
virtual status_t queueBuffer(int slot, const QueueBufferInput& input,
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 0c471bb..80469df 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -465,6 +465,7 @@
bool mReportRemovedBuffers = false;
std::vector<sp<GraphicBuffer>> mRemovedBuffers;
+ int mMaxBufferCount;
};
} // namespace android
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 119e888..98dc1e6 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -169,6 +169,18 @@
ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
}
+TEST_F(BufferQueueTest, GetMaxBufferCountInQueueBufferOutput_Succeeds) {
+ createBufferQueue();
+ sp<DummyConsumer> dc(new DummyConsumer);
+ mConsumer->consumerConnect(dc, false);
+ int bufferCount = 50;
+ mConsumer->setMaxBufferCount(bufferCount);
+
+ IGraphicBufferProducer::QueueBufferOutput output;
+ mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, &output);
+ ASSERT_EQ(output.maxBufferCount, bufferCount);
+}
+
TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
createBufferQueue();
sp<DummyConsumer> dc(new DummyConsumer);