Merge "swapchain: increase the minimal buffer count to 3" into sc-dev
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 8d6681c..2715587 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -537,6 +537,30 @@
     }
 }
 
+int get_min_buffer_count(ANativeWindow* window,
+                         uint32_t* out_min_buffer_count) {
+    constexpr int kExtraBuffers = 2;
+
+    int err;
+    int min_undequeued_buffers;
+    err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
+                        &min_undequeued_buffers);
+    if (err != android::OK || min_undequeued_buffers < 0) {
+        ALOGE(
+            "NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d) "
+            "value=%d",
+            strerror(-err), err, min_undequeued_buffers);
+        if (err == android::OK) {
+            err = android::UNKNOWN_ERROR;
+        }
+        return err;
+    }
+
+    *out_min_buffer_count =
+        static_cast<uint32_t>(min_undequeued_buffers + kExtraBuffers);
+    return android::OK;
+}
+
 }  // anonymous namespace
 
 VKAPI_ATTR
@@ -848,15 +872,13 @@
 
     int err;
     int query_value;
+    uint32_t min_buffer_count;
     ANativeWindow* window = SurfaceFromHandle(surface)->window.get();
 
-    err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
-    if (err != android::OK || query_value < 0) {
-        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d) value=%d",
-              strerror(-err), err, query_value);
+    err = get_min_buffer_count(window, &min_buffer_count);
+    if (err != android::OK) {
         return VK_ERROR_SURFACE_LOST_KHR;
     }
-    uint32_t min_undequeued_buffers = static_cast<uint32_t>(query_value);
 
     err = window->query(window, NATIVE_WINDOW_MAX_BUFFER_COUNT, &query_value);
     if (err != android::OK || query_value < 0) {
@@ -867,7 +889,7 @@
     uint32_t max_buffer_count = static_cast<uint32_t>(query_value);
 
     std::vector<VkPresentModeKHR> present_modes;
-    if (min_undequeued_buffers + 1 < max_buffer_count)
+    if (min_buffer_count < max_buffer_count)
         present_modes.push_back(VK_PRESENT_MODE_MAILBOX_KHR);
     present_modes.push_back(VK_PRESENT_MODE_FIFO_KHR);
 
@@ -1188,19 +1210,14 @@
         }
     }
 
-    int query_value;
-    err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
-                        &query_value);
-    if (err != android::OK || query_value < 0) {
-        ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err,
-              query_value);
+    uint32_t min_buffer_count;
+    err = get_min_buffer_count(window, &min_buffer_count);
+    if (err != android::OK) {
         return VK_ERROR_SURFACE_LOST_KHR;
     }
-    uint32_t min_undequeued_buffers = static_cast<uint32_t>(query_value);
+
     uint32_t num_images =
-        (swap_interval ? create_info->minImageCount
-                       : std::max(3u, create_info->minImageCount)) -
-        1 + min_undequeued_buffers;
+        std::max(min_buffer_count, create_info->minImageCount);
 
     // Lower layer insists that we have at least two buffers. This is wasteful
     // and we'd like to relax it in the shared case, but not all the pieces are