Skip to content

Commit aac33d1

Browse files
authored
Reland "Smooth out iOS irregular input events delivery (flutter#11817)" (flutter#12280)
Additionally, we now use the engine directly as a delegate instead of storing potentially dead runtime_controller. Unit tests have been updated to include an engine restart check which would fail before the fix. This fixes flutter#40303
1 parent 968c3aa commit aac33d1

15 files changed

+667
-50
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ FILE: ../../../flutter/shell/common/canvas_spy_unittests.cc
485485
FILE: ../../../flutter/shell/common/engine.cc
486486
FILE: ../../../flutter/shell/common/engine.h
487487
FILE: ../../../flutter/shell/common/fixtures/shell_test.dart
488+
FILE: ../../../flutter/shell/common/input_events_unittests.cc
488489
FILE: ../../../flutter/shell/common/isolate_configuration.cc
489490
FILE: ../../../flutter/shell/common/isolate_configuration.h
490491
FILE: ../../../flutter/shell/common/persistent_cache.cc
@@ -494,6 +495,8 @@ FILE: ../../../flutter/shell/common/pipeline.h
494495
FILE: ../../../flutter/shell/common/pipeline_unittests.cc
495496
FILE: ../../../flutter/shell/common/platform_view.cc
496497
FILE: ../../../flutter/shell/common/platform_view.h
498+
FILE: ../../../flutter/shell/common/pointer_data_dispatcher.cc
499+
FILE: ../../../flutter/shell/common/pointer_data_dispatcher.h
497500
FILE: ../../../flutter/shell/common/rasterizer.cc
498501
FILE: ../../../flutter/shell/common/rasterizer.h
499502
FILE: ../../../flutter/shell/common/run_configuration.cc

shell/common/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ source_set("common") {
7474
"pipeline.h",
7575
"platform_view.cc",
7676
"platform_view.h",
77+
"pointer_data_dispatcher.cc",
78+
"pointer_data_dispatcher.h",
7779
"rasterizer.cc",
7880
"rasterizer.h",
7981
"run_configuration.cc",
@@ -156,6 +158,7 @@ if (current_toolchain == host_toolchain) {
156158
shell_host_executable("shell_unittests") {
157159
sources = [
158160
"canvas_spy_unittests.cc",
161+
"input_events_unittests.cc",
159162
"pipeline_unittests.cc",
160163
"shell_test.cc",
161164
"shell_test.h",

shell/common/engine.cc

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ static constexpr char kSettingsChannel[] = "flutter/settings";
3636
static constexpr char kIsolateChannel[] = "flutter/isolate";
3737

3838
Engine::Engine(Delegate& delegate,
39+
PointerDataDispatcherMaker& dispatcher_maker,
3940
DartVM& vm,
4041
fml::RefPtr<const DartSnapshot> isolate_snapshot,
4142
fml::RefPtr<const DartSnapshot> shared_snapshot,
@@ -51,6 +52,7 @@ Engine::Engine(Delegate& delegate,
5152
image_decoder_(task_runners,
5253
vm.GetConcurrentWorkerTaskRunner(),
5354
io_manager),
55+
task_runners_(std::move(task_runners)),
5456
weak_factory_(this) {
5557
// Runtime controller is initialized here because it takes a reference to this
5658
// object as its delegate. The delegate may be called in the constructor and
@@ -60,7 +62,7 @@ Engine::Engine(Delegate& delegate,
6062
&vm, // VM
6163
std::move(isolate_snapshot), // isolate snapshot
6264
std::move(shared_snapshot), // shared snapshot
63-
std::move(task_runners), // task runners
65+
task_runners_, // task runners
6466
std::move(io_manager), // io manager
6567
image_decoder_.GetWeakPtr(), // image decoder
6668
settings_.advisory_script_uri, // advisory script uri
@@ -69,6 +71,8 @@ Engine::Engine(Delegate& delegate,
6971
settings_.isolate_create_callback, // isolate create callback
7072
settings_.isolate_shutdown_callback // isolate shutdown callback
7173
);
74+
75+
pointer_data_dispatcher_ = dispatcher_maker(*this);
7276
}
7377

7478
Engine::~Engine() = default;
@@ -381,12 +385,12 @@ void Engine::HandleSettingsPlatformMessage(PlatformMessage* message) {
381385
}
382386
}
383387

384-
void Engine::DispatchPointerDataPacket(const PointerDataPacket& packet,
385-
uint64_t trace_flow_id) {
388+
void Engine::DispatchPointerDataPacket(
389+
std::unique_ptr<PointerDataPacket> packet,
390+
uint64_t trace_flow_id) {
386391
TRACE_EVENT0("flutter", "Engine::DispatchPointerDataPacket");
387392
TRACE_FLOW_STEP("flutter", "PointerEvent", trace_flow_id);
388-
animator_->EnqueueTraceFlowId(trace_flow_id);
389-
runtime_controller_->DispatchPointerDataPacket(packet);
393+
pointer_data_dispatcher_->DispatchPacket(std::move(packet), trace_flow_id);
390394
}
391395

392396
void Engine::DispatchSemanticsAction(int id,
@@ -434,6 +438,8 @@ void Engine::Render(std::unique_ptr<flutter::LayerTree> layer_tree) {
434438

435439
layer_tree->set_frame_size(frame_size);
436440
animator_->Render(std::move(layer_tree));
441+
442+
pointer_data_dispatcher_->OnFrameLayerTreeReceived();
437443
}
438444

439445
void Engine::UpdateSemantics(SemanticsNodeUpdates update,
@@ -462,6 +468,14 @@ FontCollection& Engine::GetFontCollection() {
462468
return font_collection_;
463469
}
464470

471+
void Engine::DoDispatchPacket(std::unique_ptr<PointerDataPacket> packet,
472+
uint64_t trace_flow_id) {
473+
animator_->EnqueueTraceFlowId(trace_flow_id);
474+
if (runtime_controller_) {
475+
runtime_controller_->DispatchPointerDataPacket(*packet);
476+
}
477+
}
478+
465479
void Engine::HandleAssetPlatformMessage(fml::RefPtr<PlatformMessage> message) {
466480
fml::RefPtr<PlatformMessageResponse> response = message->response();
467481
if (!response) {

shell/common/engine.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include "flutter/runtime/runtime_controller.h"
2323
#include "flutter/runtime/runtime_delegate.h"
2424
#include "flutter/shell/common/animator.h"
25+
#include "flutter/shell/common/platform_view.h"
26+
#include "flutter/shell/common/pointer_data_dispatcher.h"
2527
#include "flutter/shell/common/rasterizer.h"
2628
#include "flutter/shell/common/run_configuration.h"
2729
#include "flutter/shell/common/shell_io_manager.h"
@@ -65,7 +67,7 @@ namespace flutter {
6567
/// name and it does happen to be one of the older classes in the
6668
/// repository.
6769
///
68-
class Engine final : public RuntimeDelegate {
70+
class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
6971
public:
7072
//----------------------------------------------------------------------------
7173
/// @brief Indicates the result of the call to `Engine::Run`.
@@ -234,6 +236,12 @@ class Engine final : public RuntimeDelegate {
234236
/// tasks that require access to components
235237
/// that cannot be safely accessed by the
236238
/// engine. This is the shell.
239+
/// @param dispatcher_maker The `std::function` provided by
240+
/// `PlatformView` for engine to create the
241+
/// pointer data dispatcher. Similar to other
242+
/// engine resources, this dispatcher_maker and
243+
/// its returned dispatcher is only safe to be
244+
/// called from the UI thread.
237245
/// @param vm An instance of the running Dart VM.
238246
/// @param[in] isolate_snapshot The snapshot used to create the root
239247
/// isolate. Even though the isolate is not
@@ -265,6 +273,7 @@ class Engine final : public RuntimeDelegate {
265273
/// GPU.
266274
///
267275
Engine(Delegate& delegate,
276+
PointerDataDispatcherMaker& dispatcher_maker,
268277
DartVM& vm,
269278
fml::RefPtr<const DartSnapshot> isolate_snapshot,
270279
fml::RefPtr<const DartSnapshot> shared_snapshot,
@@ -649,7 +658,7 @@ class Engine final : public RuntimeDelegate {
649658
/// timeline and allow grouping frames and input
650659
/// events into logical chunks.
651660
///
652-
void DispatchPointerDataPacket(const PointerDataPacket& packet,
661+
void DispatchPointerDataPacket(std::unique_ptr<PointerDataPacket> packet,
653662
uint64_t trace_flow_id);
654663

655664
//----------------------------------------------------------------------------
@@ -700,18 +709,31 @@ class Engine final : public RuntimeDelegate {
700709
// |RuntimeDelegate|
701710
FontCollection& GetFontCollection() override;
702711

712+
// |PointerDataDispatcher::Delegate|
713+
void DoDispatchPacket(std::unique_ptr<PointerDataPacket> packet,
714+
uint64_t trace_flow_id) override;
715+
716+
TaskRunners& task_runners() override { return task_runners_; }
717+
703718
private:
704719
Engine::Delegate& delegate_;
705720
const Settings settings_;
706721
std::unique_ptr<Animator> animator_;
707722
std::unique_ptr<RuntimeController> runtime_controller_;
723+
724+
// The pointer_data_dispatcher_ depends on animator_ and runtime_controller_.
725+
// So it should be defined after them to ensure that pointer_data_dispatcher_
726+
// is destructed first.
727+
std::unique_ptr<PointerDataDispatcher> pointer_data_dispatcher_;
728+
708729
std::string initial_route_;
709730
ViewportMetrics viewport_metrics_;
710731
std::shared_ptr<AssetManager> asset_manager_;
711732
bool activity_running_;
712733
bool have_surface_;
713734
FontCollection font_collection_;
714735
ImageDecoder image_decoder_;
736+
TaskRunners task_runners_;
715737
fml::WeakPtrFactory<Engine> weak_factory_;
716738

717739
// |RuntimeDelegate|

shell/common/fixtures/shell_test.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ void main() {}
1111

1212
void nativeReportTimingsCallback(List<int> timings) native 'NativeReportTimingsCallback';
1313
void nativeOnBeginFrame(int microseconds) native 'NativeOnBeginFrame';
14+
void nativeOnPointerDataPacket() native 'NativeOnPointerDataPacket';
1415

1516
@pragma('vm:entry-point')
1617
void reportTimingsMain() {
@@ -32,6 +33,16 @@ void onBeginFrameMain() {
3233
};
3334
}
3435

36+
@pragma('vm:entry-point')
37+
void onPointerDataPacketMain() {
38+
window.onPointerDataPacket = (PointerDataPacket packet) {
39+
nativeOnPointerDataPacket();
40+
};
41+
window.onBeginFrame = (Duration beginTime) {
42+
nativeOnBeginFrame(beginTime.inMicroseconds);
43+
};
44+
}
45+
3546
@pragma('vm:entry-point')
3647
void emptyMain() {}
3748

0 commit comments

Comments
 (0)