Skip to content

Commit

Permalink
Create a session presentation backed Vsync waiter on Fuchsia. (flutte…
Browse files Browse the repository at this point in the history
  • Loading branch information
chinmaygarde committed May 14, 2018
1 parent f943345 commit c3c6c36
Show file tree
Hide file tree
Showing 16 changed files with 230 additions and 28 deletions.
2 changes: 2 additions & 0 deletions content_handler/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ template("flutter_content_handler") {
"task_observers.cc",
"task_observers.h",
"unique_fdio_ns.h",
"vsync_waiter.cc",
"vsync_waiter.h",
"vulkan_surface.cc",
"vulkan_surface.h",
"vulkan_surface_pool.cc",
Expand Down
21 changes: 21 additions & 0 deletions content_handler/application_runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "flutter/lib/ui/text/font_collection.h"
#include "fuchsia_font_manager.h"
#include "lib/fxl/functional/make_copyable.h"
#include "lib/icu_data/cpp/icu_data.h"
#include "third_party/flutter/runtime/dart_vm.h"
#include "third_party/skia/include/core/SkGraphics.h"
Expand Down Expand Up @@ -94,7 +95,27 @@ void ApplicationRunner::StartApplication(
}

void ApplicationRunner::OnApplicationTerminate(const Application* application) {
auto& active_application = active_applications_.at(application);

// Grab the items out of the entry because we will have to rethread the
// destruction.
auto application_to_destroy = std::move(active_application.application);
auto application_destruction_thread = std::move(active_application.thread);

// Delegate the entry.
active_applications_.erase(application);

// Post the task to destroy the application and quit its message loop.
auto runner = application_destruction_thread->TaskRunner();
runner->PostTask(fxl::MakeCopyable(
[instance = std::move(application_to_destroy)]() mutable {
instance.reset();

fsl::MessageLoop::GetCurrent()->PostQuitTask();
}));

// This works because just posted the quit task on the hosted thread.
application_destruction_thread->Join();
}

void ApplicationRunner::SetupICU() {
Expand Down
12 changes: 1 addition & 11 deletions content_handler/application_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "lib/app/cpp/application_context.h"
#include "lib/fidl/cpp/binding_set.h"
#include "lib/fsl/tasks/message_loop.h"
#include "lib/fxl/functional/make_copyable.h"
#include "lib/fxl/macros.h"

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

ActiveApplication() {
if (thread && application) {
thread->TaskRunner()->PostTask(
fxl::MakeCopyable([application = std::move(application)]() mutable {
application.reset();
fsl::MessageLoop::GetCurrent()->PostQuitTask();
}));
thread.reset(); // join
}
}
ActiveApplication() = default;
};

std::unique_ptr<component::ApplicationContext> host_context_;
Expand Down
6 changes: 4 additions & 2 deletions content_handler/compositor_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,15 @@ CompositorContext::CompositorContext(
std::string debug_label,
zx::eventpair import_token,
OnMetricsUpdate session_metrics_did_change_callback,
fxl::Closure session_error_callback)
fxl::Closure session_error_callback,
zx_handle_t vsync_event_handle)
: debug_label_(std::move(debug_label)),
session_connection_(std::move(scenic),
debug_label_,
std::move(import_token),
std::move(session_metrics_did_change_callback),
std::move(session_error_callback)) {}
std::move(session_error_callback),
vsync_event_handle) {}

CompositorContext::~CompositorContext() = default;

Expand Down
3 changes: 2 additions & 1 deletion content_handler/compositor_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ class CompositorContext final : public flow::CompositorContext {
std::string debug_label,
zx::eventpair import_token,
OnMetricsUpdate session_metrics_did_change_callback,
fxl::Closure session_error_callback);
fxl::Closure session_error_callback,
zx_handle_t vsync_event_handle);

~CompositorContext() override;

