Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1495,6 +1495,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
Expand Down
1 change: 1 addition & 0 deletions shell/platform/fuchsia/flutter/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,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.
Expand Down
18 changes: 13 additions & 5 deletions shell/platform/fuchsia/flutter/vsync_waiter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,27 @@ 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
// to wait on a latch because we only ever use the WeakPtrFactory on the UI
// 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();
}));
}

Expand Down
7 changes: 4 additions & 3 deletions shell/platform/fuchsia/flutter/vsync_waiter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down Expand Up @@ -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_;

Expand All @@ -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_
63 changes: 63 additions & 0 deletions shell/platform/fuchsia/flutter/vsync_waiter_unittest.cc
Original file line number Diff line number Diff line change
@@ -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