[Impeller] Size AHB swapchain based on vk surface properties. (#52692)
Pixel 4 uses 4 images, 7 Pro uses ... 6 actually.
https://github.com/flutter/flutter/issues/147721
diff --git a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.cc b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.cc
index 0212d0c..b50972e 100644
--- a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.cc
+++ b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.cc
@@ -44,9 +44,11 @@
const std::weak_ptr<Context>& context,
std::weak_ptr<android::SurfaceControl> surface_control,
const ISize& size,
- bool enable_msaa) {
- auto impl = std::shared_ptr<AHBSwapchainImplVK>(new AHBSwapchainImplVK(
- context, std::move(surface_control), size, enable_msaa));
+ bool enable_msaa,
+ size_t swapchain_image_count) {
+ auto impl = std::shared_ptr<AHBSwapchainImplVK>(
+ new AHBSwapchainImplVK(context, std::move(surface_control), size,
+ enable_msaa, swapchain_image_count));
return impl->IsValid() ? impl : nullptr;
}
@@ -54,11 +56,13 @@
const std::weak_ptr<Context>& context,
std::weak_ptr<android::SurfaceControl> surface_control,
const ISize& size,
- bool enable_msaa)
+ bool enable_msaa,
+ size_t swapchain_image_count)
: surface_control_(std::move(surface_control)),
pending_presents_(std::make_shared<fml::Semaphore>(kMaxPendingPresents)) {
desc_ = android::HardwareBufferDescriptor::MakeForSwapchainImage(size);
- pool_ = std::make_shared<AHBTexturePoolVK>(context, desc_);
+ pool_ =
+ std::make_shared<AHBTexturePoolVK>(context, desc_, swapchain_image_count);
if (!pool_->IsValid()) {
return;
}
@@ -245,7 +249,6 @@
}
const auto& context_vk = ContextVK::Cast(*context);
-
const auto& device = context_vk.GetDevice();
auto signal_wait = device.createSemaphoreUnique({});
diff --git a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.h b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.h
index f865efc..72979cb 100644
--- a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.h
+++ b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.h
@@ -51,7 +51,8 @@
const std::weak_ptr<Context>& context,
std::weak_ptr<android::SurfaceControl> surface_control,
const ISize& size,
- bool enable_msaa);
+ bool enable_msaa,
+ size_t swapchain_image_count);
~AHBSwapchainImplVK();
@@ -107,7 +108,8 @@
const std::weak_ptr<Context>& context,
std::weak_ptr<android::SurfaceControl> surface_control,
const ISize& size,
- bool enable_msaa);
+ bool enable_msaa,
+ size_t swapchain_image_count);
bool Present(const AutoSemaSignaler& signaler,
const std::shared_ptr<AHBTextureSourceVK>& texture);
diff --git a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.cc b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.cc
index 2532a36..ad805a0 100644
--- a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.cc
+++ b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.cc
@@ -5,8 +5,10 @@
#include "impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h"
#include "flutter/fml/trace_event.h"
+#include "impeller/renderer/backend/vulkan/context_vk.h"
#include "impeller/renderer/backend/vulkan/formats_vk.h"
#include "impeller/renderer/backend/vulkan/swapchain/ahb/ahb_formats.h"
+#include "third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan_enums.hpp"
namespace impeller {
@@ -17,12 +19,26 @@
AHBSwapchainVK::AHBSwapchainVK(const std::shared_ptr<Context>& context,
ANativeWindow* window,
+ vk::UniqueSurfaceKHR surface,
const ISize& size,
bool enable_msaa)
: context_(context),
surface_control_(
std::make_shared<android::SurfaceControl>(window, "ImpellerSurface")),
enable_msaa_(enable_msaa) {
+ const auto [caps_result, surface_caps] =
+ ContextVK::Cast(*context).GetPhysicalDevice().getSurfaceCapabilitiesKHR(
+ *surface);
+ if (caps_result == vk::Result::eSuccess) {
+ swapchain_image_count_ =
+ std::clamp(surface_caps.minImageCount + 1u, // preferred image count
+ surface_caps.minImageCount, // min count cannot be zero
+ surface_caps.maxImageCount == 0u
+ ? surface_caps.minImageCount + 1u
+ : surface_caps.maxImageCount // max zero means no limit
+ );
+ }
+
UpdateSurfaceSize(size);
}
@@ -56,10 +72,11 @@
return;
}
TRACE_EVENT0("impeller", __FUNCTION__);
- auto impl = AHBSwapchainImplVK::Create(context_, //
- surface_control_, //
- size, //
- enable_msaa_ //
+ auto impl = AHBSwapchainImplVK::Create(context_, //
+ surface_control_, //
+ size, //
+ enable_msaa_, //
+ swapchain_image_count_ //
);
if (!impl || !impl->IsValid()) {
VALIDATION_LOG << "Could not resize swapchain to size: " << size;
diff --git a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h
index b95e1c2..a3b330f 100644
--- a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h
+++ b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h
@@ -52,10 +52,12 @@
std::weak_ptr<Context> context_;
std::shared_ptr<android::SurfaceControl> surface_control_;
const bool enable_msaa_;
+ size_t swapchain_image_count_ = 3u;
std::shared_ptr<AHBSwapchainImplVK> impl_;
explicit AHBSwapchainVK(const std::shared_ptr<Context>& context,
ANativeWindow* window,
+ vk::UniqueSurfaceKHR surface,
const ISize& size,
bool enable_msaa);
};
diff --git a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_texture_pool_vk.h b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_texture_pool_vk.h
index 19429ad..f6d3840 100644
--- a/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_texture_pool_vk.h
+++ b/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_texture_pool_vk.h
@@ -9,7 +9,6 @@
#include "flutter/fml/unique_fd.h"
#include "impeller/base/thread.h"
-#include "impeller/base/timing.h"
#include "impeller/renderer/backend/vulkan/android/ahb_texture_source_vk.h"
namespace impeller {
@@ -30,14 +29,12 @@
class AHBTexturePoolVK {
public:
struct PoolEntry {
- TimePoint last_access_time;
std::shared_ptr<AHBTextureSourceVK> texture;
std::shared_ptr<fml::UniqueFD> render_ready_fence;
explicit PoolEntry(std::shared_ptr<AHBTextureSourceVK> p_item,
fml::UniqueFD p_render_ready_fence = {})
- : last_access_time(Clock::now()),
- texture(std::move(p_item)),
+ : texture(std::move(p_item)),
render_ready_fence(std::make_shared<fml::UniqueFD>(
std::move(p_render_ready_fence))) {}
diff --git a/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc b/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc
index 70e9553..a777e66 100644
--- a/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc
+++ b/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc
@@ -44,6 +44,17 @@
return nullptr;
}
+ vk::AndroidSurfaceCreateInfoKHR surface_info;
+ surface_info.setWindow(window.GetHandle());
+ auto [result, surface] =
+ ContextVK::Cast(*context).GetInstance().createAndroidSurfaceKHRUnique(
+ surface_info);
+ if (result != vk::Result::eSuccess) {
+ VALIDATION_LOG << "Could not create KHR Android Surface: "
+ << vk::to_string(result);
+ return nullptr;
+ }
+
// TODO(147533): AHB swapchains on emulators are not functional.
const auto emulator = ContextVK::Cast(*context).GetDriverInfo()->IsEmulator();
@@ -52,6 +63,7 @@
auto ahb_swapchain = std::shared_ptr<AHBSwapchainVK>(new AHBSwapchainVK(
context, //
window.GetHandle(), //
+ std::move(surface), //
window.GetSize(), //
enable_msaa //
));
@@ -65,16 +77,6 @@
}
// Fallback to KHR swapchains if AHB swapchains aren't available.
- vk::AndroidSurfaceCreateInfoKHR surface_info;
- surface_info.setWindow(window.GetHandle());
- auto [result, surface] =
- ContextVK::Cast(*context).GetInstance().createAndroidSurfaceKHRUnique(
- surface_info);
- if (result != vk::Result::eSuccess) {
- VALIDATION_LOG << "Could not create KHR Android Surface: "
- << vk::to_string(result);
- return nullptr;
- }
return Create(context, std::move(surface), window.GetSize(), enable_msaa);
}
#endif // FML_OS_ANDROID