Skip to content

Commit 4654fc6

Browse files
Patrick SosinskiEmmanuel Garcia
Patrick Sosinski
and
Emmanuel Garcia
authored
Flutter 1.22.0-12.1.pre engine cherrypicks (flutter#21188)
* Update 1.22 engine to use Dart 2.10.0-110.3.beta * Add a new raster status `kSkipAndRetry` frame (flutter#21059) * update license file for Dart 2.10.0-110.3.beta * Account for current open image in FlutterImageView (flutter#21191) Co-authored-by: Emmanuel Garcia <[email protected]>
1 parent fee6f9e commit 4654fc6

17 files changed

+224
-102
lines changed

DEPS

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ vars = {
3434
# Dart is: https://github.com/dart-lang/sdk/blob/master/DEPS.
3535
# You can use //tools/dart/create_updated_flutter_deps.py to produce
3636
# updated revision list of existing dependencies.
37-
'dart_revision': '325d9b628caa8ca043181f92bf6e050b85a7c2f9',
37+
'dart_revision': '52130c19ca593b185ea9cf72b26b1d02455551ef',
3838

3939
# WARNING: DO NOT EDIT MANUALLY
4040
# The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py

ci/licenses_golden/licenses_third_party

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Signature: 14693ed982fa820c5dbce3c385be0a60
1+
Signature: a1bbcd05a2657658be7c5f38e0d366f4
22

33
UNUSED LICENSES:
44

flow/compositor_context.cc

+3
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ RasterStatus CompositorContext::ScopedFrame::Raster(
8282
if (post_preroll_result == PostPrerollResult::kResubmitFrame) {
8383
return RasterStatus::kResubmit;
8484
}
85+
if (post_preroll_result == PostPrerollResult::kSkipAndRetryFrame) {
86+
return RasterStatus::kSkipAndRetry;
87+
}
8588
// Clearing canvas after preroll reduces one render target switch when preroll
8689
// paints some raster cache.
8790
if (canvas()) {

flow/compositor_context.h

+16-3
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,25 @@ class LayerTree;
2424
enum class RasterStatus {
2525
// Frame has successfully rasterized.
2626
kSuccess,
27-
// Frame needs to be resubmitted for rasterization. This is
28-
// currently only called when thread configuration change occurs.
27+
// Frame is submitted twice. This is only used on Android when
28+
// switching the background surface to FlutterImageView.
29+
//
30+
// On Android, the first frame doesn't make the image available
31+
// to the ImageReader right away. The second frame does.
32+
//
33+
// TODO(egarciad): https://github.com/flutter/flutter/issues/65652
2934
kResubmit,
35+
// Frame is dropped and a new frame with the same layer tree is
36+
// attempted.
37+
//
38+
// This is currently used to wait for the thread merger to merge
39+
// the raster and platform threads.
40+
//
41+
// Since the thread merger may be disabled,
42+
kSkipAndRetry,
3043
// Frame has been successfully rasterized, but "there are additional items in
3144
// the pipeline waiting to be consumed. This is currently
32-
// only called when thread configuration change occurs.
45+
// only used when thread configuration change occurs.
3346
kEnqueuePipeline,
3447
// Failed to rasterize the frame.
3548
kFailed

flow/embedded_views.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,17 @@ class EmbeddedViewParams {
242242
SkRect final_bounding_rect_;
243243
};
244244

245-
enum class PostPrerollResult { kResubmitFrame, kSuccess };
245+
enum class PostPrerollResult {
246+
// Frame has successfully rasterized.
247+
kSuccess,
248+
// Frame is submitted twice. This is currently only used when
249+
// thread configuration change occurs.
250+
kResubmitFrame,
251+
// Frame is dropped and a new frame with the same layer tree is
252+
// attempted. This is currently only used when thread configuration
253+
// change occurs.
254+
kSkipAndRetryFrame
255+
};
246256

247257
// Facilitates embedding of platform views within the flow layer tree.
248258
//

shell/common/rasterizer.cc

+8-4
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,10 @@ void Rasterizer::Draw(fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline) {
172172
PipelineConsumeResult consume_result = pipeline->Consume(consumer);
173173
// if the raster status is to resubmit the frame, we push the frame to the
174174
// front of the queue and also change the consume status to more available.
175-
if (raster_status == RasterStatus::kResubmit) {
175+
176+
auto should_resubmit_frame = raster_status == RasterStatus::kResubmit ||
177+
raster_status == RasterStatus::kSkipAndRetry;
178+
if (should_resubmit_frame) {
176179
auto front_continuation = pipeline->ProduceIfEmpty();
177180
bool result =
178181
front_continuation.Complete(std::move(resubmitted_layer_tree_));
@@ -186,7 +189,6 @@ void Rasterizer::Draw(fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline) {
186189
// Merging the thread as we know the next `Draw` should be run on the platform
187190
// thread.
188191
if (surface_ != nullptr && surface_->GetExternalViewEmbedder() != nullptr) {
189-
auto should_resubmit_frame = raster_status == RasterStatus::kResubmit;
190192
surface_->GetExternalViewEmbedder()->EndFrame(should_resubmit_frame,
191193
raster_thread_merger_);
192194
}
@@ -332,7 +334,8 @@ RasterStatus Rasterizer::DoDraw(
332334
RasterStatus raster_status = DrawToSurface(*layer_tree);
333335
if (raster_status == RasterStatus::kSuccess) {
334336
last_layer_tree_ = std::move(layer_tree);
335-
} else if (raster_status == RasterStatus::kResubmit) {
337+
} else if (raster_status == RasterStatus::kResubmit ||
338+
raster_status == RasterStatus::kSkipAndRetry) {
336339
resubmitted_layer_tree_ = std::move(layer_tree);
337340
return raster_status;
338341
}
@@ -457,7 +460,8 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) {
457460

458461
if (compositor_frame) {
459462
RasterStatus raster_status = compositor_frame->Raster(layer_tree, false);
460-
if (raster_status == RasterStatus::kFailed) {
463+
if (raster_status == RasterStatus::kFailed ||
464+
raster_status == RasterStatus::kSkipAndRetry) {
461465
return raster_status;
462466
}
463467
if (external_view_embedder != nullptr) {

shell/common/shell_test_external_view_embedder.cc

+5-9
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,16 @@ ShellTestExternalViewEmbedder::ShellTestExternalViewEmbedder(
88
bool support_thread_merging)
99
: end_frame_call_back_(end_frame_call_back),
1010
post_preroll_result_(post_preroll_result),
11-
support_thread_merging_(support_thread_merging) {
12-
resubmit_once_ = false;
13-
}
11+
support_thread_merging_(support_thread_merging),
12+
submitted_frame_count_(0) {}
1413

1514
void ShellTestExternalViewEmbedder::UpdatePostPrerollResult(
1615
PostPrerollResult post_preroll_result) {
1716
post_preroll_result_ = post_preroll_result;
1817
}
1918

20-
void ShellTestExternalViewEmbedder::SetResubmitOnce() {
21-
resubmit_once_ = true;
19+
int ShellTestExternalViewEmbedder::GetSubmittedFrameCount() {
20+
return submitted_frame_count_;
2221
}
2322

2423
// |ExternalViewEmbedder|
@@ -40,10 +39,6 @@ void ShellTestExternalViewEmbedder::PrerollCompositeEmbeddedView(
4039
PostPrerollResult ShellTestExternalViewEmbedder::PostPrerollAction(
4140
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
4241
FML_DCHECK(raster_thread_merger);
43-
if (resubmit_once_) {
44-
resubmit_once_ = false;
45-
return PostPrerollResult::kResubmitFrame;
46-
}
4742
return post_preroll_result_;
4843
}
4944

@@ -62,6 +57,7 @@ void ShellTestExternalViewEmbedder::SubmitFrame(
6257
GrDirectContext* context,
6358
std::unique_ptr<SurfaceFrame> frame) {
6459
frame->Submit();
60+
submitted_frame_count_++;
6561
}
6662

6763
// |ExternalViewEmbedder|

shell/common/shell_test_external_view_embedder.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder {
2828
// returns the new `post_preroll_result`.
2929
void UpdatePostPrerollResult(PostPrerollResult post_preroll_result);
3030

31-
// Updates the post preroll result to `PostPrerollResult::kResubmitFrame` for
32-
// only the next frame.
33-
void SetResubmitOnce();
31+
// Gets the number of times the SubmitFrame method has been called in
32+
// the external view embedder.
33+
int GetSubmittedFrameCount();
3434

3535
private:
3636
// |ExternalViewEmbedder|
@@ -74,11 +74,13 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder {
7474
bool SupportsDynamicThreadMerging() override;
7575

7676
const EndFrameCallBack end_frame_call_back_;
77+
7778
PostPrerollResult post_preroll_result_;
78-
bool resubmit_once_;
7979

8080
bool support_thread_merging_;
8181

82+
std::atomic<int> submitted_frame_count_;
83+
8284
FML_DISALLOW_COPY_AND_ASSIGN(ShellTestExternalViewEmbedder);
8385
};
8486

shell/common/shell_unittests.cc

+102-5
Original file line numberDiff line numberDiff line change
@@ -617,8 +617,7 @@ TEST_F(ShellTest,
617617
};
618618
auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
619619
end_frame_callback, PostPrerollResult::kSuccess, true);
620-
// Set resubmit once to trigger thread merging.
621-
external_view_embedder->SetResubmitOnce();
620+
622621
auto shell = CreateShell(std::move(settings), GetTaskRunnersForFixture(),
623622
false, external_view_embedder);
624623

@@ -674,18 +673,25 @@ TEST_F(ShellTest,
674673
const size_t ThreadMergingLease = 10;
675674
auto settings = CreateSettingsForFixture();
676675
fml::AutoResetWaitableEvent end_frame_latch;
676+
std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
677+
677678
auto end_frame_callback =
678679
[&](bool should_resubmit_frame,
679680
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
680681
if (should_resubmit_frame && !raster_thread_merger->IsMerged()) {
681682
raster_thread_merger->MergeWithLease(ThreadMergingLease);
683+
684+
ASSERT_TRUE(raster_thread_merger->IsMerged());
685+
external_view_embedder->UpdatePostPrerollResult(
686+
PostPrerollResult::kSuccess);
682687
}
683688
end_frame_latch.Signal();
684689
};
685-
auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
690+
external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
686691
end_frame_callback, PostPrerollResult::kSuccess, true);
687692
// Set resubmit once to trigger thread merging.
688-
external_view_embedder->SetResubmitOnce();
693+
external_view_embedder->UpdatePostPrerollResult(
694+
PostPrerollResult::kResubmitFrame);
689695
auto shell = CreateShell(std::move(settings), GetTaskRunnersForFixture(),
690696
false, external_view_embedder);
691697

@@ -796,7 +802,8 @@ TEST_F(ShellTest,
796802

797803
// Pump a frame with `PostPrerollResult::kResubmitFrame` to start merging
798804
// threads
799-
external_view_embedder->SetResubmitOnce();
805+
external_view_embedder->UpdatePostPrerollResult(
806+
PostPrerollResult::kResubmitFrame);
800807
PumpOneFrame(shell.get(), 100, 100, builder);
801808

802809
// Now destroy the platform view immediately.
@@ -988,6 +995,96 @@ TEST_F(ShellTest,
988995
DestroyShell(std::move(shell), std::move(task_runners));
989996
}
990997

998+
// TODO(https://github.com/flutter/flutter/issues/59816): Enable on fuchsia.
999+
TEST_F(ShellTest,
1000+
#if defined(OS_FUCHSIA)
1001+
DISABLED_SkipAndSubmitFrame
1002+
#else
1003+
SkipAndSubmitFrame
1004+
#endif
1005+
) {
1006+
auto settings = CreateSettingsForFixture();
1007+
fml::AutoResetWaitableEvent end_frame_latch;
1008+
std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
1009+
1010+
auto end_frame_callback =
1011+
[&](bool should_resubmit_frame,
1012+
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
1013+
external_view_embedder->UpdatePostPrerollResult(
1014+
PostPrerollResult::kSuccess);
1015+
end_frame_latch.Signal();
1016+
};
1017+
external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1018+
end_frame_callback, PostPrerollResult::kSkipAndRetryFrame, true);
1019+
1020+
auto shell = CreateShell(std::move(settings), GetTaskRunnersForFixture(),
1021+
false, external_view_embedder);
1022+
1023+
PlatformViewNotifyCreated(shell.get());
1024+
1025+
auto configuration = RunConfiguration::InferFromSettings(settings);
1026+
configuration.SetEntrypoint("emptyMain");
1027+
RunEngine(shell.get(), std::move(configuration));
1028+
1029+
ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
1030+
1031+
PumpOneFrame(shell.get());
1032+
1033+
// `EndFrame` changed the post preroll result to `kSuccess`.
1034+
end_frame_latch.Wait();
1035+
ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
1036+
1037+
PumpOneFrame(shell.get());
1038+
end_frame_latch.Wait();
1039+
ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount());
1040+
1041+
DestroyShell(std::move(shell));
1042+
}
1043+
1044+
// TODO(https://github.com/flutter/flutter/issues/59816): Enable on fuchsia.
1045+
TEST_F(ShellTest,
1046+
#if defined(OS_FUCHSIA)
1047+
DISABLED_ResubmitFrame
1048+
#else
1049+
ResubmitFrame
1050+
#endif
1051+
) {
1052+
auto settings = CreateSettingsForFixture();
1053+
fml::AutoResetWaitableEvent end_frame_latch;
1054+
std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
1055+
1056+
auto end_frame_callback =
1057+
[&](bool should_resubmit_frame,
1058+
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
1059+
external_view_embedder->UpdatePostPrerollResult(
1060+
PostPrerollResult::kSuccess);
1061+
end_frame_latch.Signal();
1062+
};
1063+
external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1064+
end_frame_callback, PostPrerollResult::kResubmitFrame, true);
1065+
1066+
auto shell = CreateShell(std::move(settings), GetTaskRunnersForFixture(),
1067+
false, external_view_embedder);
1068+
1069+
PlatformViewNotifyCreated(shell.get());
1070+
1071+
auto configuration = RunConfiguration::InferFromSettings(settings);
1072+
configuration.SetEntrypoint("emptyMain");
1073+
RunEngine(shell.get(), std::move(configuration));
1074+
1075+
ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
1076+
1077+
PumpOneFrame(shell.get());
1078+
// `EndFrame` changed the post preroll result to `kSuccess`.
1079+
end_frame_latch.Wait();
1080+
ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount());
1081+
1082+
end_frame_latch.Wait();
1083+
ASSERT_EQ(2, external_view_embedder->GetSubmittedFrameCount());
1084+
1085+
DestroyShell(std::move(shell));
1086+
}
1087+
9911088
TEST(SettingsTest, FrameTimingSetsAndGetsProperly) {
9921089
// Ensure that all phases are in kPhases.
9931090
ASSERT_EQ(sizeof(FrameTiming::kPhases),

shell/platform/android/external_view_embedder/external_view_embedder.cc

+13-30
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,6 @@ void AndroidExternalViewEmbedder::SubmitFrame(
7777
std::unique_ptr<SurfaceFrame> frame) {
7878
TRACE_EVENT0("flutter", "AndroidExternalViewEmbedder::SubmitFrame");
7979

80-
if (should_run_rasterizer_on_platform_thread_) {
81-
// Don't submit the current frame if the frame will be resubmitted.
82-
return;
83-
}
8480
if (!FrameHasPlatformLayers()) {
8581
frame->Submit();
8682
return;
@@ -217,27 +213,25 @@ AndroidExternalViewEmbedder::CreateSurfaceIfNeeded(GrDirectContext* context,
217213
// |ExternalViewEmbedder|
218214
PostPrerollResult AndroidExternalViewEmbedder::PostPrerollAction(
219215
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
220-
// This frame may remove existing platform views that aren't contained
221-
// in `composition_order_`.
222-
//
223-
// If this frame doesn't have platform views, it's still required to keep
224-
// the rasterizer running on the platform thread for at least one more
225-
// frame.
226-
//
227-
// To keep the rasterizer running on the platform thread one more frame,
228-
// `kDefaultMergedLeaseDuration` must be at least `1`.
229216
if (!FrameHasPlatformLayers()) {
230217
return PostPrerollResult::kSuccess;
231218
}
232-
if (raster_thread_merger->IsMerged()) {
233-
raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
234-
} else {
235-
// Merge the raster and platform threads in `EndFrame`.
236-
should_run_rasterizer_on_platform_thread_ = true;
219+
if (!raster_thread_merger->IsMerged()) {
220+
// The raster thread merger may be disabled if the rasterizer is being
221+
// created or teared down.
222+
//
223+
// In such cases, the current frame is dropped, and a new frame is attempted
224+
// with the same layer tree.
225+
//
226+
// Eventually, the frame is submitted once this method returns `kSuccess`.
227+
// At that point, the raster tasks are handled on the platform thread.
228+
raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
237229
CancelFrame();
238-
return PostPrerollResult::kResubmitFrame;
230+
return PostPrerollResult::kSkipAndRetryFrame;
239231
}
232+
raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
240233
// Surface switch requires to resubmit the frame.
234+
// TODO(egarciad): https://github.com/flutter/flutter/issues/65652
241235
if (previous_frame_view_count_ == 0) {
242236
return PostPrerollResult::kResubmitFrame;
243237
}
@@ -291,17 +285,6 @@ void AndroidExternalViewEmbedder::CancelFrame() {
291285
void AndroidExternalViewEmbedder::EndFrame(
292286
bool should_resubmit_frame,
293287
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
294-
if (should_resubmit_frame && should_run_rasterizer_on_platform_thread_) {
295-
raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
296-
if (raster_thread_merger->IsMerged()) {
297-
// The raster thread merger may be disabled if the rasterizer is being
298-
// teared down.
299-
//
300-
// Therefore, set `should_run_rasterizer_on_platform_thread_` to `false`
301-
// only if the thread merger was able to set the lease.
302-
should_run_rasterizer_on_platform_thread_ = false;
303-
}
304-
}
305288
surface_pool_->RecycleLayers();
306289
// JNI method must be called on the platform thread.
307290
if (raster_thread_merger->IsOnPlatformThread()) {

0 commit comments

Comments
 (0)