Skip to content

Commit 89077a0

Browse files
author
Jonah Williams
authored
[Impeller] size vk swapchain to window size. (flutter#50205)
The size the engine recieves from the `AndroidSurfaceVulkanImpeller::OnScreenSurfaceResize` appears to be correct in the case of window rotation. Use this instead of physical surface properties to set the swapchain image size. Querying the physical surface properties seems to have some additional non-deterministic delay. This means that querying the properties during a window rotation will frequently return old values. Fixes flutter/flutter#138780 Fixes flutter/flutter#132708
1 parent 38a81f5 commit 89077a0

18 files changed

+333
-93
lines changed

impeller/playground/backend/vulkan/playground_impl_vk.cc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ PlaygroundImplVK::PlaygroundImplVK(PlaygroundSwitches switches)
8585
return;
8686
}
8787

88+
int width = 0;
89+
int height = 0;
90+
::glfwGetWindowSize(window, &width, &height);
91+
size_ = ISize{width, height};
92+
8893
handle_.reset(window);
8994

9095
ContextVK::Settings context_settings;
@@ -125,7 +130,7 @@ PlaygroundImplVK::PlaygroundImplVK(PlaygroundSwitches switches)
125130

126131
vk::UniqueSurfaceKHR surface{vk_surface, context_vk->GetInstance()};
127132
auto context = context_vk->CreateSurfaceContext();
128-
if (!context->SetWindowSurface(std::move(surface))) {
133+
if (!context->SetWindowSurface(std::move(surface), size_)) {
129134
VALIDATION_LOG << "Could not set up surface for context.";
130135
return;
131136
}
@@ -150,6 +155,14 @@ std::unique_ptr<Surface> PlaygroundImplVK::AcquireSurfaceFrame(
150155
std::shared_ptr<Context> context) {
151156
SurfaceContextVK* surface_context_vk =
152157
reinterpret_cast<SurfaceContextVK*>(context_.get());
158+
159+
int width = 0;
160+
int height = 0;
161+
::glfwGetWindowSize(reinterpret_cast<GLFWwindow*>(handle_.get()), &width,
162+
&height);
163+
size_ = ISize{width, height};
164+
surface_context_vk->UpdateSurfaceSize(ISize{width, height});
165+
153166
return surface_context_vk->AcquireNextSurface();
154167
}
155168

impeller/playground/backend/vulkan/playground_impl_vk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class PlaygroundImplVK final : public PlaygroundImpl {
2727
static void DestroyWindowHandle(WindowHandle handle);
2828
using UniqueHandle = std::unique_ptr<void, decltype(&DestroyWindowHandle)>;
2929
UniqueHandle handle_;
30+
ISize size_ = {1, 1};
3031

3132
// A global Vulkan instance which ensures that the Vulkan library will remain
3233
// loaded throughout the lifetime of the process.

impeller/renderer/backend/vulkan/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ impeller_component("vulkan_unittests") {
1919
"test/mock_vulkan.cc",
2020
"test/mock_vulkan.h",
2121
"test/mock_vulkan_unittests.cc",
22+
"test/swapchain_unittests.cc",
2223
]
2324
deps = [
2425
":vulkan",

impeller/renderer/backend/vulkan/gpu_tracer_vk.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ bool GPUTracerVK::IsEnabled() const {
7676
}
7777

7878
void GPUTracerVK::MarkFrameStart() {
79+
if (!enabled_) {
80+
return;
81+
}
7982
FML_DCHECK(!in_frame_);
8083
in_frame_ = true;
8184
raster_thread_id_ = std::this_thread::get_id();

impeller/renderer/backend/vulkan/surface_context_vk.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "impeller/renderer/backend/vulkan/command_pool_vk.h"
99
#include "impeller/renderer/backend/vulkan/context_vk.h"
1010
#include "impeller/renderer/backend/vulkan/swapchain_vk.h"
11+
#include "impeller/renderer/surface.h"
1112

1213
namespace impeller {
1314

@@ -61,8 +62,9 @@ void SurfaceContextVK::Shutdown() {
6162
parent_->Shutdown();
6263
}
6364

64-
bool SurfaceContextVK::SetWindowSurface(vk::UniqueSurfaceKHR surface) {
65-
auto swapchain = SwapchainVK::Create(parent_, std::move(surface));
65+
bool SurfaceContextVK::SetWindowSurface(vk::UniqueSurfaceKHR surface,
66+
const ISize& size) {
67+
auto swapchain = SwapchainVK::Create(parent_, std::move(surface), size);
6668
if (!swapchain) {
6769
VALIDATION_LOG << "Could not create swapchain.";
6870
return false;
@@ -93,6 +95,10 @@ void SurfaceContextVK::SetSyncPresentation(bool value) {
9395
parent_->SetSyncPresentation(value);
9496
}
9597

98+
void SurfaceContextVK::UpdateSurfaceSize(const ISize& size) const {
99+
swapchain_->UpdateSurfaceSize(size);
100+
}
101+
96102
#ifdef FML_OS_ANDROID
97103

98104
vk::UniqueSurfaceKHR SurfaceContextVK::CreateAndroidSurface(

impeller/renderer/backend/vulkan/surface_context_vk.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,15 @@ class SurfaceContextVK : public Context,
7272
// |Context|
7373
void SetSyncPresentation(bool value) override;
7474

75-
[[nodiscard]] bool SetWindowSurface(vk::UniqueSurfaceKHR surface);
75+
[[nodiscard]] bool SetWindowSurface(vk::UniqueSurfaceKHR surface,
76+
const ISize& size);
7677

7778
std::unique_ptr<Surface> AcquireNextSurface();
7879

80+
/// @brief Mark the current swapchain configuration as dirty, forcing it to be
81+
/// recreated on the next frame.
82+
void UpdateSurfaceSize(const ISize& size) const;
83+
7984
#ifdef FML_OS_ANDROID
8085
vk::UniqueSurfaceKHR CreateAndroidSurface(ANativeWindow* window) const;
8186
#endif // FML_OS_ANDROID

impeller/renderer/backend/vulkan/surface_vk.cc

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "impeller/renderer/backend/vulkan/surface_vk.h"
66

7+
#include "impeller/core/formats.h"
78
#include "impeller/renderer/backend/vulkan/swapchain_image_vk.h"
89
#include "impeller/renderer/backend/vulkan/texture_vk.h"
910
#include "impeller/renderer/surface.h"
@@ -13,30 +14,33 @@ namespace impeller {
1314
std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
1415
const std::shared_ptr<Context>& context,
1516
std::shared_ptr<SwapchainImageVK>& swapchain_image,
16-
SwapCallback swap_callback) {
17+
SwapCallback swap_callback,
18+
bool enable_msaa) {
1719
if (!context || !swapchain_image || !swap_callback) {
1820
return nullptr;
1921
}
2022

21-
TextureDescriptor msaa_tex_desc;
22-
msaa_tex_desc.storage_mode = StorageMode::kDeviceTransient;
23-
msaa_tex_desc.type = TextureType::kTexture2DMultisample;
24-
msaa_tex_desc.sample_count = SampleCount::kCount4;
25-
msaa_tex_desc.format = swapchain_image->GetPixelFormat();
26-
msaa_tex_desc.size = swapchain_image->GetSize();
27-
msaa_tex_desc.usage = static_cast<uint64_t>(TextureUsage::kRenderTarget);
28-
2923
std::shared_ptr<Texture> msaa_tex;
30-
if (!swapchain_image->HasMSAATexture()) {
31-
msaa_tex = context->GetResourceAllocator()->CreateTexture(msaa_tex_desc);
32-
msaa_tex->SetLabel("ImpellerOnscreenColorMSAA");
33-
if (!msaa_tex) {
34-
VALIDATION_LOG << "Could not allocate MSAA color texture.";
35-
return nullptr;
24+
if (enable_msaa) {
25+
TextureDescriptor msaa_tex_desc;
26+
msaa_tex_desc.storage_mode = StorageMode::kDeviceTransient;
27+
msaa_tex_desc.type = TextureType::kTexture2DMultisample;
28+
msaa_tex_desc.sample_count = SampleCount::kCount4;
29+
msaa_tex_desc.format = swapchain_image->GetPixelFormat();
30+
msaa_tex_desc.size = swapchain_image->GetSize();
31+
msaa_tex_desc.usage = static_cast<uint64_t>(TextureUsage::kRenderTarget);
32+
33+
if (!swapchain_image->HasMSAATexture()) {
34+
msaa_tex = context->GetResourceAllocator()->CreateTexture(msaa_tex_desc);
35+
msaa_tex->SetLabel("ImpellerOnscreenColorMSAA");
36+
if (!msaa_tex) {
37+
VALIDATION_LOG << "Could not allocate MSAA color texture.";
38+
return nullptr;
39+
}
40+
swapchain_image->SetMSAATexture(msaa_tex);
41+
} else {
42+
msaa_tex = swapchain_image->GetMSAATexture();
3643
}
37-
swapchain_image->SetMSAATexture(msaa_tex);
38-
} else {
39-
msaa_tex = swapchain_image->GetMSAATexture();
4044
}
4145

4246
TextureDescriptor resolve_tex_desc;
@@ -60,11 +64,16 @@ std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
6064
resolve_tex->SetLabel("ImpellerOnscreenResolve");
6165

6266
ColorAttachment color0;
63-
color0.texture = msaa_tex;
6467
color0.clear_color = Color::DarkSlateGray();
6568
color0.load_action = LoadAction::kClear;
66-
color0.store_action = StoreAction::kMultisampleResolve;
67-
color0.resolve_texture = resolve_tex;
69+
if (enable_msaa) {
70+
color0.texture = msaa_tex;
71+
color0.store_action = StoreAction::kMultisampleResolve;
72+
color0.resolve_texture = resolve_tex;
73+
} else {
74+
color0.texture = resolve_tex;
75+
color0.store_action = StoreAction::kStore;
76+
}
6877

6978
RenderTarget render_target_desc;
7079
render_target_desc.SetColorAttachment(color0, 0u);

impeller/renderer/backend/vulkan/surface_vk.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class SurfaceVK final : public Surface {
2121
static std::unique_ptr<SurfaceVK> WrapSwapchainImage(
2222
const std::shared_ptr<Context>& context,
2323
std::shared_ptr<SwapchainImageVK>& swapchain_image,
24-
SwapCallback swap_callback);
24+
SwapCallback swap_callback,
25+
bool enable_msaa = true);
2526

2627
// |Surface|
2728
~SurfaceVK() override;

impeller/renderer/backend/vulkan/swapchain_image_vk.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_SWAPCHAIN_IMAGE_VK_H_
66
#define FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_SWAPCHAIN_IMAGE_VK_H_
77

8-
#include "flutter/fml/macros.h"
98
#include "impeller/geometry/size.h"
109
#include "impeller/renderer/backend/vulkan/formats_vk.h"
1110
#include "impeller/renderer/backend/vulkan/texture_source_vk.h"

impeller/renderer/backend/vulkan/swapchain_impl_vk.cc

Lines changed: 19 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -145,17 +145,18 @@ static std::optional<vk::Queue> ChoosePresentQueue(
145145
std::shared_ptr<SwapchainImplVK> SwapchainImplVK::Create(
146146
const std::shared_ptr<Context>& context,
147147
vk::UniqueSurfaceKHR surface,
148-
vk::SwapchainKHR old_swapchain,
149-
vk::SurfaceTransformFlagBitsKHR last_transform) {
148+
const ISize& size,
149+
bool enable_msaa,
150+
vk::SwapchainKHR old_swapchain) {
150151
return std::shared_ptr<SwapchainImplVK>(new SwapchainImplVK(
151-
context, std::move(surface), old_swapchain, last_transform));
152+
context, std::move(surface), size, enable_msaa, old_swapchain));
152153
}
153154

154-
SwapchainImplVK::SwapchainImplVK(
155-
const std::shared_ptr<Context>& context,
156-
vk::UniqueSurfaceKHR surface,
157-
vk::SwapchainKHR old_swapchain,
158-
vk::SurfaceTransformFlagBitsKHR last_transform) {
155+
SwapchainImplVK::SwapchainImplVK(const std::shared_ptr<Context>& context,
156+
vk::UniqueSurfaceKHR surface,
157+
const ISize& size,
158+
bool enable_msaa,
159+
vk::SwapchainKHR old_swapchain) {
159160
if (!context) {
160161
VALIDATION_LOG << "Cannot create a swapchain without a context.";
161162
return;
@@ -209,10 +210,10 @@ SwapchainImplVK::SwapchainImplVK(
209210
swapchain_info.imageColorSpace = format.value().colorSpace;
210211
swapchain_info.presentMode = vk::PresentModeKHR::eFifo;
211212
swapchain_info.imageExtent = vk::Extent2D{
212-
std::clamp(surface_caps.currentExtent.width,
213+
std::clamp(static_cast<uint32_t>(size.width),
213214
surface_caps.minImageExtent.width,
214215
surface_caps.maxImageExtent.width),
215-
std::clamp(surface_caps.currentExtent.height,
216+
std::clamp(static_cast<uint32_t>(size.height),
216217
surface_caps.minImageExtent.height,
217218
surface_caps.maxImageExtent.height),
218219
};
@@ -304,14 +305,19 @@ SwapchainImplVK::SwapchainImplVK(
304305
images_ = std::move(swapchain_images);
305306
synchronizers_ = std::move(synchronizers);
306307
current_frame_ = synchronizers_.size() - 1u;
308+
size_ = size;
309+
enable_msaa_ = enable_msaa;
307310
is_valid_ = true;
308-
transform_if_changed_discard_swapchain_ = last_transform;
309311
}
310312

311313
SwapchainImplVK::~SwapchainImplVK() {
312314
DestroySwapchain();
313315
}
314316

317+
const ISize& SwapchainImplVK::GetSize() const {
318+
return size_;
319+
}
320+
315321
bool SwapchainImplVK::IsValid() const {
316322
return is_valid_;
317323
}
@@ -337,10 +343,6 @@ vk::Format SwapchainImplVK::GetSurfaceFormat() const {
337343
return surface_format_;
338344
}
339345

340-
vk::SurfaceTransformFlagBitsKHR SwapchainImplVK::GetLastTransform() const {
341-
return transform_if_changed_discard_swapchain_;
342-
}
343-
344346
std::shared_ptr<Context> SwapchainImplVK::GetContext() const {
345347
return context_.lock();
346348
}
@@ -365,26 +367,6 @@ SwapchainImplVK::AcquireResult SwapchainImplVK::AcquireNextDrawable() {
365367
return SwapchainImplVK::AcquireResult{};
366368
}
367369

368-
//----------------------------------------------------------------------------
369-
/// Poll to see if the orientation has changed.
370-
///
371-
/// https://developer.android.com/games/optimize/vulkan-prerotation#using_polling
372-
current_transform_poll_count_++;
373-
if (current_transform_poll_count_ >= kPollFramesForOrientation) {
374-
current_transform_poll_count_ = 0u;
375-
auto [caps_result, caps] =
376-
context.GetPhysicalDevice().getSurfaceCapabilitiesKHR(*surface_);
377-
if (caps_result != vk::Result::eSuccess) {
378-
VALIDATION_LOG << "Could not get surface capabilities: "
379-
<< vk::to_string(caps_result);
380-
return SwapchainImplVK::AcquireResult{};
381-
}
382-
if (caps.currentTransform != transform_if_changed_discard_swapchain_) {
383-
transform_if_changed_discard_swapchain_ = caps.currentTransform;
384-
return AcquireResult{true /* out of date */};
385-
}
386-
}
387-
388370
//----------------------------------------------------------------------------
389371
/// Get the next image index.
390372
///
@@ -430,7 +412,8 @@ SwapchainImplVK::AcquireResult SwapchainImplVK::AcquireNextDrawable() {
430412
return false;
431413
}
432414
return swapchain->Present(image, image_index);
433-
} // swap callback
415+
}, // swap callback
416+
enable_msaa_ //
434417
)};
435418
}
436419

0 commit comments

Comments
 (0)