Skip to content

Commit c3c6c36

Browse files
authored
Create a session presentation backed Vsync waiter on Fuchsia. (flutter#5255)
1 parent f943345 commit c3c6c36

16 files changed

+230
-28
lines changed

content_handler/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ template("flutter_content_handler") {
4242
"task_observers.cc",
4343
"task_observers.h",
4444
"unique_fdio_ns.h",
45+
"vsync_waiter.cc",
46+
"vsync_waiter.h",
4547
"vulkan_surface.cc",
4648
"vulkan_surface.h",
4749
"vulkan_surface_pool.cc",

content_handler/application_runner.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "flutter/lib/ui/text/font_collection.h"
1313
#include "fuchsia_font_manager.h"
14+
#include "lib/fxl/functional/make_copyable.h"
1415
#include "lib/icu_data/cpp/icu_data.h"
1516
#include "third_party/flutter/runtime/dart_vm.h"
1617
#include "third_party/skia/include/core/SkGraphics.h"
@@ -94,7 +95,27 @@ void ApplicationRunner::StartApplication(
9495
}
9596

9697
void ApplicationRunner::OnApplicationTerminate(const Application* application) {
98+
auto& active_application = active_applications_.at(application);
99+
100+
// Grab the items out of the entry because we will have to rethread the
101+
// destruction.
102+
auto application_to_destroy = std::move(active_application.application);
103+
auto application_destruction_thread = std::move(active_application.thread);
104+
105+
// Delegate the entry.
97106
active_applications_.erase(application);
107+
108+
// Post the task to destroy the application and quit its message loop.
109+
auto runner = application_destruction_thread->TaskRunner();
110+
runner->PostTask(fxl::MakeCopyable(
111+
[instance = std::move(application_to_destroy)]() mutable {
112+
instance.reset();
113+
114+
fsl::MessageLoop::GetCurrent()->PostQuitTask();
115+
}));
116+
117+
// This works because just posted the quit task on the hosted thread.
118+
application_destruction_thread->Join();
98119
}
99120

100121
void ApplicationRunner::SetupICU() {

content_handler/application_runner.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include "lib/app/cpp/application_context.h"
1414
#include "lib/fidl/cpp/binding_set.h"
1515
#include "lib/fsl/tasks/message_loop.h"
16-
#include "lib/fxl/functional/make_copyable.h"
1716
#include "lib/fxl/macros.h"
1817

1918
namespace flutter {
@@ -35,16 +34,7 @@ class ApplicationRunner final : public component::ApplicationRunner {
3534
std::unique_ptr<Application>> pair)
3635
: thread(std::move(pair.first)), application(std::move(pair.second)) {}
3736

38-
ActiveApplication() {
39-
if (thread && application) {
40-
thread->TaskRunner()->PostTask(
41-
fxl::MakeCopyable([application = std::move(application)]() mutable {
42-
application.reset();
43-
fsl::MessageLoop::GetCurrent()->PostQuitTask();
44-
}));
45-
thread.reset(); // join
46-
}
47-
}
37+
ActiveApplication() = default;
4838
};
4939

5040
std::unique_ptr<component::ApplicationContext> host_context_;

content_handler/compositor_context.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,15 @@ CompositorContext::CompositorContext(
6060
std::string debug_label,
6161
zx::eventpair import_token,
6262
OnMetricsUpdate session_metrics_did_change_callback,
63-
fxl::Closure session_error_callback)
63+
fxl::Closure session_error_callback,
64+
zx_handle_t vsync_event_handle)
6465
: debug_label_(std::move(debug_label)),
6566
session_connection_(std::move(scenic),
6667
debug_label_,
6768
std::move(import_token),
6869
std::move(session_metrics_did_change_callback),
69-
std::move(session_error_callback)) {}
70+
std::move(session_error_callback),
71+
vsync_event_handle) {}
7072

7173
CompositorContext::~CompositorContext() = default;
7274

content_handler/compositor_context.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ class CompositorContext final : public flow::CompositorContext {
2020
std::string debug_label,
2121
zx::eventpair import_token,
2222
OnMetricsUpdate session_metrics_did_change_callback,
23-
fxl::Closure session_error_callback);
23+
fxl::Closure session_error_callback,
24+
zx_handle_t vsync_event_handle);
2425

2526
~CompositorContext() override;
2627

