mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
VSyncWaiter on Fuchsia will defer firing until frame start time (flutter/engine#29287)
* VSyncWaiter on Fuchsia will defer firing until frame start time The common vsync waiter implementation expects this invariant to be held. * Add a test for vsync_waiter
This commit is contained in:
parent
b9c37424dc
commit
dc905faa2d
@ -1498,6 +1498,7 @@ FILE: ../../../flutter/shell/platform/fuchsia/flutter/task_runner_adapter.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/unique_fdio_ns.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/vsync_waiter.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/vsync_waiter.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/vsync_waiter_unittest.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/vulkan_surface.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/vulkan_surface.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/vulkan_surface_pool.cc
|
||||
|
||||
@ -485,6 +485,7 @@ executable("flutter_runner_unittests") {
|
||||
"tests/gfx_session_connection_unittests.cc",
|
||||
"tests/pointer_event_utility.cc",
|
||||
"tests/pointer_event_utility.h",
|
||||
"vsync_waiter_unittest.cc",
|
||||
]
|
||||
|
||||
# This is needed for //third_party/googletest for linking zircon symbols.
|
||||
|
||||
@ -30,10 +30,17 @@ VsyncWaiter::VsyncWaiter(AwaitVsyncCallback await_vsync_callback,
|
||||
weak_factory_(this) {
|
||||
fire_callback_callback_ = [this](fml::TimePoint frame_start,
|
||||
fml::TimePoint frame_end) {
|
||||
// Note: It is VERY important to set |pause_secondary_tasks| to false, else
|
||||
// Animator will almost immediately crash on Fuchsia.
|
||||
// FML_LOG(INFO) << "CRASH:: VsyncWaiter about to FireCallback";
|
||||
FireCallback(frame_start, frame_end, /*pause_secondary_tasks=*/false);
|
||||
task_runners_.GetUITaskRunner()->PostTaskForTime(
|
||||
[frame_start, frame_end, weak_this = weak_ui_]() {
|
||||
if (weak_this) {
|
||||
// Note: It is VERY important to set |pause_secondary_tasks| to
|
||||
// false, else Animator will almost immediately crash on Fuchsia.
|
||||
// FML_LOG(INFO) << "CRASH:: VsyncWaiter about to FireCallback";
|
||||
weak_this->FireCallback(frame_start, frame_end,
|
||||
/*pause_secondary_tasks*/ false);
|
||||
}
|
||||
},
|
||||
frame_start);
|
||||
};
|
||||
|
||||
// Generate a WeakPtrFactory for use with the UI thread. This does not need
|
||||
@ -41,8 +48,9 @@ VsyncWaiter::VsyncWaiter(AwaitVsyncCallback await_vsync_callback,
|
||||
// thread so we have ordering guarantees (see ::AwaitVSync())
|
||||
fml::TaskRunner::RunNowOrPostTask(
|
||||
task_runners_.GetUITaskRunner(), fml::MakeCopyable([this]() mutable {
|
||||
this->weak_factory_ui_ =
|
||||
weak_factory_ui_ =
|
||||
std::make_unique<fml::WeakPtrFactory<VsyncWaiter>>(this);
|
||||
weak_ui_ = weak_factory_ui_->GetWeakPtr();
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_VSYNC_WAITER_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_VSYNC_WAITER_H_
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_VSYNC_WAITER_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_VSYNC_WAITER_H_
|
||||
|
||||
#include <lib/async/cpp/wait.h>
|
||||
|
||||
@ -46,6 +46,7 @@ class VsyncWaiter final : public flutter::VsyncWaiter {
|
||||
AwaitVsyncForSecondaryCallbackCallback
|
||||
await_vsync_for_secondary_callback_callback_;
|
||||
|
||||
fml::WeakPtr<VsyncWaiter> weak_ui_;
|
||||
std::unique_ptr<fml::WeakPtrFactory<VsyncWaiter>> weak_factory_ui_;
|
||||
fml::WeakPtrFactory<VsyncWaiter> weak_factory_;
|
||||
|
||||
@ -54,4 +55,4 @@ class VsyncWaiter final : public flutter::VsyncWaiter {
|
||||
|
||||
} // namespace flutter_runner
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_VSYNC_WAITER_H_
|
||||
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_VSYNC_WAITER_H_
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "flutter/fml/task_runner.h"
|
||||
#include "flutter/shell/common/thread_host.h"
|
||||
#include "fml/make_copyable.h"
|
||||
#include "fml/message_loop.h"
|
||||
#include "fml/synchronization/waitable_event.h"
|
||||
#include "fml/time/time_delta.h"
|
||||
#include "fml/time/time_point.h"
|
||||
#include "vsync_waiter.h"
|
||||
|
||||
namespace flutter_runner {
|
||||
|
||||
TEST(VSyncWaiterFuchsia, FrameScheduledForStartTime) {
|
||||
using flutter::ThreadHost;
|
||||
std::string prefix = "vsync_waiter_test";
|
||||
|
||||
fml::MessageLoop::EnsureInitializedForCurrentThread();
|
||||
auto platform_task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner();
|
||||
|
||||
ThreadHost thread_host =
|
||||
ThreadHost(prefix, flutter::ThreadHost::Type::RASTER |
|
||||
flutter::ThreadHost::Type::UI |
|
||||
flutter::ThreadHost::Type::IO);
|
||||
const flutter::TaskRunners task_runners(
|
||||
prefix, // Dart thread labels
|
||||
platform_task_runner, // platform
|
||||
thread_host.raster_thread->GetTaskRunner(), // raster
|
||||
thread_host.ui_thread->GetTaskRunner(), // ui
|
||||
thread_host.io_thread->GetTaskRunner() // io
|
||||
);
|
||||
|
||||
// await vsync will invoke the callback right away, but vsync waiter will post
|
||||
// the task for frame_start time.
|
||||
VsyncWaiter vsync_waiter(
|
||||
[](FireCallbackCallback callback) {
|
||||
const auto now = fml::TimePoint::Now();
|
||||
const auto frame_start = now + fml::TimeDelta::FromMilliseconds(20);
|
||||
const auto frame_end = now + fml::TimeDelta::FromMilliseconds(36);
|
||||
callback(frame_start, frame_end);
|
||||
},
|
||||
/*secondary callback*/ nullptr, task_runners);
|
||||
|
||||
fml::AutoResetWaitableEvent latch;
|
||||
task_runners.GetUITaskRunner()->PostTask([&]() {
|
||||
vsync_waiter.AsyncWaitForVsync(
|
||||
[&](std::unique_ptr<flutter::FrameTimingsRecorder> recorder) {
|
||||
const auto now = fml::TimePoint::Now();
|
||||
EXPECT_GT(now, recorder->GetVsyncStartTime());
|
||||
latch.Signal();
|
||||
});
|
||||
});
|
||||
|
||||
latch.Wait();
|
||||
}
|
||||
|
||||
} // namespace flutter_runner
|
||||
Loading…
x
Reference in New Issue
Block a user