[Impeller] Size AHB swapchain based on vk surface properties. (flutter/engine#52692)

Pixel 4 uses 4 images, 7 Pro uses ... 6 actually.

https://github.com/flutter/flutter/issues/147721
This commit is contained in:
Jonah Williams 2024-05-09 10:24:05 -07:00 committed by GitHub
parent 806db3d5b8
commit b40b5418e6
6 changed files with 49 additions and 26 deletions

View File

@ -44,9 +44,11 @@ std::shared_ptr<AHBSwapchainImplVK> AHBSwapchainImplVK::Create(
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 @@ AHBSwapchainImplVK::AHBSwapchainImplVK(
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 @@ vk::UniqueSemaphore AHBSwapchainImplVK::CreateRenderReadySemaphore(
}
const auto& context_vk = ContextVK::Cast(*context);
const auto& device = context_vk.GetDevice();
auto signal_wait = device.createSemaphoreUnique({});

View File

@ -51,7 +51,8 @@ class AHBSwapchainImplVK final
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 @@ class AHBSwapchainImplVK final
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);

View File

@ -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 @@ bool AHBSwapchainVK::IsAvailableOnPlatform() {
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 @@ void AHBSwapchainVK::UpdateSurfaceSize(const ISize& size) {
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;

View File

@ -52,10 +52,12 @@ class AHBSwapchainVK final : public SwapchainVK {
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);
};

View File

@ -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 @@ namespace impeller {
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))) {}

View File

@ -44,6 +44,17 @@ std::shared_ptr<SwapchainVK> SwapchainVK::Create(
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 @@ std::shared_ptr<SwapchainVK> SwapchainVK::Create(
auto ahb_swapchain = std::shared_ptr<AHBSwapchainVK>(new AHBSwapchainVK(
context, //
window.GetHandle(), //
std::move(surface), //
window.GetSize(), //
enable_msaa //
));
@ -65,16 +77,6 @@ std::shared_ptr<SwapchainVK> SwapchainVK::Create(
}
// 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