diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index e9a22a5a7cb..d697aec9898 100755 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -1374,8 +1374,6 @@ FILE: ../../../flutter/shell/platform/fuchsia/flutter/accessibility_bridge_unitt FILE: ../../../flutter/shell/platform/fuchsia/flutter/component.cc FILE: ../../../flutter/shell/platform/fuchsia/flutter/component.h FILE: ../../../flutter/shell/platform/fuchsia/flutter/component_unittest.cc -FILE: ../../../flutter/shell/platform/fuchsia/flutter/default_session_connection.cc -FILE: ../../../flutter/shell/platform/fuchsia/flutter/default_session_connection.h FILE: ../../../flutter/shell/platform/fuchsia/flutter/engine.cc FILE: ../../../flutter/shell/platform/fuchsia/flutter/engine.h FILE: ../../../flutter/shell/platform/fuchsia/flutter/flutter_runner_fakes.h @@ -1389,6 +1387,8 @@ FILE: ../../../flutter/shell/platform/fuchsia/flutter/fuchsia_external_view_embe FILE: ../../../flutter/shell/platform/fuchsia/flutter/fuchsia_intl.cc FILE: ../../../flutter/shell/platform/fuchsia/flutter/fuchsia_intl.h FILE: ../../../flutter/shell/platform/fuchsia/flutter/fuchsia_intl_unittest.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/gfx_session_connection.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/gfx_session_connection.h FILE: ../../../flutter/shell/platform/fuchsia/flutter/isolate_configurator.cc FILE: ../../../flutter/shell/platform/fuchsia/flutter/isolate_configurator.h FILE: ../../../flutter/shell/platform/fuchsia/flutter/kernel/extract_far.dart @@ -1405,7 +1405,6 @@ FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/flutter_aot_product_r FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/flutter_aot_runner.cmx FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/flutter_jit_product_runner.cmx FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/flutter_jit_runner.cmx -FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/flutter_runner_scenic_tests.cmx FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/flutter_runner_tests.cmx FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/jit_product_runtime FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/jit_runtime diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/BUILD.gn b/engine/src/flutter/shell/platform/fuchsia/flutter/BUILD.gn index 218f751c721..70dae94473e 100644 --- a/engine/src/flutter/shell/platform/fuchsia/flutter/BUILD.gn +++ b/engine/src/flutter/shell/platform/fuchsia/flutter/BUILD.gn @@ -53,8 +53,6 @@ template("runner_sources") { "accessibility_bridge.h", "component.cc", "component.h", - "default_session_connection.cc", - "default_session_connection.h", "engine.cc", "engine.h", "flutter_runner_product_configuration.cc", @@ -65,6 +63,8 @@ template("runner_sources") { "fuchsia_external_view_embedder.h", "fuchsia_intl.cc", "fuchsia_intl.h", + "gfx_session_connection.cc", + "gfx_session_connection.h", "isolate_configurator.cc", "isolate_configurator.h", "keyboard.cc", @@ -449,6 +449,7 @@ executable("flutter_runner_unittests") { "runner_unittest.cc", "tests/engine_unittests.cc", "tests/flutter_runner_product_configuration_unittests.cc", + "tests/gfx_session_connection_unittests.cc", ] # This is needed for //third_party/googletest for linking zircon symbols. @@ -470,6 +471,8 @@ executable("flutter_runner_unittests") { "tests/fakes", ":flutter_runner_fixtures", ":flutter_runner_sources", + "tests/fakes", + "//build/fuchsia/pkg:async-testing", "//build/fuchsia/pkg:sys_cpp_testing", "//flutter/testing", ] + flutter_deps @@ -500,32 +503,6 @@ executable("flutter_runner_tzdata_unittests") { ] + flutter_deps } -executable("flutter_runner_scenic_unittests") { - testonly = true - - output_name = "flutter_runner_scenic_tests" - - sources = [ "tests/default_session_connection_unittests.cc" ] - - # This is needed for //third_party/googletest for linking zircon symbols. - libs = [ "$fuchsia_sdk_path/arch/$target_cpu/sysroot/lib/libzircon.so" ] - - # The use of these dependencies is temporary and will be moved behind the - # embedder API. - flutter_deps = [ - "//flutter/lib/ui", - "//third_party/dart/runtime:libdart_jit", - "//third_party/dart/runtime/platform:libdart_platform_jit", - ] - - deps = [ - ":flutter_runner_fixtures", - ":flutter_runner_sources", - "$fuchsia_sdk_root/fidl:fuchsia.ui.policy", - "//flutter/testing", - ] + flutter_deps -} - fuchsia_test_archive("flutter_runner_tests") { deps = [ ":flutter_runner_unittests" ] @@ -556,21 +533,6 @@ fuchsia_test_archive("flutter_runner_tests") { cmx_file = rebase_path("meta/$target_name.cmx") } -fuchsia_test_archive("flutter_runner_scenic_tests") { - deps = [ ":flutter_runner_scenic_unittests" ] - - binary = "$target_name" - - resources = [ - { - path = rebase_path("//third_party/icu/common/icudtl.dat") - dest = "icudtl.dat" - }, - ] - - cmx_file = rebase_path("meta/$target_name.cmx") -} - fuchsia_test_archive("flutter_runner_tzdata_tests") { deps = [ ":flutter_runner_tzdata_unittests" ] @@ -825,7 +787,6 @@ group("tests") { ":dart_utils_tests", ":embedder_tests", ":flow_tests", - ":flutter_runner_scenic_tests", ":flutter_runner_tests", ":flutter_runner_tzdata_tests", ":fml_tests", diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/engine.cc b/engine/src/flutter/shell/platform/fuchsia/flutter/engine.cc index 9f29903e4f4..1589f4cb864 100644 --- a/engine/src/flutter/shell/platform/fuchsia/flutter/engine.cc +++ b/engine/src/flutter/shell/platform/fuchsia/flutter/engine.cc @@ -24,6 +24,7 @@ #include "third_party/skia/include/ports/SkFontMgr_fuchsia.h" #include "../runtime/dart/utils/files.h" +#include "../runtime/dart/utils/root_inspect_node.h" #include "focus_delegate.h" #include "fuchsia_intl.h" #include "platform_view.h" @@ -119,16 +120,19 @@ Engine::Engine(Delegate& delegate, // thread. We also need to wait for the external view embedder to be set up // before creating the shell. fml::AutoResetWaitableEvent view_embedder_latch; + auto session_inspect_node = + dart_utils::RootInspectNode::CreateRootChild("vsync_stats"); task_runners.GetRasterTaskRunner()->PostTask(fml::MakeCopyable( - [this, session = std::move(session), + [this, &view_embedder_latch, + session_inspect_node = std::move(session_inspect_node), + session = std::move(session), session_error_callback = std::move(session_error_callback), view_token = std::move(view_token), view_ref_pair = std::move(view_ref_pair), max_frames_in_flight = product_config.get_max_frames_in_flight(), - &view_embedder_latch, vsync_offset = product_config.get_vsync_offset()]() mutable { - session_connection_ = std::make_shared( - thread_label_, std::move(session), + session_connection_ = std::make_shared( + thread_label_, std::move(session_inspect_node), std::move(session), std::move(session_error_callback), [](auto) {}, max_frames_in_flight, vsync_offset); surface_producer_.emplace(session_connection_->get()); @@ -326,7 +330,7 @@ Engine::Engine(Delegate& delegate, std::move(on_semantics_node_update_callback), std::move(on_request_announce_callback), std::move(on_shader_warmup), external_view_embedder, - // Callbacks for VsyncWaiter to call into SessionConnection. + // Callbacks for VsyncWaiter to call into GfxSessionConnection. await_vsync_callback, await_vsync_for_secondary_callback_callback); }); diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/engine.h b/engine/src/flutter/shell/platform/fuchsia/flutter/engine.h index 8d0e7b93c12..bc7a66fdc24 100644 --- a/engine/src/flutter/shell/platform/fuchsia/flutter/engine.h +++ b/engine/src/flutter/shell/platform/fuchsia/flutter/engine.h @@ -24,9 +24,9 @@ #include "flutter/shell/common/thread_host.h" #include "flutter/shell/platform/fuchsia/flutter/accessibility_bridge.h" -#include "default_session_connection.h" #include "flutter_runner_product_configuration.h" #include "fuchsia_external_view_embedder.h" +#include "gfx_session_connection.h" #include "isolate_configurator.h" #include "vulkan_surface_producer.h" @@ -71,7 +71,7 @@ class Engine final { const std::string thread_label_; flutter::ThreadHost thread_host_; - std::shared_ptr session_connection_; + std::shared_ptr session_connection_; std::optional surface_producer_; std::shared_ptr external_view_embedder_; diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.cc b/engine/src/flutter/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.cc index a9a291f6046..639dd3c1b11 100644 --- a/engine/src/flutter/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.cc +++ b/engine/src/flutter/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.cc @@ -109,7 +109,7 @@ FuchsiaExternalViewEmbedder::FuchsiaExternalViewEmbedder( std::string debug_label, fuchsia::ui::views::ViewToken view_token, scenic::ViewRefPair view_ref_pair, - DefaultSessionConnection& session, + GfxSessionConnection& session, VulkanSurfaceProducer& surface_producer, bool intercept_all_input) : session_(session), diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.h b/engine/src/flutter/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.h index d20305a50ed..125c8f843ec 100644 --- a/engine/src/flutter/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.h +++ b/engine/src/flutter/shell/platform/fuchsia/flutter/fuchsia_external_view_embedder.h @@ -27,7 +27,7 @@ #include "third_party/skia/include/core/SkSize.h" #include "third_party/skia/include/gpu/GrDirectContext.h" -#include "default_session_connection.h" +#include "gfx_session_connection.h" #include "vulkan_surface_producer.h" namespace flutter_runner { @@ -67,7 +67,7 @@ class FuchsiaExternalViewEmbedder final : public flutter::ExternalViewEmbedder { FuchsiaExternalViewEmbedder(std::string debug_label, fuchsia::ui::views::ViewToken view_token, scenic::ViewRefPair view_ref_pair, - DefaultSessionConnection& session, + GfxSessionConnection& session, VulkanSurfaceProducer& surface_producer, bool intercept_all_input = false); ~FuchsiaExternalViewEmbedder(); @@ -171,7 +171,7 @@ class FuchsiaExternalViewEmbedder final : public flutter::ExternalViewEmbedder { scenic::Material material; }; - DefaultSessionConnection& session_; + GfxSessionConnection& session_; VulkanSurfaceProducer& surface_producer_; scenic::View root_view_; diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/default_session_connection.cc b/engine/src/flutter/shell/platform/fuchsia/flutter/gfx_session_connection.cc similarity index 87% rename from engine/src/flutter/shell/platform/fuchsia/flutter/default_session_connection.cc rename to engine/src/flutter/shell/platform/fuchsia/flutter/gfx_session_connection.cc index 0ebc9d30aed..9846f67bc8b 100644 --- a/engine/src/flutter/shell/platform/fuchsia/flutter/default_session_connection.cc +++ b/engine/src/flutter/shell/platform/fuchsia/flutter/gfx_session_connection.cc @@ -2,20 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "default_session_connection.h" +#include "gfx_session_connection.h" + +#include +#include #include #include #include #include "flutter/fml/make_copyable.h" +#include "flutter/fml/time/time_point.h" #include "flutter/fml/trace_event.h" -#include "fml/time/time_point.h" -#include "runtime/dart/utils/root_inspect_node.h" #include "vsync_waiter.h" namespace flutter_runner { +namespace { + +fml::TimePoint Now() { + return fml::TimePoint::FromEpochDelta(fml::TimeDelta::FromNanoseconds( + async::Now(async_get_default_dispatcher()).get())); +} + +} // namespace // This function takes in all relevant information to determining when should // the next frame be scheduled. It returns a pair of (frame_start_time, @@ -42,7 +52,7 @@ namespace flutter_runner { // // |next_vsync| - the next vsync after |now|. This can be generated using the // SnapToNextPhase function. -FlutterFrameTimes DefaultSessionConnection::GetTargetTimes( +FlutterFrameTimes GfxSessionConnection::GetTargetTimes( fml::TimeDelta vsync_offset, fml::TimeDelta vsync_interval, fml::TimePoint last_targeted_vsync, @@ -76,18 +86,18 @@ FlutterFrameTimes DefaultSessionConnection::GetTargetTimes( // Useful knowledge for analyzing traces. fml::TimePoint previous_vsync = next_vsync - vsync_interval; TRACE_DURATION( - "flutter", "DefaultSessionConnection::GetTargetTimes", - "previous_vsync(ms)", previous_vsync.ToEpochDelta().ToMilliseconds(), - "last_targeted(ms)", last_targeted_vsync.ToEpochDelta().ToMilliseconds(), - "now(ms)", fml::TimePoint::Now().ToEpochDelta().ToMilliseconds(), - "next_vsync(ms))", next_vsync.ToEpochDelta().ToMilliseconds(), - "frame_start_time(ms)", frame_start_time.ToEpochDelta().ToMilliseconds(), - "frame_end_time(ms)", frame_end_time.ToEpochDelta().ToMilliseconds()); + "flutter", "GfxSessionConnection::GetTargetTimes", "previous_vsync(ms)", + previous_vsync.ToEpochDelta().ToMilliseconds(), "last_targeted(ms)", + last_targeted_vsync.ToEpochDelta().ToMilliseconds(), "now(ms)", + now.ToEpochDelta().ToMilliseconds(), "next_vsync(ms))", + next_vsync.ToEpochDelta().ToMilliseconds(), "frame_start_time(ms)", + frame_start_time.ToEpochDelta().ToMilliseconds(), "frame_end_time(ms)", + frame_end_time.ToEpochDelta().ToMilliseconds()); return {frame_start_time, frame_end_time}; } -fml::TimePoint DefaultSessionConnection::CalculateNextLatchPoint( +fml::TimePoint GfxSessionConnection::CalculateNextLatchPoint( fml::TimePoint present_requested_time, fml::TimePoint now, fml::TimePoint last_latch_point_targeted, @@ -115,6 +125,7 @@ fml::TimePoint DefaultSessionConnection::CalculateNextLatchPoint( // Scenic, so aim for the smallest safe value. return minimum_latch_point_to_target; } + /// Returns the system time at which the next frame is likely to be presented. /// /// Consider the following scenarios, where in both the @@ -142,7 +153,7 @@ fml::TimePoint DefaultSessionConnection::CalculateNextLatchPoint( /// | +>now /// | /// +->last_presentation_time -fml::TimePoint DefaultSessionConnection::SnapToNextPhase( +fml::TimePoint GfxSessionConnection::SnapToNextPhase( const fml::TimePoint now, const fml::TimePoint last_frame_presentation_time, const fml::TimeDelta presentation_interval) { @@ -153,7 +164,7 @@ fml::TimePoint DefaultSessionConnection::SnapToNextPhase( return now; } - if (last_frame_presentation_time >= now) { + if (last_frame_presentation_time > now) { FML_LOG(WARNING) << "Last frame was presented in the future. Clamping to now."; return now + presentation_interval; @@ -173,16 +184,16 @@ fml::TimePoint DefaultSessionConnection::SnapToNextPhase( } } -DefaultSessionConnection::DefaultSessionConnection( +GfxSessionConnection::GfxSessionConnection( std::string debug_label, + inspect::Node inspect_node, fidl::InterfaceHandle session, fml::closure session_error_callback, on_frame_presented_event on_frame_presented_callback, uint64_t max_frames_in_flight, fml::TimeDelta vsync_offset) : session_wrapper_(session.Bind(), nullptr), - inspect_node_( - dart_utils::RootInspectNode::CreateRootChild("vsync_stats")), + inspect_node_(std::move(inspect_node)), secondary_vsyncs_completed_( inspect_node_.CreateUint("SecondaryVsyncsCompleted", 0u)), vsyncs_requested_(inspect_node_.CreateUint("VsyncsRequested", 0u)), @@ -206,6 +217,7 @@ DefaultSessionConnection::DefaultSessionConnection( kMaxFramesInFlight(max_frames_in_flight), vsync_offset_(vsync_offset) { FML_CHECK(kMaxFramesInFlight > 0); + last_presentation_time_ = Now(); next_presentation_info_.set_presentation_time(0); @@ -272,19 +284,19 @@ DefaultSessionConnection::DefaultSessionConnection( PresentSession(); }); - FML_LOG(INFO) << "Flutter DefaultSessionConnection: Set vsync_offset to " + FML_LOG(INFO) << "Flutter GfxSessionConnection: Set vsync_offset to " << vsync_offset_.ToMicroseconds() << "us"; } -DefaultSessionConnection::~DefaultSessionConnection() = default; +GfxSessionConnection::~GfxSessionConnection() = default; -void DefaultSessionConnection::Present() { +void GfxSessionConnection::Present() { std::lock_guard lock(mutex_); - TRACE_DURATION("gfx", "DefaultSessionConnection::Present", "frames_in_flight", + TRACE_DURATION("gfx", "GfxSessionConnection::Present", "frames_in_flight", frames_in_flight_, "max_frames_in_flight", kMaxFramesInFlight); - TRACE_FLOW_BEGIN("gfx", "DefaultSessionConnection::PresentSession", + TRACE_FLOW_BEGIN("gfx", "GfxSessionConnection::PresentSession", next_present_session_trace_id_); ++next_present_session_trace_id_; @@ -314,9 +326,9 @@ void DefaultSessionConnection::Present() { } } -void DefaultSessionConnection::AwaitVsync(FireCallbackCallback callback) { +void GfxSessionConnection::AwaitVsync(FireCallbackCallback callback) { std::lock_guard lock(mutex_); - TRACE_DURATION("flutter", "DefaultSessionConnection::AwaitVsync"); + TRACE_DURATION("flutter", "GfxSessionConnection::AwaitVsync"); fire_callback_ = callback; // Flutter is requesting a vsync here, so mark it as such. @@ -331,11 +343,11 @@ void DefaultSessionConnection::AwaitVsync(FireCallbackCallback callback) { FireCallbackMaybe(); } -void DefaultSessionConnection::AwaitVsyncForSecondaryCallback( +void GfxSessionConnection::AwaitVsyncForSecondaryCallback( FireCallbackCallback callback) { std::lock_guard lock(mutex_); TRACE_DURATION("flutter", - "DefaultSessionConnection::AwaitVsyncForSecondaryCallback"); + "GfxSessionConnection::AwaitVsyncForSecondaryCallback"); fire_callback_ = callback; // Flutter is requesting a secondary vsync here, so mark it as such. @@ -352,13 +364,13 @@ void DefaultSessionConnection::AwaitVsyncForSecondaryCallback( } // Precondition: |mutex_| is held -void DefaultSessionConnection::PresentSession() { - TRACE_DURATION("gfx", "DefaultSessionConnection::PresentSession"); +void GfxSessionConnection::PresentSession() { + TRACE_DURATION("gfx", "GfxSessionConnection::PresentSession"); present_session_pending_ = false; while (processed_present_session_trace_id_ < next_present_session_trace_id_) { - TRACE_FLOW_END("gfx", "DefaultSessionConnection::PresentSession", + TRACE_FLOW_END("gfx", "GfxSessionConnection::PresentSession", processed_present_session_trace_id_); ++processed_present_session_trace_id_; } @@ -366,16 +378,12 @@ void DefaultSessionConnection::PresentSession() { ++next_present_trace_id_; ++frames_in_flight_; - // Flush all session ops. Paint tasks may not yet have executed but those are - // fenced. The compositor can start processing ops while we finalize paint - // tasks. fml::TimeDelta presentation_interval = GetCurrentVsyncInfo().presentation_interval; fml::TimePoint next_latch_point = CalculateNextLatchPoint( - fml::TimePoint::Now(), present_requested_time_, - last_latch_point_targeted_, + Now(), present_requested_time_, last_latch_point_targeted_, fml::TimeDelta::FromMicroseconds(0), // flutter_frame_build_time presentation_interval, future_presentation_infos_); @@ -421,7 +429,7 @@ void DefaultSessionConnection::PresentSession() { // Postcondition: Either a frame is scheduled or fire_callback_request_pending_ // is set to true, meaning we will attempt to schedule a frame on the next // |OnFramePresented|. -void DefaultSessionConnection::FireCallbackMaybe() { +void GfxSessionConnection::FireCallbackMaybe() { TRACE_DURATION("flutter", "FireCallbackMaybe"); if (frames_in_flight_ < kMaxFramesInFlight) { @@ -450,13 +458,13 @@ void DefaultSessionConnection::FireCallbackMaybe() { // // A helper function for GetTargetTimes(), since many of the fields it takes // have to be derived from other state. -FlutterFrameTimes DefaultSessionConnection::GetTargetTimesHelper( +FlutterFrameTimes GfxSessionConnection::GetTargetTimesHelper( bool secondary_callback) { fml::TimeDelta presentation_interval = GetCurrentVsyncInfo().presentation_interval; fml::TimePoint next_vsync = GetCurrentVsyncInfo().presentation_time; - fml::TimePoint now = fml::TimePoint::Now(); + fml::TimePoint now = Now(); fml::TimePoint last_presentation_time = last_presentation_time_; if (next_vsync <= now) { next_vsync = @@ -470,8 +478,7 @@ FlutterFrameTimes DefaultSessionConnection::GetTargetTimesHelper( } fuchsia::scenic::scheduling::PresentationInfo - -DefaultSessionConnection::UpdatePresentationInfo( +GfxSessionConnection::UpdatePresentationInfo( fuchsia::scenic::scheduling::FuturePresentationTimes future_info, fuchsia::scenic::scheduling::PresentationInfo& presentation_info) { fuchsia::scenic::scheduling::PresentationInfo new_presentation_info; @@ -493,7 +500,7 @@ DefaultSessionConnection::UpdatePresentationInfo( } // Precondition: |mutex_| is held -VsyncInfo DefaultSessionConnection::GetCurrentVsyncInfo() const { +VsyncInfo GfxSessionConnection::GetCurrentVsyncInfo() const { return {fml::TimePoint::FromEpochDelta(fml::TimeDelta::FromNanoseconds( next_presentation_info_.presentation_time())), kDefaultPresentationInterval}; diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/default_session_connection.h b/engine/src/flutter/shell/platform/fuchsia/flutter/gfx_session_connection.h similarity index 90% rename from engine/src/flutter/shell/platform/fuchsia/flutter/default_session_connection.h rename to engine/src/flutter/shell/platform/fuchsia/flutter/gfx_session_connection.h index 7336362045e..8947f383cb4 100644 --- a/engine/src/flutter/shell/platform/fuchsia/flutter/default_session_connection.h +++ b/engine/src/flutter/shell/platform/fuchsia/flutter/gfx_session_connection.h @@ -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_DEFAULT_SESSION_CONNECTION_H_ -#define FLUTTER_SHELL_PLATFORM_FUCHSIA_DEFAULT_SESSION_CONNECTION_H_ +#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_GFX_SESSION_CONNECTION_H_ +#define FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_GFX_SESSION_CONNECTION_H_ #include #include @@ -15,6 +15,7 @@ #include "flutter/fml/closure.h" #include "flutter/fml/macros.h" +#include "fml/time/time_delta.h" #include "vsync_waiter.h" #include @@ -41,7 +42,7 @@ static constexpr fml::TimeDelta kDefaultPresentationInterval = // The component residing on the raster thread that is responsible for // maintaining the Scenic session connection and presenting node updates. -class DefaultSessionConnection final { +class GfxSessionConnection final { public: static FlutterFrameTimes GetTargetTimes(fml::TimeDelta vsync_offset, fml::TimeDelta vsync_interval, @@ -73,15 +74,16 @@ class DefaultSessionConnection final { fuchsia::scenic::scheduling::FuturePresentationTimes future_info, fuchsia::scenic::scheduling::PresentationInfo& presentation_info); - DefaultSessionConnection( + GfxSessionConnection( std::string debug_label, + inspect::Node inspect_node, fidl::InterfaceHandle session, fml::closure session_error_callback, on_frame_presented_event on_frame_presented_callback, uint64_t max_frames_in_flight, fml::TimeDelta vsync_offset); - ~DefaultSessionConnection(); + ~GfxSessionConnection(); scenic::Session* get() { return &session_wrapper_; } @@ -99,7 +101,6 @@ class DefaultSessionConnection final { void FireCallbackMaybe(); FlutterFrameTimes GetTargetTimesHelper(bool secondary_callback); - VsyncInfo GetCurrentVsyncInfo() const; scenic::Session session_wrapper_; @@ -121,10 +122,8 @@ class DefaultSessionConnection final { on_frame_presented_event on_frame_presented_callback_; - fml::TimePoint last_latch_point_targeted_ = - fml::TimePoint::FromEpochDelta(fml::TimeDelta::Zero()); - fml::TimePoint present_requested_time_ = - fml::TimePoint::FromEpochDelta(fml::TimeDelta::Zero()); + fml::TimePoint last_latch_point_targeted_; + fml::TimePoint present_requested_time_; std::deque> future_presentation_infos_ = {}; @@ -152,7 +151,7 @@ class DefaultSessionConnection final { fml::TimeDelta vsync_offset_; // Variables for recording past and future vsync info, as reported by Scenic. - fml::TimePoint last_presentation_time_ = fml::TimePoint::Now(); + fml::TimePoint last_presentation_time_; fuchsia::scenic::scheduling::PresentationInfo next_presentation_info_; // Flutter framework pipeline logic. @@ -175,9 +174,9 @@ class DefaultSessionConnection final { // thread. FireCallbackCallback fire_callback_; - FML_DISALLOW_COPY_AND_ASSIGN(DefaultSessionConnection); + FML_DISALLOW_COPY_AND_ASSIGN(GfxSessionConnection); }; } // namespace flutter_runner -#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_DEFAULT_SESSION_CONNECTION_H_ +#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_GFX_SESSION_CONNECTION_H_ diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/meta/flutter_runner_scenic_tests.cmx b/engine/src/flutter/shell/platform/fuchsia/flutter/meta/flutter_runner_scenic_tests.cmx deleted file mode 100644 index 24b894e8af5..00000000000 --- a/engine/src/flutter/shell/platform/fuchsia/flutter/meta/flutter_runner_scenic_tests.cmx +++ /dev/null @@ -1,23 +0,0 @@ -{ - "program": { - "binary": "bin/app" - }, -"sandbox": { - "features": [ - "config-data", - "deprecated-ambient-replace-as-executable", - "root-ssl-certificates", - "vulkan" - ], - "services": [ - "fuchsia.logger.LogSink", - "fuchsia.sys.Environment", - "fuchsia.sysmem.Allocator", - "fuchsia.tracing.provider.Registry", - "fuchsia.ui.input.ImeService", - "fuchsia.ui.policy.Presenter", - "fuchsia.ui.scenic.Scenic", - "fuchsia.vulkan.loader.Loader" - ] - } -} diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/tests/engine_unittests.cc b/engine/src/flutter/shell/platform/fuchsia/flutter/tests/engine_unittests.cc index 34f9acfc86e..b0778789aeb 100644 --- a/engine/src/flutter/shell/platform/fuchsia/flutter/tests/engine_unittests.cc +++ b/engine/src/flutter/shell/platform/fuchsia/flutter/tests/engine_unittests.cc @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include -#include #include #include #include @@ -14,7 +12,7 @@ #include "flutter/fml/message_loop_impl.h" #include "flutter/fml/task_runner.h" #include "flutter/shell/common/serialization_callbacks.h" -#include "flutter/shell/platform/fuchsia/flutter/default_session_connection.h" +#include "flutter/shell/platform/fuchsia/flutter/gfx_session_connection.h" #include "flutter/shell/platform/fuchsia/flutter/logging.h" #include "flutter/shell/platform/fuchsia/flutter/runner.h" #include "gtest/gtest.h" @@ -66,8 +64,9 @@ class EngineTest : public ::testing::Test { context_ = sys::ComponentContext::CreateAndServeOutgoingDirectory(); scenic_ = context_->svc()->Connect(); - scenic::Session session(scenic_.get()); - surface_producer_ = std::make_unique(&session); + session_.emplace(scenic_.get()); + surface_producer_ = + std::make_unique(&session_.value()); Engine::WarmupSkps(&concurrent_task_runner_, &raster_task_runner_, *surface_producer_, width, height, asset_manager, @@ -81,6 +80,7 @@ class EngineTest : public ::testing::Test { std::unique_ptr context_; fuchsia::ui::scenic::ScenicPtr scenic_; + std::optional session_; }; TEST_F(EngineTest, SkpWarmup) { diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/tests/fakes/BUILD.gn b/engine/src/flutter/shell/platform/fuchsia/flutter/tests/fakes/BUILD.gn index 11c88e30048..3ab5ab00f6b 100644 --- a/engine/src/flutter/shell/platform/fuchsia/flutter/tests/fakes/BUILD.gn +++ b/engine/src/flutter/shell/platform/fuchsia/flutter/tests/fakes/BUILD.gn @@ -4,7 +4,16 @@ assert(is_fuchsia) -source_set("fakes") { +group("fakes") { + testonly = true + + public_deps = [ + ":focus", + "scenic", + ] +} + +source_set("focus") { testonly = true sources = [ diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/tests/fakes/scenic/BUILD.gn b/engine/src/flutter/shell/platform/fuchsia/flutter/tests/fakes/scenic/BUILD.gn new file mode 100644 index 00000000000..0888597d26f --- /dev/null +++ b/engine/src/flutter/shell/platform/fuchsia/flutter/tests/fakes/scenic/BUILD.gn @@ -0,0 +1,24 @@ +# 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. + +assert(is_fuchsia) + +source_set("scenic") { + testonly = true + + sources = [ + "fake_session.cc", + "fake_session.h", + ] + + public_deps = [ + "//build/fuchsia/fidl:fuchsia.scenic.scheduling", + "//build/fuchsia/fidl:fuchsia.ui.gfx", + "//build/fuchsia/fidl:fuchsia.ui.scenic", + "//build/fuchsia/pkg:async-cpp", + "//build/fuchsia/pkg:async-testing", + "//build/fuchsia/pkg:fidl_cpp", + "//flutter/fml", + ] +} diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_session.cc b/engine/src/flutter/shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_session.cc new file mode 100644 index 00000000000..1b5599a614b --- /dev/null +++ b/engine/src/flutter/shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_session.cc @@ -0,0 +1,126 @@ +// 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 "fake_session.h" + +#include // For make_move_iterator + +#include "flutter/fml/logging.h" +#include "lib/async/dispatcher.h" + +namespace flutter_runner::testing { + +FakeSession::FakeSession() : binding_(this) {} + +FakeSession::SessionAndListenerClientPair FakeSession::Bind( + async_dispatcher_t* dispatcher) { + FML_CHECK(!listener_.is_bound()); + FML_CHECK(!binding_.is_bound()); + + fidl::InterfaceHandle session; + auto listener_request = listener_.NewRequest(dispatcher); + binding_.Bind(session.NewRequest(), dispatcher); + + return std::make_pair(std::move(session), std::move(listener_request)); +} + +void FakeSession::SetPresentHandler(PresentHandler present_handler) { + present_handler_ = std::move(present_handler); +} + +void FakeSession::SetPresent2Handler(Present2Handler present2_handler) { + present2_handler_ = std::move(present2_handler); +} + +void FakeSession::SetRequestPresentationTimesHandler( + RequestPresentationTimesHandler request_presentation_times_handler) { + request_presentation_times_handler_ = + std::move(request_presentation_times_handler); +} + +void FakeSession::FireOnFramePresentedEvent( + fuchsia::scenic::scheduling::FramePresentedInfo frame_presented_info) { + FML_CHECK(is_bound()); + + binding_.events().OnFramePresented(std::move(frame_presented_info)); +} + +void FakeSession::DisconnectSession() { + // Unbind the channels and drop them on the floor, simulating Scenic behavior. + binding_.Unbind(); + listener_.Unbind(); +} + +void FakeSession::Enqueue(std::vector cmds) { + // Append `cmds` to the end of the command queue, preferring to move elements + // when possible. + command_queue_.insert(command_queue_.end(), + std::make_move_iterator(cmds.begin()), + std::make_move_iterator(cmds.end())); +} + +void FakeSession::Present(uint64_t presentation_time, + std::vector acquire_fences, + std::vector release_fences, + PresentCallback callback) { + if (!present_handler_) { + return NotImplemented_("Present"); + } + + command_queue_.clear(); // TODO Process commands + + auto present_info = present_handler_( + presentation_time, std::move(acquire_fences), std::move(release_fences)); + if (callback) { + callback(std::move(present_info)); + } +} + +void FakeSession::Present2(fuchsia::ui::scenic::Present2Args args, + Present2Callback callback) { + if (!present2_handler_) { + return NotImplemented_("Present2"); + } + + command_queue_.clear(); // TODO Process commands + + auto future_presentation_times = present2_handler_(std::move(args)); + if (callback) { + callback(std::move(future_presentation_times)); + } +} + +void FakeSession::RequestPresentationTimes( + int64_t requested_prediction_span, + RequestPresentationTimesCallback callback) { + if (!request_presentation_times_handler_) { + return NotImplemented_("RequestPresentationTimes"); + } + + auto future_presentation_times = + request_presentation_times_handler_(requested_prediction_span); + if (callback) { + callback(std::move(future_presentation_times)); + } +} + +void FakeSession::RegisterBufferCollection( + uint32_t buffer_id, + fidl::InterfaceHandle token) { + NotImplemented_("RegisterBufferCollection"); // TODO +} + +void FakeSession::DeregisterBufferCollection(uint32_t buffer_id) { + NotImplemented_("DeregisterBufferCollection"); // TODO +} + +void FakeSession::SetDebugName(std::string debug_name) { + debug_name_ = std::move(debug_name); +} + +void FakeSession::NotImplemented_(const std::string& name) { + FML_LOG(FATAL) << "FakeSession does not implement " << name; +} + +} // namespace flutter_runner::testing diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_session.h b/engine/src/flutter/shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_session.h new file mode 100644 index 00000000000..e1dfa8ede3b --- /dev/null +++ b/engine/src/flutter/shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_session.h @@ -0,0 +1,121 @@ +// 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. + +#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_SESSION_H_ +#define FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_SESSION_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include // For std::pair +#include + +#include "flutter/fml/macros.h" + +namespace flutter_runner::testing { + +class FakeSession : public fuchsia::ui::scenic::testing::Session_TestBase { + public: + using PresentHandler = + std::function, + std::vector)>; + using Present2Handler = + std::function; + using RequestPresentationTimesHandler = + std::function; + using SessionAndListenerClientPair = + std::pair, + fidl::InterfaceRequest>; + + FakeSession(); + ~FakeSession() override = default; + + bool is_bound() const { return binding_.is_bound() && listener_.is_bound(); } + + const std::string& debug_name() const { return debug_name_; } + + const std::vector& command_queue() { + return command_queue_; + } + + // Bind method. Call to bind this session's FIDL channels to the |dispatcher| + // and allow processing of incoming FIDL requests. + SessionAndListenerClientPair Bind(async_dispatcher_t* dispatcher = nullptr); + + // Stub methods. Call these to set a handler for the specified FIDL calls' + // return values. + void SetPresentHandler(PresentHandler present_handler); + void SetPresent2Handler(Present2Handler present2_handler); + void SetRequestPresentationTimesHandler( + RequestPresentationTimesHandler request_presentation_times_handler); + + // Event methods. Call these to fire the associated FIDL event. + void FireOnFramePresentedEvent( + fuchsia::scenic::scheduling::FramePresentedInfo frame_presented_info); + + // Error method. Call to disconnect the session with an error. + void DisconnectSession(); + + private: + // |fuchsia::ui::scenic::Session| + void Enqueue(std::vector cmds) override; + + // |fuchsia::ui::scenic::Session| + void Present(uint64_t presentation_time, + std::vector acquire_fences, + std::vector release_fences, + PresentCallback callback) override; + + // |fuchsia::ui::scenic::Session| + void Present2(fuchsia::ui::scenic::Present2Args args, + Present2Callback callback) override; + + // |fuchsia::ui::scenic::Session| + void RequestPresentationTimes( + int64_t requested_prediction_span, + RequestPresentationTimesCallback callback) override; + + // |fuchsia::ui::scenic::Session| + void RegisterBufferCollection( + uint32_t buffer_id, + fidl::InterfaceHandle token) + override; + + // |fuchsia::ui::scenic::Session| + void DeregisterBufferCollection(uint32_t buffer_id) override; + + // |fuchsia::ui::scenic::Session| + void SetDebugName(std::string debug_name) override; + + // |fuchsia::ui::scenic::testing::Session_TestBase| + void NotImplemented_(const std::string& name) override; + + fidl::Binding binding_; + fuchsia::ui::scenic::SessionListenerPtr listener_; + + std::string debug_name_; + + std::vector command_queue_; + + PresentHandler present_handler_; + Present2Handler present2_handler_; + RequestPresentationTimesHandler request_presentation_times_handler_; + + FML_DISALLOW_COPY_AND_ASSIGN(FakeSession); +}; + +} // namespace flutter_runner::testing + +#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_SESSION_H_ diff --git a/engine/src/flutter/shell/platform/fuchsia/flutter/tests/default_session_connection_unittests.cc b/engine/src/flutter/shell/platform/fuchsia/flutter/tests/gfx_session_connection_unittests.cc similarity index 59% rename from engine/src/flutter/shell/platform/fuchsia/flutter/tests/default_session_connection_unittests.cc rename to engine/src/flutter/shell/platform/fuchsia/flutter/tests/gfx_session_connection_unittests.cc index 75b1ac41c0c..26bf6c5e69d 100644 --- a/engine/src/flutter/shell/platform/fuchsia/flutter/tests/default_session_connection_unittests.cc +++ b/engine/src/flutter/shell/platform/fuchsia/flutter/tests/gfx_session_connection_unittests.cc @@ -1,33 +1,49 @@ -// Copyright 2020 The Flutter Authors. All rights reserved. +// 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 "flutter/shell/platform/fuchsia/flutter/gfx_session_connection.h" + #include -#include #include -#include +#include +#include #include -#include "flutter/shell/platform/fuchsia/flutter/default_session_connection.h" -#include "flutter/shell/platform/fuchsia/flutter/logging.h" -#include "flutter/shell/platform/fuchsia/flutter/runner.h" +#include +#include +#include + +#include "flutter/fml/time/time_delta.h" +#include "flutter/fml/time/time_point.h" #include "gtest/gtest.h" -using namespace flutter_runner; +#include "fakes/scenic/fake_session.h" -namespace flutter_runner_test { +using fuchsia::scenic::scheduling::FramePresentedInfo; +using fuchsia::scenic::scheduling::FuturePresentationTimes; +using fuchsia::scenic::scheduling::PresentReceivedInfo; -static fml::TimePoint TimePointFromInt(int i) { +namespace flutter_runner::testing { +namespace { + +std::string GetCurrentTestName() { + return ::testing::UnitTest::GetInstance()->current_test_info()->name(); +} + +fml::TimePoint TimePointFromInt(int64_t i) { return fml::TimePoint::FromEpochDelta(fml::TimeDelta::FromNanoseconds(i)); } -static fml::TimeDelta TimeDeltaFromInt(int i) { + +fml::TimeDelta TimeDeltaFromInt(int64_t i) { return fml::TimeDelta::FromNanoseconds(i); } -static int TimePointToInt(fml::TimePoint time) { + +int64_t TimePointToInt(fml::TimePoint time) { return time.ToEpochDelta().ToNanoseconds(); } -static fuchsia::scenic::scheduling::PresentationInfo CreatePresentationInfo( +fuchsia::scenic::scheduling::PresentationInfo CreatePresentationInfo( zx_time_t latch_point, zx_time_t presentation_time) { fuchsia::scenic::scheduling::PresentationInfo info; @@ -37,209 +53,427 @@ static fuchsia::scenic::scheduling::PresentationInfo CreatePresentationInfo( return info; } -class DefaultSessionConnectionTest : public ::testing::Test { - public: - void SetUp() override { - context_ = sys::ComponentContext::CreateAndServeOutgoingDirectory(); - scenic_ = context_->svc()->Connect(); - presenter_ = context_->svc()->Connect(); +FramePresentedInfo MakeFramePresentedInfoForOnePresent( + int64_t latched_time, + int64_t frame_presented_time) { + std::vector present_infos; + present_infos.emplace_back(); + present_infos.back().set_present_received_time(0); + present_infos.back().set_latched_time(0); + return FramePresentedInfo{ + .actual_presentation_time = 0, + .presentation_infos = std::move(present_infos), + .num_presents_allowed = 1, + }; +} - FML_CHECK(ZX_OK == loop_.StartThread("DefaultSessionConnectionTestThread", - &fidl_thread_)); +void AwaitVsyncChecked(GfxSessionConnection& session_connection, + bool& condition_variable, + fml::TimeDelta expected_frame_start, + fml::TimeDelta expected_frame_end) { + session_connection.AwaitVsync( + [&condition_variable, + expected_frame_start = std::move(expected_frame_start), + expected_frame_end = std::move(expected_frame_end)]( + fml::TimePoint frame_start, fml::TimePoint frame_end) { + EXPECT_EQ(frame_start.ToEpochDelta(), expected_frame_start); + EXPECT_EQ(frame_end.ToEpochDelta(), expected_frame_end); + condition_variable = true; + }); +} - auto session_listener_request = session_listener_.NewRequest(); +}; // namespace - scenic_->CreateSession(session_.NewRequest(), session_listener_.Bind()); +class GfxSessionConnectionTest : public ::testing::Test, + public fuchsia::ui::scenic::SessionListener { + protected: + GfxSessionConnectionTest() + : session_listener_(this), session_subloop_(loop_.StartNewLoop()) { + FakeSession::SessionAndListenerClientPair session_and_listener = + fake_session().Bind(session_subloop_->dispatcher()); - // Ensure Scenic has had time to wake up before the test logic begins. - // TODO(61768) Find a better solution than sleeping periodically checking a - // condition. - int scenic_initialized = false; - scenic_->GetDisplayInfo( - [&scenic_initialized](fuchsia::ui::gfx::DisplayInfo display_info) { - scenic_initialized = true; - }); - while (!scenic_initialized) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } + session_ = std::move(session_and_listener.first); + session_listener_.Bind(std::move(session_and_listener.second)); } - // Warning: Initialization order matters here. |loop_| must be initialized - // before |SetUp()| so that we have a dispatcher already initialized. - async::Loop loop_ = async::Loop(&kAsyncLoopConfigAttachToCurrentThread); + ~GfxSessionConnectionTest() override = default; - std::unique_ptr context_; - fuchsia::ui::scenic::ScenicPtr scenic_; - fuchsia::ui::policy::PresenterPtr presenter_; + async::TestLoop& loop() { return loop_; } + + FakeSession& fake_session() { return fake_session_; } + + inspect::Node GetInspectNode() { + return inspector_.GetRoot().CreateChild("GfxSessionConnectionTest"); + } + + fidl::InterfaceHandle TakeSessionHandle() { + FML_CHECK(session_.is_valid()); + return std::move(session_); + } + + void SetUpSessionStubs( + FakeSession::RequestPresentationTimesHandler + request_presentation_times_handler = nullptr, + FakeSession::Present2Handler present_handler = nullptr) { + auto non_null_request_presentation_times_handler = + request_presentation_times_handler ? request_presentation_times_handler + : [](auto...) -> auto { + return FuturePresentationTimes{ + .future_presentations = {}, + .remaining_presents_in_flight_allowed = 1, + }; + }; + fake_session().SetRequestPresentationTimesHandler( + std::move(non_null_request_presentation_times_handler)); + + auto non_null_present_handler = + present_handler ? present_handler : [](auto...) -> auto { + return FuturePresentationTimes{ + .future_presentations = {}, + .remaining_presents_in_flight_allowed = 1, + }; + }; + fake_session().SetPresent2Handler(std::move(non_null_present_handler)); + } + + private: + // |fuchsia::ui::scenic::SessionListener| + void OnScenicError(std::string error) override { FML_CHECK(false); } + + // |fuchsia::ui::scenic::SessionListener| + void OnScenicEvent(std::vector events) override { + FML_CHECK(false); + } + + async::TestLoop loop_; + + inspect::Inspector inspector_; fidl::InterfaceHandle session_; - fidl::InterfaceHandle session_listener_; - thrd_t fidl_thread_; + fidl::Binding session_listener_; + + std::unique_ptr session_subloop_; + FakeSession fake_session_; }; -TEST_F(DefaultSessionConnectionTest, SimplePresent) { - fml::closure on_session_error_callback = []() { FML_CHECK(false); }; +TEST_F(GfxSessionConnectionTest, Initialization) { + SetUpSessionStubs(); // So we don't CHECK - uint64_t num_presents_handled = 0; - on_frame_presented_event on_frame_presented_callback = - [&num_presents_handled]( - fuchsia::scenic::scheduling::FramePresentedInfo info) { - num_presents_handled += info.presentation_infos.size(); - }; + // Create the GfxSessionConnection but don't pump the loop. No FIDL calls are + // completed yet. + const std::string debug_name = GetCurrentTestName(); + flutter_runner::GfxSessionConnection session_connection( + debug_name, GetInspectNode(), TakeSessionHandle(), + []() { FML_CHECK(false); }, [](auto...) { FML_CHECK(false); }, 1, + fml::TimeDelta::Zero()); + EXPECT_EQ(fake_session().debug_name(), ""); + EXPECT_TRUE(fake_session().command_queue().empty()); - flutter_runner::DefaultSessionConnection session_connection( - "debug label", std::move(session_), on_session_error_callback, - on_frame_presented_callback, 3, fml::TimeDelta::FromSeconds(0)); + // Simulate an AwaitVsync that comes immediately, before + // `RequestPresentationTimes` returns. + bool await_vsync_fired = false; + AwaitVsyncChecked(session_connection, await_vsync_fired, + fml::TimeDelta::Zero(), kDefaultPresentationInterval); + EXPECT_TRUE(await_vsync_fired); - for (int i = 0; i < 200; ++i) { - session_connection.Present(); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - EXPECT_GT(num_presents_handled, 0u); + // Ensure the debug name is set. + loop().RunUntilIdle(); + EXPECT_EQ(fake_session().debug_name(), debug_name); + EXPECT_TRUE(fake_session().command_queue().empty()); } -TEST_F(DefaultSessionConnectionTest, BatchedPresent) { - fml::closure on_session_error_callback = []() { FML_CHECK(false); }; +TEST_F(GfxSessionConnectionTest, SessionDisconnect) { + SetUpSessionStubs(); // So we don't CHECK - uint64_t num_presents_handled = 0; - on_frame_presented_event on_frame_presented_callback = - [&num_presents_handled]( - fuchsia::scenic::scheduling::FramePresentedInfo info) { - num_presents_handled += info.presentation_infos.size(); - }; + // Set up a callback which allows sensing of the session error state. + bool session_error_fired = false; + fml::closure on_session_error = [&session_error_fired]() { + session_error_fired = true; + }; - flutter_runner::DefaultSessionConnection session_connection( - "debug label", std::move(session_), on_session_error_callback, - on_frame_presented_callback, 3, fml::TimeDelta::FromSeconds(0)); + // Create the GfxSessionConnection but don't pump the loop. No FIDL calls are + // completed yet. + flutter_runner::GfxSessionConnection session_connection( + GetCurrentTestName(), GetInspectNode(), TakeSessionHandle(), + std::move(on_session_error), [](auto...) { FML_CHECK(false); }, 1, + fml::TimeDelta::Zero()); + EXPECT_FALSE(session_error_fired); - for (int i = 0; i < 200; ++i) { - session_connection.Present(); - if (i % 10 == 9) { - std::this_thread::sleep_for(std::chrono::milliseconds(20)); - } - } - - EXPECT_GT(num_presents_handled, 0u); + // Simulate a session disconnection, then Pump the loop. The session error + // callback will fire. + fake_session().DisconnectSession(); + loop().RunUntilIdle(); + EXPECT_TRUE(session_error_fired); } -TEST_F(DefaultSessionConnectionTest, AwaitVsync) { - fml::closure on_session_error_callback = []() { FML_CHECK(false); }; +TEST_F(GfxSessionConnectionTest, BasicPresent) { + // Set up callbacks which allow sensing of how many presents + // (`RequestPresentationTimes` or `Present` calls) were handled. + size_t request_times_called = 0u; + size_t presents_called = 0u; + SetUpSessionStubs( + [&request_times_called](auto...) -> auto { + request_times_called++; + return FuturePresentationTimes{ + .future_presentations = {}, + .remaining_presents_in_flight_allowed = 1, + }; + }, + [&presents_called](auto...) -> auto { + presents_called++; + return FuturePresentationTimes{ + .future_presentations = {}, + .remaining_presents_in_flight_allowed = 1, + }; + }); - uint64_t num_presents_handled = 0; - on_frame_presented_event on_frame_presented_callback = - [&num_presents_handled]( - fuchsia::scenic::scheduling::FramePresentedInfo info) { - num_presents_handled += info.presentation_infos.size(); - }; + // Set up a callback which allows sensing of how many vsync's + // (`OnFramePresented` events) were handled. + size_t vsyncs_handled = 0u; + on_frame_presented_event on_frame_presented = [&vsyncs_handled](auto...) { + vsyncs_handled++; + }; - flutter_runner::DefaultSessionConnection session_connection( - "debug label", std::move(session_), on_session_error_callback, - on_frame_presented_callback, 3, fml::TimeDelta::FromSeconds(0)); + // Create the GfxSessionConnection but don't pump the loop. No FIDL calls are + // completed yet. + flutter_runner::GfxSessionConnection session_connection( + GetCurrentTestName(), GetInspectNode(), TakeSessionHandle(), + []() { FML_CHECK(false); }, std::move(on_frame_presented), 1, + fml::TimeDelta::Zero()); + EXPECT_TRUE(fake_session().command_queue().empty()); + EXPECT_EQ(request_times_called, 0u); + EXPECT_EQ(presents_called, 0u); + EXPECT_EQ(vsyncs_handled, 0u); - uint64_t await_vsyncs_handled = 0; + // Pump the loop; `RequestPresentationTimes`, `Present`, and both of their + // callbacks are called. + loop().RunUntilIdle(); + EXPECT_TRUE(fake_session().command_queue().empty()); + EXPECT_EQ(request_times_called, 1u); + EXPECT_EQ(presents_called, 1u); + EXPECT_EQ(vsyncs_handled, 0u); - for (int i = 0; i < 5; ++i) { - session_connection.Present(); - session_connection.AwaitVsync( - [&await_vsyncs_handled](auto...) { await_vsyncs_handled++; }); - std::this_thread::sleep_for(std::chrono::milliseconds(20)); - } + // Fire the `OnFramePresented` event associated with the first `Present`, then + // pump the loop. The `OnFramePresented` event is resolved. + fake_session().FireOnFramePresentedEvent( + MakeFramePresentedInfoForOnePresent(0, 0)); + loop().RunUntilIdle(); + EXPECT_TRUE(fake_session().command_queue().empty()); + EXPECT_EQ(request_times_called, 1u); + EXPECT_EQ(presents_called, 1u); + EXPECT_EQ(vsyncs_handled, 1u); - EXPECT_GT(num_presents_handled, 0u); - EXPECT_GT(await_vsyncs_handled, 0u); + // Simulate an AwaitVsync that comes after the first `OnFramePresented` + // event. + bool await_vsync_fired = false; + AwaitVsyncChecked(session_connection, await_vsync_fired, + fml::TimeDelta::Zero(), kDefaultPresentationInterval); + EXPECT_TRUE(await_vsync_fired); + + // Call Present and Pump the loop; `Present` and its callback is called. + await_vsync_fired = false; + session_connection.Present(); + loop().RunUntilIdle(); + EXPECT_TRUE(fake_session().command_queue().empty()); + EXPECT_FALSE(await_vsync_fired); + EXPECT_EQ(request_times_called, 1u); + EXPECT_EQ(presents_called, 2u); + EXPECT_EQ(vsyncs_handled, 1u); + + // Fire the `OnFramePresented` event associated with the second `Present`, + // then pump the loop. The `OnFramePresented` event is resolved. + fake_session().FireOnFramePresentedEvent( + MakeFramePresentedInfoForOnePresent(0, 0)); + loop().RunUntilIdle(); + EXPECT_TRUE(fake_session().command_queue().empty()); + EXPECT_FALSE(await_vsync_fired); + EXPECT_EQ(request_times_called, 1u); + EXPECT_EQ(presents_called, 2u); + EXPECT_EQ(vsyncs_handled, 2u); + + // Simulate an AwaitVsync that comes after the second `OnFramePresented` + // event. + await_vsync_fired = false; + AwaitVsyncChecked(session_connection, await_vsync_fired, + kDefaultPresentationInterval, + kDefaultPresentationInterval * 2); + EXPECT_TRUE(await_vsync_fired); } -TEST_F(DefaultSessionConnectionTest, EnsureBackpressureForAwaitVsync) { - fml::closure on_session_error_callback = []() { FML_CHECK(false); }; +TEST_F(GfxSessionConnectionTest, AwaitVsyncBackpressure) { + // Set up a callback which allows sensing of how many presents + // (`Present` calls) were handled. + size_t presents_called = 0u; + SetUpSessionStubs( + nullptr /* request_presentation_times_handler */, + [&presents_called](auto...) -> auto { + presents_called++; + return FuturePresentationTimes{ + .future_presentations = {}, + .remaining_presents_in_flight_allowed = 1, + }; + }); - uint64_t num_presents_handled = 0; - on_frame_presented_event on_frame_presented_callback = - [&num_presents_handled]( - fuchsia::scenic::scheduling::FramePresentedInfo info) { - num_presents_handled += info.presentation_infos.size(); - }; + // Set up a callback which allows sensing of how many vsync's + // (`OnFramePresented` events) were handled. + size_t vsyncs_handled = 0u; + on_frame_presented_event on_frame_presented = [&vsyncs_handled](auto...) { + vsyncs_handled++; + }; - flutter_runner::DefaultSessionConnection session_connection( - "debug label", std::move(session_), on_session_error_callback, - on_frame_presented_callback, 0, fml::TimeDelta::FromSeconds(0)); + // Create the GfxSessionConnection but don't pump the loop. No FIDL calls are + // completed yet. + flutter_runner::GfxSessionConnection session_connection( + GetCurrentTestName(), GetInspectNode(), TakeSessionHandle(), + []() { FML_CHECK(false); }, std::move(on_frame_presented), 1, + fml::TimeDelta::Zero()); + EXPECT_EQ(presents_called, 0u); + EXPECT_EQ(vsyncs_handled, 0u); - uint64_t await_vsyncs_handled = 0; + // Pump the loop; `RequestPresentationTimes`, `Present`, and both of their + // callbacks are called. + loop().RunUntilIdle(); + EXPECT_EQ(presents_called, 1u); + EXPECT_EQ(vsyncs_handled, 0u); - for (int i = 0; i < 5; ++i) { - session_connection.Present(); - session_connection.AwaitVsync( - [&await_vsyncs_handled](auto...) { await_vsyncs_handled++; }); - std::this_thread::sleep_for(std::chrono::milliseconds(20)); - } + // Simulate an AwaitVsync that comes before the first `OnFramePresented` + // event. + bool await_vsync_fired = false; + AwaitVsyncChecked(session_connection, await_vsync_fired, + fml::TimeDelta::Zero(), kDefaultPresentationInterval); + EXPECT_FALSE(await_vsync_fired); - EXPECT_EQ(num_presents_handled, 1u); - EXPECT_EQ(await_vsyncs_handled, 0u); + // Fire the `OnFramePresented` event associated with the first `Present`, then + // pump the loop. The `OnFramePresented` event is resolved. The AwaitVsync + // callback is resolved. + fake_session().FireOnFramePresentedEvent( + MakeFramePresentedInfoForOnePresent(0, 0)); + loop().RunUntilIdle(); + EXPECT_TRUE(await_vsync_fired); + EXPECT_EQ(presents_called, 1u); + EXPECT_EQ(vsyncs_handled, 1u); + + // Simulate an AwaitVsync that comes before the second `Present`. + await_vsync_fired = false; + AwaitVsyncChecked(session_connection, await_vsync_fired, + kDefaultPresentationInterval, + kDefaultPresentationInterval * 2); + EXPECT_TRUE(await_vsync_fired); + + // Call Present and Pump the loop; `Present` and its callback is called. + await_vsync_fired = false; + session_connection.Present(); + loop().RunUntilIdle(); + EXPECT_FALSE(await_vsync_fired); + EXPECT_EQ(presents_called, 2u); + EXPECT_EQ(vsyncs_handled, 1u); + + // Simulate an AwaitVsync that comes before the second `OnFramePresented` + // event. + await_vsync_fired = false; + AwaitVsyncChecked(session_connection, await_vsync_fired, + kDefaultPresentationInterval * 2, + kDefaultPresentationInterval * 3); + EXPECT_FALSE(await_vsync_fired); + + // Fire the `OnFramePresented` event associated with the second `Present`, + // then pump the loop. The `OnFramePresented` event is resolved. + fake_session().FireOnFramePresentedEvent( + MakeFramePresentedInfoForOnePresent(0, 0)); + loop().RunUntilIdle(); + EXPECT_TRUE(await_vsync_fired); + EXPECT_EQ(presents_called, 2u); + EXPECT_EQ(vsyncs_handled, 2u); } -TEST_F(DefaultSessionConnectionTest, SecondaryCallbackShouldFireRegardless) { - fml::closure on_session_error_callback = []() { FML_CHECK(false); }; +TEST_F(GfxSessionConnectionTest, PresentBackpressure) { + // Set up a callback which allows sensing of how many presents + // (`Present` calls) were handled. + size_t presents_called = 0u; + SetUpSessionStubs( + nullptr /* request_presentation_times_handler */, + [&presents_called](auto...) -> auto { + presents_called++; + return FuturePresentationTimes{ + .future_presentations = {}, + .remaining_presents_in_flight_allowed = 1, + }; + }); - uint64_t num_presents_handled = 0; - on_frame_presented_event on_frame_presented_callback = - [&num_presents_handled]( - fuchsia::scenic::scheduling::FramePresentedInfo info) { - num_presents_handled += info.presentation_infos.size(); - }; + // Set up a callback which allows sensing of how many vsync's + // (`OnFramePresented` events) were handled. + size_t vsyncs_handled = 0u; + on_frame_presented_event on_frame_presented = [&vsyncs_handled](auto...) { + vsyncs_handled++; + }; - flutter_runner::DefaultSessionConnection session_connection( - "debug label", std::move(session_), on_session_error_callback, - on_frame_presented_callback, 0, fml::TimeDelta::FromSeconds(0)); + // Create the GfxSessionConnection but don't pump the loop. No FIDL calls are + // completed yet. + flutter_runner::GfxSessionConnection session_connection( + GetCurrentTestName(), GetInspectNode(), TakeSessionHandle(), + []() { FML_CHECK(false); }, std::move(on_frame_presented), 1, + fml::TimeDelta::Zero()); + EXPECT_EQ(presents_called, 0u); + EXPECT_EQ(vsyncs_handled, 0u); - // We're going to expect *only* secondary callbacks to be triggered. - uint64_t await_vsyncs_handled = 0; - uint64_t await_vsync_for_secondary_callbacks_handled = 0; + // Pump the loop; `RequestPresentationTimes`, `Present`, and both of their + // callbacks are called. + loop().RunUntilIdle(); + EXPECT_EQ(presents_called, 1u); + EXPECT_EQ(vsyncs_handled, 0u); - for (int i = 0; i < 5; ++i) { - session_connection.Present(); - session_connection.AwaitVsync( - [&await_vsyncs_handled](auto...) { await_vsyncs_handled++; }); - session_connection.AwaitVsyncForSecondaryCallback( - [&await_vsync_for_secondary_callbacks_handled](auto...) { - await_vsync_for_secondary_callbacks_handled++; - }); - std::this_thread::sleep_for(std::chrono::milliseconds(20)); - } + // Call Present and Pump the loop; `Present` is not called due to backpressue. + session_connection.Present(); + loop().RunUntilIdle(); + EXPECT_EQ(presents_called, 1u); + EXPECT_EQ(vsyncs_handled, 0u); - EXPECT_EQ(num_presents_handled, 1u); - EXPECT_EQ(await_vsyncs_handled, 0u); - EXPECT_GT(await_vsync_for_secondary_callbacks_handled, 0u); -} + // Call Present again and Pump the loop; `Present` is not called due to + // backpressue. + session_connection.Present(); + loop().RunUntilIdle(); + EXPECT_EQ(presents_called, 1u); + EXPECT_EQ(vsyncs_handled, 0u); -TEST_F(DefaultSessionConnectionTest, AwaitVsyncBackpressureRelief) { - fml::closure on_session_error_callback = []() { FML_CHECK(false); }; + // Fire the `OnFramePresented` event associated with the first `Present`, then + // pump the loop. The `OnFramePresented` event is resolved. The pending + // `Present` calls are resolved. + fake_session().FireOnFramePresentedEvent( + MakeFramePresentedInfoForOnePresent(0, 0)); + loop().RunUntilIdle(); + EXPECT_EQ(presents_called, 2u); + EXPECT_EQ(vsyncs_handled, 1u); - uint64_t num_presents_handled = 0; - on_frame_presented_event on_frame_presented_callback = - [&num_presents_handled]( - fuchsia::scenic::scheduling::FramePresentedInfo info) { - num_presents_handled += info.presentation_infos.size(); - }; + // Call Present and Pump the loop; `Present` is not called due to + // backpressue. + session_connection.Present(); + loop().RunUntilIdle(); + EXPECT_EQ(presents_called, 2u); + EXPECT_EQ(vsyncs_handled, 1u); - flutter_runner::DefaultSessionConnection session_connection( - "debug label", std::move(session_), on_session_error_callback, - on_frame_presented_callback, 1, fml::TimeDelta::FromSeconds(0)); + // Call Present again and Pump the loop; `Present` is not called due to + // backpressue. + session_connection.Present(); + loop().RunUntilIdle(); + EXPECT_EQ(presents_called, 2u); + EXPECT_EQ(vsyncs_handled, 1u); - uint64_t await_vsyncs_handled = 0; + // Fire the `OnFramePresented` event associated with the second `Present`, + // then pump the loop. The `OnFramePresented` event is resolved. The pending + // `Present` calls are resolved. + fake_session().FireOnFramePresentedEvent( + MakeFramePresentedInfoForOnePresent(0, 0)); + loop().RunUntilIdle(); + EXPECT_EQ(presents_called, 3u); + EXPECT_EQ(vsyncs_handled, 2u); - // Max out our present budget. - for (int i = 0; i < 5; ++i) { - session_connection.Present(); - } - - // AwaitVsyncs(). - for (int i = 0; i < 5; ++i) { - session_connection.AwaitVsync( - [&await_vsyncs_handled](auto...) { await_vsyncs_handled++; }); - std::this_thread::sleep_for(std::chrono::milliseconds(20)); - } - - EXPECT_GT(num_presents_handled, 0u); - EXPECT_GT(await_vsyncs_handled, 0u); + // Fire the `OnFramePresented` event associated with the third `Present`, + // then pump the loop. The `OnFramePresented` event is resolved. No pending + // `Present` calls exist, so none are resolved. + fake_session().FireOnFramePresentedEvent( + MakeFramePresentedInfoForOnePresent(0, 0)); + loop().RunUntilIdle(); + EXPECT_EQ(presents_called, 3u); + EXPECT_EQ(vsyncs_handled, 3u); } // The first set of tests has an empty |future_presentation_infos| passed in. @@ -260,7 +494,7 @@ TEST(CalculateNextLatchPointTest, PresentAsSoonAsPossible) { EXPECT_GT(vsync_interval, TimeDeltaFromInt(0)); fml::TimePoint calculated_latch_point = - DefaultSessionConnection::CalculateNextLatchPoint( + GfxSessionConnection::CalculateNextLatchPoint( present_requested_time, now, last_latch_point_targeted, flutter_frame_build_time, vsync_interval, future_presentation_infos); @@ -291,7 +525,7 @@ TEST(CalculateNextLatchPointTest, LongFrameBuildTime) { EXPECT_GT(flutter_frame_build_time, vsync_interval); fml::TimePoint calculated_latch_point = - DefaultSessionConnection::CalculateNextLatchPoint( + GfxSessionConnection::CalculateNextLatchPoint( present_requested_time, now, last_latch_point_targeted, flutter_frame_build_time, vsync_interval, future_presentation_infos); @@ -324,7 +558,7 @@ TEST(CalculateNextLatchPointTest, DelayedPresentRequestWithLongFrameBuildTime) { EXPECT_GT(now, present_requested_time + vsync_interval); fml::TimePoint calculated_latch_point = - DefaultSessionConnection::CalculateNextLatchPoint( + GfxSessionConnection::CalculateNextLatchPoint( present_requested_time, now, last_latch_point_targeted, flutter_frame_build_time, vsync_interval, future_presentation_infos); @@ -355,7 +589,7 @@ TEST(CalculateNextLatchPointTest, LastLastPointTargetedLate) { EXPECT_GT(last_latch_point_targeted, present_requested_time); fml::TimePoint calculated_latch_point = - DefaultSessionConnection::CalculateNextLatchPoint( + GfxSessionConnection::CalculateNextLatchPoint( present_requested_time, now, last_latch_point_targeted, flutter_frame_build_time, vsync_interval, future_presentation_infos); @@ -395,7 +629,7 @@ TEST(CalculateNextLatchPointTest, SteadyState_OnTimeFrames) { EXPECT_GT(vsync_interval, TimeDeltaFromInt(0)); fml::TimePoint calculated_latch_point = - DefaultSessionConnection::CalculateNextLatchPoint( + GfxSessionConnection::CalculateNextLatchPoint( present_requested_time, now, last_latch_point_targeted, flutter_frame_build_time, vsync_interval, future_presentation_infos); @@ -434,7 +668,7 @@ TEST(CalculateNextLatchPointTest, SteadyState_LongFrameBuildTimes) { EXPECT_GT(flutter_frame_build_time, vsync_interval); fml::TimePoint calculated_latch_point = - DefaultSessionConnection::CalculateNextLatchPoint( + GfxSessionConnection::CalculateNextLatchPoint( present_requested_time, now, last_latch_point_targeted, flutter_frame_build_time, vsync_interval, future_presentation_infos); @@ -473,7 +707,7 @@ TEST(CalculateNextLatchPointTest, SteadyState_LateLastLatchPointTargeted) { EXPECT_GT(last_latch_point_targeted, now + vsync_interval); fml::TimePoint calculated_latch_point = - DefaultSessionConnection::CalculateNextLatchPoint( + GfxSessionConnection::CalculateNextLatchPoint( present_requested_time, now, last_latch_point_targeted, flutter_frame_build_time, vsync_interval, future_presentation_infos); @@ -512,7 +746,7 @@ TEST(CalculateNextLatchPointTest, EXPECT_GT(now, present_requested_time + vsync_interval); fml::TimePoint calculated_latch_point = - DefaultSessionConnection::CalculateNextLatchPoint( + GfxSessionConnection::CalculateNextLatchPoint( present_requested_time, now, last_latch_point_targeted, flutter_frame_build_time, vsync_interval, future_presentation_infos); @@ -548,7 +782,7 @@ TEST(CalculateNextLatchPointTest, SteadyState_FuzzyLatchPointsBeforeTarget) { EXPECT_GT(vsync_interval, TimeDeltaFromInt(0)); fml::TimePoint calculated_latch_point = - DefaultSessionConnection::CalculateNextLatchPoint( + GfxSessionConnection::CalculateNextLatchPoint( present_requested_time, now, last_latch_point_targeted, flutter_frame_build_time, vsync_interval, future_presentation_infos); @@ -584,7 +818,7 @@ TEST(CalculateNextLatchPointTest, SteadyState_FuzzyLatchPointsAfterTarget) { EXPECT_GT(vsync_interval, TimeDeltaFromInt(0)); fml::TimePoint calculated_latch_point = - DefaultSessionConnection::CalculateNextLatchPoint( + GfxSessionConnection::CalculateNextLatchPoint( present_requested_time, now, last_latch_point_targeted, flutter_frame_build_time, vsync_interval, future_presentation_infos); @@ -604,9 +838,8 @@ TEST(SnapToNextPhaseTest, SnapOverlapsWithNow) { const auto now = fml::TimePoint::Now(); const auto last_presentation_time = now - fml::TimeDelta::FromNanoseconds(10); const auto delta = fml::TimeDelta::FromNanoseconds(10); - const auto next_vsync = - flutter_runner::DefaultSessionConnection::SnapToNextPhase( - now, last_presentation_time, delta); + const auto next_vsync = flutter_runner::GfxSessionConnection::SnapToNextPhase( + now, last_presentation_time, delta); EXPECT_EQ(now + delta, next_vsync); } @@ -615,9 +848,8 @@ TEST(SnapToNextPhaseTest, SnapAfterNow) { const auto now = fml::TimePoint::Now(); const auto last_presentation_time = now - fml::TimeDelta::FromNanoseconds(9); const auto delta = fml::TimeDelta::FromNanoseconds(10); - const auto next_vsync = - flutter_runner::DefaultSessionConnection::SnapToNextPhase( - now, last_presentation_time, delta); + const auto next_vsync = flutter_runner::GfxSessionConnection::SnapToNextPhase( + now, last_presentation_time, delta); // math here: 10 - 9 = 1 EXPECT_EQ(now + fml::TimeDelta::FromNanoseconds(1), next_vsync); @@ -627,9 +859,8 @@ TEST(SnapToNextPhaseTest, SnapAfterNowMultiJump) { const auto now = fml::TimePoint::Now(); const auto last_presentation_time = now - fml::TimeDelta::FromNanoseconds(34); const auto delta = fml::TimeDelta::FromNanoseconds(10); - const auto next_vsync = - flutter_runner::DefaultSessionConnection::SnapToNextPhase( - now, last_presentation_time, delta); + const auto next_vsync = flutter_runner::GfxSessionConnection::SnapToNextPhase( + now, last_presentation_time, delta); // zeroes: -34, -24, -14, -4, 6, ... EXPECT_EQ(now + fml::TimeDelta::FromNanoseconds(6), next_vsync); @@ -639,9 +870,8 @@ TEST(SnapToNextPhaseTest, SnapAfterNowMultiJumpAccountForCeils) { const auto now = fml::TimePoint::Now(); const auto last_presentation_time = now - fml::TimeDelta::FromNanoseconds(20); const auto delta = fml::TimeDelta::FromNanoseconds(16); - const auto next_vsync = - flutter_runner::DefaultSessionConnection::SnapToNextPhase( - now, last_presentation_time, delta); + const auto next_vsync = flutter_runner::GfxSessionConnection::SnapToNextPhase( + now, last_presentation_time, delta); // zeroes: -20, -4, 12, 28, ... EXPECT_EQ(now + fml::TimeDelta::FromNanoseconds(12), next_vsync); @@ -655,7 +885,7 @@ TEST(GetTargetTimesTest, ScheduleForNextVsync) { const fml::TimePoint next_vsync = TimePointFromInt(10); const auto target_times = - flutter_runner::DefaultSessionConnection::GetTargetTimes( + flutter_runner::GfxSessionConnection::GetTargetTimes( vsync_offset, vsync_interval, last_targeted_vsync, now, next_vsync); EXPECT_EQ(TimePointToInt(target_times.frame_start), 10); @@ -670,7 +900,7 @@ TEST(GetTargetTimesTest, ScheduleForCurrentVsync_DueToOffset) { const fml::TimePoint next_vsync = TimePointFromInt(10); const auto target_times = - flutter_runner::DefaultSessionConnection::GetTargetTimes( + flutter_runner::GfxSessionConnection::GetTargetTimes( vsync_offset, vsync_interval, last_targeted_vsync, now, next_vsync); EXPECT_EQ(TimePointToInt(target_times.frame_start), 7); @@ -685,7 +915,7 @@ TEST(GetTargetTimesTest, ScheduleForFollowingVsync_BecauseOfNow) { const fml::TimePoint next_vsync = TimePointFromInt(10); const auto target_times = - flutter_runner::DefaultSessionConnection::GetTargetTimes( + flutter_runner::GfxSessionConnection::GetTargetTimes( vsync_offset, vsync_interval, last_targeted_vsync, now, next_vsync); EXPECT_EQ(TimePointToInt(target_times.frame_start), 20); @@ -700,7 +930,7 @@ TEST(GetTargetTimesTest, ScheduleForFollowingVsync_BecauseOfTargettedTime) { const fml::TimePoint next_vsync = TimePointFromInt(10); const auto target_times = - flutter_runner::DefaultSessionConnection::GetTargetTimes( + flutter_runner::GfxSessionConnection::GetTargetTimes( vsync_offset, vsync_interval, last_targeted_vsync, now, next_vsync); EXPECT_EQ(TimePointToInt(target_times.frame_start), 20); @@ -715,7 +945,7 @@ TEST(GetTargetTimesTest, ScheduleForDistantVsync_BecauseOfTargettedTime) { const fml::TimePoint next_vsync = TimePointFromInt(10); const auto target_times = - flutter_runner::DefaultSessionConnection::GetTargetTimes( + flutter_runner::GfxSessionConnection::GetTargetTimes( vsync_offset, vsync_interval, last_targeted_vsync, now, next_vsync); EXPECT_EQ(TimePointToInt(target_times.frame_start), 60); @@ -733,7 +963,7 @@ TEST(GetTargetTimesTest, ScheduleForFollowingVsync_WithSlightVsyncDrift) { const fml::TimePoint next_vsync = TimePointFromInt(10); const auto target_times = - flutter_runner::DefaultSessionConnection::GetTargetTimes( + flutter_runner::GfxSessionConnection::GetTargetTimes( vsync_offset, vsync_interval, last_targeted_vsync, now, next_vsync); EXPECT_EQ(TimePointToInt(target_times.frame_start), 40); @@ -748,7 +978,7 @@ TEST(GetTargetTimesTest, ScheduleForAnOffsetFromVsync) { const fml::TimePoint next_vsync = TimePointFromInt(10); const auto target_times = - flutter_runner::DefaultSessionConnection::GetTargetTimes( + flutter_runner::GfxSessionConnection::GetTargetTimes( vsync_offset, vsync_interval, last_targeted_vsync, now, next_vsync); EXPECT_EQ(TimePointToInt(target_times.frame_start), 16); @@ -765,7 +995,7 @@ TEST(GetTargetTimesTest, ScheduleMultipleTimes) { for (int i = 0; i < 100; ++i) { const auto target_times = - flutter_runner::DefaultSessionConnection::GetTargetTimes( + flutter_runner::GfxSessionConnection::GetTargetTimes( vsync_offset, vsync_interval, last_targeted_vsync, now, next_vsync); EXPECT_EQ(TimePointToInt(target_times.frame_start), 10 * (i + 1)); @@ -780,7 +1010,7 @@ TEST(GetTargetTimesTest, ScheduleMultipleTimes) { TEST(GetTargetTimesTest, ScheduleMultipleTimes_WithDelayedWakeups) { // It is often the case that Flutter does not wake up when it intends to due - // to CPU contention. This test has DefaultSessionConnection wake up to + // to CPU contention. This test has GfxSessionConnection wake up to // schedule 0-4ns after when |now| should be - and we verify that the results // should be the same as if there were no delay. const fml::TimeDelta vsync_offset = TimeDeltaFromInt(0); @@ -792,11 +1022,11 @@ TEST(GetTargetTimesTest, ScheduleMultipleTimes_WithDelayedWakeups) { for (int i = 0; i < 100; ++i) { const auto target_times = - flutter_runner::DefaultSessionConnection::GetTargetTimes( + flutter_runner::GfxSessionConnection::GetTargetTimes( vsync_offset, vsync_interval, last_targeted_vsync, now, next_vsync); const auto target_times_delay = - flutter_runner::DefaultSessionConnection::GetTargetTimes( + flutter_runner::GfxSessionConnection::GetTargetTimes( vsync_offset, vsync_interval, last_targeted_vsync, now + TimeDeltaFromInt(i % 5), next_vsync); @@ -811,9 +1041,6 @@ TEST(GetTargetTimesTest, ScheduleMultipleTimes_WithDelayedWakeups) { last_targeted_vsync = target_times.frame_target; } } -// static fuchsia::scenic::scheduling::PresentationInfo UpdatePresentationInfo( -// fuchsia::scenic::scheduling::FuturePresentationTimes future_info, -// fuchsia::scenic::scheduling::PresentationInfo& presentation_info); TEST(UpdatePresentationInfoTest, SingleUpdate) { std::vector @@ -831,7 +1058,7 @@ TEST(UpdatePresentationInfoTest, SingleUpdate) { presentation_info.set_presentation_time(0); fuchsia::scenic::scheduling::PresentationInfo new_presentation_info = - flutter_runner::DefaultSessionConnection::UpdatePresentationInfo( + flutter_runner::GfxSessionConnection::UpdatePresentationInfo( std::move(future_info), presentation_info); EXPECT_EQ(new_presentation_info.presentation_time(), 10); @@ -854,7 +1081,7 @@ TEST(UpdatePresentationInfoTest, MultipleUpdates) { presentation_info.set_presentation_time(0); fuchsia::scenic::scheduling::PresentationInfo new_presentation_info = - flutter_runner::DefaultSessionConnection::UpdatePresentationInfo( + flutter_runner::GfxSessionConnection::UpdatePresentationInfo( std::move(future_info), presentation_info); EXPECT_EQ(new_presentation_info.presentation_time(), 20); @@ -873,10 +1100,10 @@ TEST(UpdatePresentationInfoTest, MultipleUpdates) { future_info.remaining_presents_in_flight_allowed = 1; new_presentation_info = - flutter_runner::DefaultSessionConnection::UpdatePresentationInfo( + flutter_runner::GfxSessionConnection::UpdatePresentationInfo( std::move(future_info), new_presentation_info); EXPECT_EQ(new_presentation_info.presentation_time(), 30); } -} // namespace flutter_runner_test +} // namespace flutter_runner::testing diff --git a/engine/src/flutter/testing/fuchsia/test_suites.yaml b/engine/src/flutter/testing/fuchsia/test_suites.yaml index 4ccf39b3c4d..eaa86975494 100644 --- a/engine/src/flutter/testing/fuchsia/test_suites.yaml +++ b/engine/src/flutter/testing/fuchsia/test_suites.yaml @@ -25,5 +25,3 @@ # Legacy v1 components. - package: flutter_runner_tests-0.far test_command: run-test-component fuchsia-pkg://fuchsia.com/flutter_runner_tests#meta/flutter_runner_tests.cmx -- package: flutter_runner_scenic_tests-0.far - test_command: run-test-component fuchsia-pkg://fuchsia.com/flutter_runner_scenic_tests#meta/flutter_runner_scenic_tests.cmx -- --gtest_filter=-DefaultSessionConnectionTest.*:CalculateNextLatchPointTest.* diff --git a/engine/src/flutter/tools/fuchsia/all_packages.list b/engine/src/flutter/tools/fuchsia/all_packages.list index 5342cc5e889..4ef7a39fb37 100644 --- a/engine/src/flutter/tools/fuchsia/all_packages.list +++ b/engine/src/flutter/tools/fuchsia/all_packages.list @@ -4,7 +4,6 @@ out/fuchsia_debug_x64/embedder_tests_package_manifest.json out/fuchsia_debug_x64/flow_tests_package_manifest.json out/fuchsia_debug_x64/flutter_aot_runner_package_manifest.json out/fuchsia_debug_x64/flutter_jit_runner_package_manifest.json -out/fuchsia_debug_x64/flutter_runner_scenic_tests_package_manifest.json out/fuchsia_debug_x64/flutter_runner_tests_package_manifest.json out/fuchsia_debug_x64/flutter_runner_tzdata_tests_package_manifest.json out/fuchsia_debug_x64/fml_tests_package_manifest.json @@ -19,7 +18,6 @@ out/fuchsia_release_x64/embedder_tests_package_manifest.json out/fuchsia_release_x64/flow_tests_package_manifest.json out/fuchsia_release_x64/flutter_aot_runner_package_manifest.json out/fuchsia_release_x64/flutter_jit_runner_package_manifest.json -out/fuchsia_release_x64/flutter_runner_scenic_tests_package_manifest.json out/fuchsia_release_x64/flutter_runner_tests_package_manifest.json out/fuchsia_release_x64/flutter_runner_tzdata_tests_package_manifest.json out/fuchsia_release_x64/fml_tests_package_manifest.json @@ -34,7 +32,6 @@ out/fuchsia_profile_x64/embedder_tests_package_manifest.json out/fuchsia_profile_x64/flow_tests_package_manifest.json out/fuchsia_profile_x64/flutter_aot_runner_package_manifest.json out/fuchsia_profile_x64/flutter_jit_runner_package_manifest.json -out/fuchsia_profile_x64/flutter_runner_scenic_tests_package_manifest.json out/fuchsia_profile_x64/flutter_runner_tests_package_manifest.json out/fuchsia_profile_x64/flutter_runner_tzdata_tests_package_manifest.json out/fuchsia_profile_x64/fml_tests_package_manifest.json @@ -49,7 +46,6 @@ out/fuchsia_debug_arm64/embedder_tests_package_manifest.json out/fuchsia_debug_arm64/flow_tests_package_manifest.json out/fuchsia_debug_arm64/flutter_aot_runner_package_manifest.json out/fuchsia_debug_arm64/flutter_jit_runner_package_manifest.json -out/fuchsia_debug_arm64/flutter_runner_scenic_tests_package_manifest.json out/fuchsia_debug_arm64/flutter_runner_tests_package_manifest.json out/fuchsia_debug_arm64/flutter_runner_tzdata_tests_package_manifest.json out/fuchsia_debug_arm64/fml_tests_package_manifest.json @@ -64,7 +60,6 @@ out/fuchsia_release_arm64/embedder_tests_package_manifest.json out/fuchsia_release_arm64/flow_tests_package_manifest.json out/fuchsia_release_arm64/flutter_aot_runner_package_manifest.json out/fuchsia_release_arm64/flutter_jit_runner_package_manifest.json -out/fuchsia_release_arm64/flutter_runner_scenic_tests_package_manifest.json out/fuchsia_release_arm64/flutter_runner_tests_package_manifest.json out/fuchsia_release_arm64/flutter_runner_tzdata_tests_package_manifest.json out/fuchsia_release_arm64/fml_tests_package_manifest.json @@ -79,7 +74,6 @@ out/fuchsia_profile_arm64/embedder_tests_package_manifest.json out/fuchsia_profile_arm64/flow_tests_package_manifest.json out/fuchsia_profile_arm64/flutter_aot_runner_package_manifest.json out/fuchsia_profile_arm64/flutter_jit_runner_package_manifest.json -out/fuchsia_profile_arm64/flutter_runner_scenic_tests_package_manifest.json out/fuchsia_profile_arm64/flutter_runner_tests_package_manifest.json out/fuchsia_profile_arm64/flutter_runner_tzdata_tests_package_manifest.json out/fuchsia_profile_arm64/fml_tests_package_manifest.json