Skip to content

Commit 1725031

Browse files
authored
VsyncWaiter schedules unneeded extra AwaitVSync callbacks for one frame (flutter#36406)
1 parent e22414a commit 1725031

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,6 +2073,7 @@ FILE: ../../../flutter/shell/common/vsync_waiter.cc
20732073
FILE: ../../../flutter/shell/common/vsync_waiter.h
20742074
FILE: ../../../flutter/shell/common/vsync_waiter_fallback.cc
20752075
FILE: ../../../flutter/shell/common/vsync_waiter_fallback.h
2076+
FILE: ../../../flutter/shell/common/vsync_waiter_unittests.cc
20762077
FILE: ../../../flutter/shell/common/vsync_waiters_test.cc
20772078
FILE: ../../../flutter/shell/common/vsync_waiters_test.h
20782079
FILE: ../../../flutter/shell/gpu/gpu_surface_gl_delegate.cc

shell/common/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ if (enable_unittests) {
293293
"shell_unittests.cc",
294294
"switches_unittests.cc",
295295
"variable_refresh_rate_display_unittests.cc",
296+
"vsync_waiter_unittests.cc",
296297
]
297298

298299
deps = [

shell/common/vsync_waiter.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ void VsyncWaiter::ScheduleSecondaryCallback(uintptr_t id,
6262

6363
{
6464
std::scoped_lock lock(callback_mutex_);
65+
bool secondary_callbacks_originally_empty = secondary_callbacks_.empty();
6566
auto [_, inserted] = secondary_callbacks_.emplace(id, callback);
6667
if (!inserted) {
6768
// Multiple schedules must result in a single callback per frame interval.
@@ -74,6 +75,11 @@ void VsyncWaiter::ScheduleSecondaryCallback(uintptr_t id,
7475
// `AsyncWaitForVsync`.
7576
return;
7677
}
78+
if (!secondary_callbacks_originally_empty) {
79+
// Return directly as `AwaitVSync` is already called by
80+
// `ScheduleSecondaryCallback`.
81+
return;
82+
}
7783
}
7884
AwaitVSyncForSecondaryCallback();
7985
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#define FML_USED_ON_EMBEDDER
2+
3+
#include <initializer_list>
4+
5+
#include "flutter/common/settings.h"
6+
#include "flutter/common/task_runners.h"
7+
#include "flutter/shell/common/switches.h"
8+
9+
#include "gtest/gtest.h"
10+
#include "thread_host.h"
11+
#include "vsync_waiter.h"
12+
13+
namespace flutter {
14+
namespace testing {
15+
16+
class TestVsyncWaiter : public VsyncWaiter {
17+
public:
18+
explicit TestVsyncWaiter(const TaskRunners& task_runners)
19+
: VsyncWaiter(task_runners) {}
20+
21+
int await_vsync_call_count_ = 0;
22+
23+
protected:
24+
void AwaitVSync() override { await_vsync_call_count_++; }
25+
};
26+
27+
TEST(VsyncWaiterTest, NoUnneededAwaitVsync) {
28+
using flutter::ThreadHost;
29+
std::string prefix = "vsync_waiter_test";
30+
31+
fml::MessageLoop::EnsureInitializedForCurrentThread();
32+
auto task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner();
33+
34+
const flutter::TaskRunners task_runners(prefix, task_runner, task_runner,
35+
task_runner, task_runner);
36+
37+
TestVsyncWaiter vsync_waiter(task_runners);
38+
39+
vsync_waiter.ScheduleSecondaryCallback(1, [] {});
40+
EXPECT_EQ(vsync_waiter.await_vsync_call_count_, 1);
41+
42+
vsync_waiter.ScheduleSecondaryCallback(2, [] {});
43+
EXPECT_EQ(vsync_waiter.await_vsync_call_count_, 1);
44+
}
45+
46+
} // namespace testing
47+
} // namespace flutter

0 commit comments

Comments
 (0)