Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 17cb2ef

Browse files
Aleksey BekkerAleksey Bekker
authored andcommitted
Windows: Prevent platform thread from deadlocking during window resize
1 parent 5635566 commit 17cb2ef

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

shell/platform/windows/flutter_windows_view.cc

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,29 @@
1313

1414
namespace flutter {
1515

16+
namespace {
17+
// The maximum duration to block the platform thread for while waiting
18+
// for a window resize operation to complete.
19+
constexpr std::chrono::milliseconds kWindowResizeTimeout{100};
20+
1621
/// Returns true if the surface will be updated as part of the resize process.
1722
///
1823
/// This is called on window resize to determine if the platform thread needs
1924
/// to be blocked until the frame with the right size has been rendered. It
2025
/// should be kept in-sync with how the engine deals with a new surface request
2126
/// as seen in `CreateOrUpdateSurface` in `GPUSurfaceGL`.
22-
static bool SurfaceWillUpdate(size_t cur_width,
23-
size_t cur_height,
24-
size_t target_width,
25-
size_t target_height) {
27+
bool SurfaceWillUpdate(size_t cur_width,
28+
size_t cur_height,
29+
size_t target_width,
30+
size_t target_height) {
2631
// TODO (https://github.com/flutter/flutter/issues/65061) : Avoid special
2732
// handling for zero dimensions.
2833
bool non_zero_target_dims = target_height > 0 && target_width > 0;
2934
bool not_same_size =
3035
(cur_height != target_height) || (cur_width != target_width);
3136
return non_zero_target_dims && not_same_size;
3237
}
38+
} // namespace
3339

3440
FlutterWindowsView::FlutterWindowsView(
3541
std::unique_ptr<WindowBindingHandler> window_binding) {
@@ -150,9 +156,10 @@ void FlutterWindowsView::OnWindowSizeChanged(size_t width, size_t height) {
150156
// Block the platform thread until:
151157
// 1. GetFrameBufferId is called with the right frame size.
152158
// 2. Any pending SwapBuffers calls have been invoked.
153-
resize_cv_.wait(lock, [&resize_status = resize_status_] {
154-
return resize_status == ResizeState::kDone;
155-
});
159+
resize_cv_.wait_for(lock, kWindowResizeTimeout,
160+
[&resize_status = resize_status_] {
161+
return resize_status == ResizeState::kDone;
162+
});
156163
}
157164
}
158165

shell/platform/windows/flutter_windows_view_unittests.cc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <comutil.h>
99
#include <oleacc.h>
1010

11+
#include <future>
1112
#include <iostream>
1213
#include <vector>
1314

@@ -546,5 +547,35 @@ TEST(FlutterWindowsViewTest, AccessibilityHitTesting) {
546547
EXPECT_EQ(varchild.pdispVal, node3_delegate->GetNativeViewAccessible());
547548
}
548549

550+
TEST(FlutterWindowsViewTest, WindowResizeTests) {
551+
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
552+
EngineModifier modifier(engine.get());
553+
554+
auto window_binding_handler =
555+
std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
556+
557+
FlutterWindowsView view(std::move(window_binding_handler));
558+
view.SetEngine(std::move(engine));
559+
560+
bool send_window_metrics_event_called = false;
561+
modifier.embedder_api().SendWindowMetricsEvent = MOCK_ENGINE_PROC(
562+
SendWindowMetricsEvent,
563+
([&send_window_metrics_event_called](
564+
auto engine, const FlutterWindowMetricsEvent* even) {
565+
send_window_metrics_event_called = true;
566+
return kSuccess;
567+
}));
568+
569+
std::promise<bool> resize_completed;
570+
std::thread([&resize_completed, &view]() {
571+
view.OnWindowSizeChanged(500, 500);
572+
resize_completed.set_value(true);
573+
}).detach();
574+
575+
auto result = resize_completed.get_future().wait_for(std::chrono::seconds(1));
576+
EXPECT_EQ(std::future_status::ready, result);
577+
EXPECT_TRUE(send_window_metrics_event_called);
578+
}
579+
549580
} // namespace testing
550581
} // namespace flutter

0 commit comments

Comments
 (0)