// Copyright 2017 The Chromium 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 "session_connection.h" #include "lib/ui/scenic/fidl_helpers.h" namespace flutter { SessionConnection::SessionConnection( const ui::ScenicPtr& scenic, std::string debug_label, zx::eventpair import_token, OnMetricsUpdate session_metrics_did_change_callback, fxl::Closure session_error_callback) : debug_label_(std::move(debug_label)), session_(scenic.get()), root_node_(&session_), surface_producer_(std::make_unique(&session_)), scene_update_context_(&session_, surface_producer_.get()), metrics_changed_callback_( std::move(session_metrics_did_change_callback)) { 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(ui::gfx::kMetricsEventMask); session_.Present(0, [](ui::PresentationInfoPtr info) {}); } SessionConnection::~SessionConnection() = default; void SessionConnection::OnSessionEvents(f1dl::Array events) { using Type = ui::gfx::Event::Tag; for (auto& raw_event : *events) { if (!raw_event->is_gfx()) { continue; } auto& event = raw_event->get_gfx(); switch (event->which()) { case Type::METRICS: { if (event->get_metrics()->node_id == root_node_.id()) { auto& metrics = event->get_metrics()->metrics; double device_pixel_ratio = metrics->scale_x; scene_update_context_.set_metrics(std::move(metrics)); if (metrics_changed_callback_) { metrics_changed_callback_(device_pixel_ratio); } } } break; default: break; } } } 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). [](ui::PresentationInfoPtr) {} // callback ); // Execute paint tasks and signal fences. auto surfaces_to_submit = scene_update_context_.ExecutePaintTasks(frame); // Tell the surface producer that a present has occurred so it can perform // book-keeping on buffer caches. surface_producer_->OnSurfacesPresented(std::move(surfaces_to_submit)); // Prepare for the next frame. These ops won't be processed till the next // present. EnqueueClearOps(); } void SessionConnection::EnqueueClearOps() { // We are going to be sending down a fresh node hierarchy every frame. So just // enqueue a detach op on the imported root node. session_.Enqueue(scenic_lib::NewDetachChildrenCommand(root_node_.id())); } } // namespace flutter