Fix NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS handling

Fixes: 123541940
Test: CTS HardwareRendererTests#testLotsOfBuffers
Change-Id: I5d96e615f552c4faa0e6dcaaaa828c871eaf6c8e
This commit is contained in:
John Reck
2019-03-28 16:57:38 -07:00
parent cd62e44210
commit ac513c2fde
2 changed files with 23 additions and 8 deletions

View File

@@ -222,7 +222,17 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode,
const SkISize maxSize = SkISize::Make(caps.maxImageExtent.width, caps.maxImageExtent.height);
ComputeWindowSizeAndTransform(&windowInfo, minSize, maxSize);
windowInfo.bufferCount = std::max<uint32_t>(VulkanSurface::sMaxBufferCount, caps.minImageCount);
int query_value;
int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
if (err != 0 || query_value < 0) {
ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err,
query_value);
return nullptr;
}
auto min_undequeued_buffers = static_cast<uint32_t>(query_value);
windowInfo.bufferCount = min_undequeued_buffers
+ std::max(VulkanSurface::sTargetBufferCount, caps.minImageCount);
if (caps.maxImageCount > 0 && windowInfo.bufferCount > caps.maxImageCount) {
// Application must settle for fewer images than desired:
windowInfo.bufferCount = caps.maxImageCount;
@@ -357,10 +367,9 @@ bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& window
return false;
}
// Lower layer insists that we have at least two buffers.
err = native_window_set_buffer_count(window, std::max(2, windowInfo.bufferCount));
err = native_window_set_buffer_count(window, windowInfo.bufferCount);
if (err != 0) {
ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%d) failed: %s (%d)",
ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%zu) failed: %s (%d)",
windowInfo.bufferCount, strerror(-err), err);
return false;
}
@@ -392,7 +401,7 @@ VulkanSurface::~VulkanSurface() {
}
void VulkanSurface::releaseBuffers() {
for (uint32_t i = 0; i < VulkanSurface::sMaxBufferCount; i++) {
for (uint32_t i = 0; i < mWindowInfo.bufferCount; i++) {
VulkanSurface::NativeBufferInfo& bufferInfo = mNativeBuffers[i];
if (bufferInfo.buffer.get() != nullptr && bufferInfo.dequeued) {

View File

@@ -83,14 +83,19 @@ private:
* as private to this class.
*
*/
static constexpr int sMaxBufferCount = 3;
// How many buffers we want to be able to use ourselves. We want 1 in active rendering with
// 1 more queued, so 2. This will be added to NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, which is
// how many buffers the consumer needs (eg, 1 for SurfaceFlinger), getting to a typically
// triple-buffered queue as a result.
static constexpr uint32_t sTargetBufferCount = 2;
struct WindowInfo {
SkISize size;
PixelFormat pixelFormat;
android_dataspace dataspace;
int transform;
int bufferCount;
size_t bufferCount;
uint64_t windowUsageFlags;
// size of the ANativeWindow if the inverse of transform requires us to swap width/height
@@ -111,7 +116,8 @@ private:
const SkISize& maxSize);
void releaseBuffers();
NativeBufferInfo mNativeBuffers[VulkanSurface::sMaxBufferCount];
// TODO: Just use a vector?
NativeBufferInfo mNativeBuffers[android::BufferQueueDefs::NUM_BUFFER_SLOTS];
sp<ANativeWindow> mNativeWindow;
WindowInfo mWindowInfo;