content_handler/engine.cc

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ Engine::Engine(Delegate& delegate,
4747
thread_label_(std::move(thread_label)),
4848
settings_(std::move(settings)),
4949
weak_factory_(this) {
50+
if (zx::event::create(0, &vsync_event_) != ZX_OK) {
51+
FXL_DLOG(ERROR) << "Could not create the vsync event.";
52+
return;
53+
}
54+
5055
// Launch the threads that will be used to run the shell. These threads will
5156
// be joined in the destructor.
5257
for (auto& thread : host_threads_) {
@@ -103,7 +108,8 @@ Engine::Engine(Delegate& delegate,
103108
thread_label_, // debug label
104109
std::move(import_token), // import token
105110
on_session_metrics_change_callback, // session metrics did change
106-
on_session_error_callback // session did encounter error
111+
on_session_error_callback, // session did encounter error
112+
vsync_event_.get() // vsync event handle
107113
);
108114

109115
// Setup the callback that will instantiate the platform view.
@@ -115,7 +121,8 @@ Engine::Engine(Delegate& delegate,
115121
view_owner = std::move(view_owner), //
116122
accessibility_context_writer =
117123
std::move(accessibility_context_writer), //
118-
export_token = std::move(export_token) //
124+
export_token = std::move(export_token), //
125+
vsync_handle = vsync_event_.get() //
119126

120127
](shell::Shell& shell) mutable {
121128
return std::make_unique<flutter::PlatformView>(
@@ -127,7 +134,8 @@ Engine::Engine(Delegate& delegate,
127134
std::move(view_owner), // view owner
128135
std::move(export_token), // export token
129136
std::move(
130-
accessibility_context_writer) // accessibility context writer
137+
accessibility_context_writer), // accessibility context writer
138+
vsync_handle // vsync handle
131139
);
132140
});
133141

content_handler/engine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <fuchsia/cpp/views_v1.h>
88
#include <fuchsia/cpp/views_v1_token.h>
9+
#include <zx/event.h>
910

1011
#include "flutter/shell/common/shell.h"
1112
#include "isolate_configurator.h"
@@ -49,6 +50,7 @@ class Engine final : public mozart::NativesDelegate {
4950
std::array<fsl::Thread, 3> host_threads_;
5051
std::unique_ptr<IsolateConfigurator> isolate_configurator_;
5152
std::unique_ptr<shell::Shell> shell_;
53+
zx::event vsync_event_;
5254
fxl::WeakPtrFactory<Engine> weak_factory_;
5355

5456
void OnMainIsolateStart();

content_handler/platform_view.cc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "third_party/rapidjson/rapidjson/document.h"
1414
#include "third_party/rapidjson/rapidjson/stringbuffer.h"
1515
#include "third_party/rapidjson/rapidjson/writer.h"
16+
#include "vsync_waiter.h"
1617

1718
namespace flutter {
1819

@@ -36,15 +37,17 @@ PlatformView::PlatformView(
3637
fidl::InterfaceHandle<views_v1::ViewManager> view_manager_handle,
3738
fidl::InterfaceRequest<views_v1_token::ViewOwner> view_owner,
3839
zx::eventpair export_token,
39-
fidl::InterfaceHandle<modular::ContextWriter> accessibility_context_writer)
40+
fidl::InterfaceHandle<modular::ContextWriter> accessibility_context_writer,
41+
zx_handle_t vsync_event_handle)
4042
: shell::PlatformView(delegate, std::move(task_runners)),
4143
debug_label_(std::move(debug_label)),
4244
view_manager_(view_manager_handle.Bind()),
4345
view_listener_(this),
4446
input_listener_(this),
4547
ime_client_(this),
4648
accessibility_bridge_(std::move(accessibility_context_writer)),
47-
surface_(std::make_unique<Surface>(debug_label_)) {
49+
surface_(std::make_unique<Surface>(debug_label_)),
50+
vsync_event_handle_(vsync_event_handle) {
4851
// Register all error handlers.
4952
SetInterfaceErrorHandler(view_manager_, "View Manager");
5053
SetInterfaceErrorHandler(view_, "View");
@@ -395,6 +398,12 @@ bool PlatformView::OnHandleFocusEvent(const input::FocusEvent& focus) {
395398
return false;
396399
}
397400

401+
// |shell::PlatformView|
402+
std::unique_ptr<shell::VsyncWaiter> PlatformView::CreateVSyncWaiter() {
403+
return std::make_unique<flutter::VsyncWaiter>(
404+
debug_label_, vsync_event_handle_, task_runners_);
405+
}
406+
398407
// |shell::PlatformView|
399408
std::unique_ptr<shell::Surface> PlatformView::CreateRenderingSurface() {
400409
// This platform does not repeatly lose and gain a surface connection. So the

content_handler/platform_view.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ class PlatformView final : public shell::PlatformView,
3737
fidl::InterfaceRequest<views_v1_token::ViewOwner> view_owner,
3838
zx::eventpair export_token,
3939
fidl::InterfaceHandle<modular::ContextWriter>
40-
accessibility_context_writer);
40+
accessibility_context_writer,
41+
zx_handle_t vsync_event_handle);
4142

4243
~PlatformView();
4344

@@ -72,6 +73,7 @@ class PlatformView final : public shell::PlatformView,
7273
std::function<void(
7374
fxl::RefPtr<blink::PlatformMessage> /* message */)> /* handler */>
7475
platform_message_handlers_;
76+
zx_handle_t vsync_event_handle_ = 0;
7577

7678
void RegisterPlatformMessageHandlers();
7779

@@ -99,6 +101,9 @@ class PlatformView final : public shell::PlatformView,
99101

100102
bool OnHandleFocusEvent(const input::FocusEvent& focus);
101103

104+
// |shell::PlatformView|
105+
std::unique_ptr<shell::VsyncWaiter> CreateVSyncWaiter() override;
106+
102107
// |shell::PlatformView|
103108
std::unique_ptr<shell::Surface> CreateRenderingSurface() override;
104109

content_handler/session_connection.cc

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "lib/fidl/cpp/optional.h"
88
#include "lib/ui/scenic/fidl_helpers.h"
9+
#include "vsync_waiter.h"
910

1011
namespace flutter {
1112

@@ -14,22 +15,27 @@ SessionConnection::SessionConnection(
1415
std::string debug_label,
1516
zx::eventpair import_token,
1617
OnMetricsUpdate session_metrics_did_change_callback,
17-
fxl::Closure session_error_callback)
18+
fxl::Closure session_error_callback,
19+
zx_handle_t vsync_event_handle)
1820
: debug_label_(std::move(debug_label)),
1921
scenic_(scenic_handle.Bind()),
2022
session_(scenic_.get()),
2123
root_node_(&session_),
2224
surface_producer_(std::make_unique<VulkanSurfaceProducer>(&session_)),
2325
scene_update_context_(&session_, surface_producer_.get()),
24-
metrics_changed_callback_(
25-
std::move(session_metrics_did_change_callback)) {
26+
metrics_changed_callback_(std::move(session_metrics_did_change_callback)),
27+
vsync_event_handle_(vsync_event_handle) {
2628
session_.set_error_handler(std::move(session_error_callback));
2729
session_.set_event_handler(std::bind(&SessionConnection::OnSessionEvents,
2830
this, std::placeholders::_1));
2931

3032
root_node_.Bind(std::move(import_token));
3133
root_node_.SetEventMask(gfx::kMetricsEventMask);
32-
session_.Present(0, [](auto) {});
34+
35+
// Signal is initially high inidicating availability of the session.
36+
ToggleSignal(vsync_event_handle_, true);
37+
38+
PresentSession();
3339
}
3440

3541
SessionConnection::~SessionConnection() = default;
@@ -66,9 +72,7 @@ void SessionConnection::Present(flow::CompositorContext::ScopedFrame& frame) {
6672
// Flush all session ops. Paint tasks have not yet executed but those are
6773
// fenced. The compositor can start processing ops while we finalize paint
6874
// tasks.
69-
session_.Present(0, // presentation_time. (placeholder).
70-
[](auto) {} // callback
71-
);
75+
PresentSession();
7276

7377
// Execute paint tasks and signal fences.
7478
auto surfaces_to_submit = scene_update_context_.ExecutePaintTasks(frame);
@@ -88,4 +92,24 @@ void SessionConnection::EnqueueClearOps() {
8892
session_.Enqueue(scenic_lib::NewDetachChildrenCommand(root_node_.id()));
8993
}
9094

95+
void SessionConnection::PresentSession() {
96+
ToggleSignal(vsync_event_handle_, false);
97+
session_.Present(0, // presentation_time. (placeholder).
98+
[handle = vsync_event_handle_](auto) {
99+
ToggleSignal(handle, true);
100+
} // callback
101+
);
102+
}
103+
104+
void SessionConnection::ToggleSignal(zx_handle_t handle, bool set) {
105+
const auto signal = flutter::VsyncWaiter::SessionPresentSignal;
106+
auto status = zx_object_signal(handle, // handle
107+
set ? 0 : signal, // clear mask
108+
set ? signal : 0 // set mask
109+
);
110+
if (status != ZX_OK) {
111+
FXL_LOG(ERROR) << "Could not toggle vsync signal: " << set;
112+
}
113+
}
114+
91115
} // namespace flutter

0 commit comments

Comments
 (0)