Expand Down
14 changes: 11 additions & 3 deletions content_handler/engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ Engine::Engine(Delegate& delegate,
thread_label_(std::move(thread_label)),
settings_(std::move(settings)),
weak_factory_(this) {
if (zx::event::create(0, &vsync_event_) != ZX_OK) {
FXL_DLOG(ERROR) << "Could not create the vsync event.";
return;
}

// Launch the threads that will be used to run the shell. These threads will
// be joined in the destructor.
for (auto& thread : host_threads_) {
Expand Down Expand Up @@ -103,7 +108,8 @@ Engine::Engine(Delegate& delegate,
thread_label_, // debug label
std::move(import_token), // import token
on_session_metrics_change_callback, // session metrics did change
on_session_error_callback // session did encounter error
on_session_error_callback, // session did encounter error
vsync_event_.get() // vsync event handle
);

// Setup the callback that will instantiate the platform view.
Expand All @@ -115,7 +121,8 @@ Engine::Engine(Delegate& delegate,
view_owner = std::move(view_owner), //
accessibility_context_writer =
std::move(accessibility_context_writer), //
export_token = std::move(export_token) //
export_token = std::move(export_token), //
vsync_handle = vsync_event_.get() //

](shell::Shell& shell) mutable {
return std::make_unique<flutter::PlatformView>(
Expand All @@ -127,7 +134,8 @@ Engine::Engine(Delegate& delegate,
std::move(view_owner), // view owner
std::move(export_token), // export token
std::move(
accessibility_context_writer) // accessibility context writer
accessibility_context_writer), // accessibility context writer
vsync_handle // vsync handle
);
});

Expand Down
2 changes: 2 additions & 0 deletions content_handler/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <fuchsia/cpp/views_v1.h>
#include <fuchsia/cpp/views_v1_token.h>
#include <zx/event.h>

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

void OnMainIsolateStart();
Expand Down
13 changes: 11 additions & 2 deletions content_handler/platform_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "third_party/rapidjson/rapidjson/document.h"
#include "third_party/rapidjson/rapidjson/stringbuffer.h"
#include "third_party/rapidjson/rapidjson/writer.h"
#include "vsync_waiter.h"

namespace flutter {

Expand All @@ -36,15 +37,17 @@ PlatformView::PlatformView(
fidl::InterfaceHandle<views_v1::ViewManager> view_manager_handle,
fidl::InterfaceRequest<views_v1_token::ViewOwner> view_owner,
zx::eventpair export_token,
fidl::InterfaceHandle<modular::ContextWriter> accessibility_context_writer)
fidl::InterfaceHandle<modular::ContextWriter> accessibility_context_writer,
zx_handle_t vsync_event_handle)
: shell::PlatformView(delegate, std::move(task_runners)),
debug_label_(std::move(debug_label)),
view_manager_(view_manager_handle.Bind()),
view_listener_(this),
input_listener_(this),
ime_client_(this),
accessibility_bridge_(std::move(accessibility_context_writer)),
surface_(std::make_unique<Surface>(debug_label_)) {
surface_(std::make_unique<Surface>(debug_label_)),
vsync_event_handle_(vsync_event_handle) {
// Register all error handlers.
SetInterfaceErrorHandler(view_manager_, "View Manager");
SetInterfaceErrorHandler(view_, "View");
Expand Down Expand Up @@ -395,6 +398,12 @@ bool PlatformView::OnHandleFocusEvent(const input::FocusEvent& focus) {
return false;
}

// |shell::PlatformView|
std::unique_ptr<shell::VsyncWaiter> PlatformView::CreateVSyncWaiter() {
return std::make_unique<flutter::VsyncWaiter>(
debug_label_, vsync_event_handle_, task_runners_);
}

// |shell::PlatformView|
std::unique_ptr<shell::Surface> PlatformView::CreateRenderingSurface() {
// This platform does not repeatly lose and gain a surface connection. So the
Expand Down
7 changes: 6 additions & 1 deletion content_handler/platform_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ class PlatformView final : public shell::PlatformView,
fidl::InterfaceRequest<views_v1_token::ViewOwner> view_owner,
zx::eventpair export_token,
fidl::InterfaceHandle<modular::ContextWriter>
accessibility_context_writer);
accessibility_context_writer,
zx_handle_t vsync_event_handle);

~PlatformView();

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

void RegisterPlatformMessageHandlers();

Expand Down Expand Up @@ -99,6 +101,9 @@ class PlatformView final : public shell::PlatformView,

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

// |shell::PlatformView|
std::unique_ptr<shell::VsyncWaiter> CreateVSyncWaiter() override;

// |shell::PlatformView|
std::unique_ptr<shell::Surface> CreateRenderingSurface() override;

Expand Down
38 changes: 31 additions & 7 deletions content_handler/session_connection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "lib/fidl/cpp/optional.h"
#include "lib/ui/scenic/fidl_helpers.h"
#include "vsync_waiter.h"

namespace flutter {

Expand All @@ -14,22 +15,27 @@ SessionConnection::SessionConnection(
std::string debug_label,
zx::eventpair import_token,
OnMetricsUpdate session_metrics_did_change_callback,
fxl::Closure session_error_callback)
fxl::Closure session_error_callback,
zx_handle_t vsync_event_handle)
: debug_label_(std::move(debug_label)),
scenic_(scenic_handle.Bind()),
session_(scenic_.get()),
root_node_(&session_),
surface_producer_(std::make_unique<VulkanSurfaceProducer>(&session_)),
scene_update_context_(&session_, surface_producer_.get()),
metrics_changed_callback_(
std::move(session_metrics_did_change_callback)) {
metrics_changed_callback_(std::move(session_metrics_did_change_callback)),
vsync_event_handle_(vsync_event_handle) {
session_.set_error_handler(std::move(session_error_callback));
session_.set_event_handler(std::bind(&SessionConnection::OnSessionEvents,
this, std::placeholders::_1));

root_node_.Bind(std::move(import_token));
root_node_.SetEventMask(gfx::kMetricsEventMask);
session_.Present(0, [](auto) {});

// Signal is initially high inidicating availability of the session.
ToggleSignal(vsync_event_handle_, true);

PresentSession();
}

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

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

void SessionConnection::PresentSession() {
ToggleSignal(vsync_event_handle_, false);
session_.Present(0, // presentation_time. (placeholder).
[handle = vsync_event_handle_](auto) {
ToggleSignal(handle, true);
} // callback
);
}

void SessionConnection::ToggleSignal(zx_handle_t handle, bool set) {
const auto signal = flutter::VsyncWaiter::SessionPresentSignal;
auto status = zx_object_signal(handle, // handle
set ? 0 : signal, // clear mask
set ? signal : 0 // set mask
);
if (status != ZX_OK) {
FXL_LOG(ERROR) << "Could not toggle vsync signal: " << set;
}
}

} // namespace flutter
8 changes: 7 additions & 1 deletion content_handler/session_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ class SessionConnection final {
std::string debug_label,
zx::eventpair import_token,
OnMetricsUpdate session_metrics_did_change_callback,
fxl::Closure session_error_callback);
fxl::Closure session_error_callback,
zx_handle_t vsync_event_handle);

~SessionConnection();

Expand All @@ -53,11 +54,16 @@ class SessionConnection final {
std::unique_ptr<VulkanSurfaceProducer> surface_producer_;
flow::SceneUpdateContext scene_update_context_;
OnMetricsUpdate metrics_changed_callback_;
zx_handle_t vsync_event_handle_;

void OnSessionEvents(fidl::VectorPtr<ui::Event> events);

void EnqueueClearOps();

void PresentSession();

static void ToggleSignal(zx_handle_t handle, bool raise);

FXL_DISALLOW_COPY_AND_ASSIGN(SessionConnection);
};

Expand Down

0 comments on commit c3c6c36

Please sign in to comment.