Skip to content

Commit

Permalink
Flutter 1.22.0-12.1.pre engine cherrypicks (#21188)
Browse files Browse the repository at this point in the history
* Update 1.22 engine to use Dart 2.10.0-110.3.beta

* Add a new raster status `kSkipAndRetry` frame (#21059)

* update license file for Dart 2.10.0-110.3.beta

* Account for current open image in FlutterImageView (#21191)

Co-authored-by: Emmanuel Garcia <egarciad@google.com>
  • Loading branch information
Patrick Sosinski and Emmanuel Garcia authored Sep 15, 2020
1 parent fee6f9e commit 4654fc6
Show file tree
Hide file tree
Showing 17 changed files with 224 additions and 102 deletions.
2 changes: 1 addition & 1 deletion DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ vars = {
# Dart is: https://github.com/dart-lang/sdk/blob/master/DEPS.
# You can use //tools/dart/create_updated_flutter_deps.py to produce
# updated revision list of existing dependencies.
'dart_revision': '325d9b628caa8ca043181f92bf6e050b85a7c2f9',
'dart_revision': '52130c19ca593b185ea9cf72b26b1d02455551ef',

# WARNING: DO NOT EDIT MANUALLY
# The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py
Expand Down
2 changes: 1 addition & 1 deletion ci/licenses_golden/licenses_third_party
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Signature: 14693ed982fa820c5dbce3c385be0a60
Signature: a1bbcd05a2657658be7c5f38e0d366f4

UNUSED LICENSES:

Expand Down
3 changes: 3 additions & 0 deletions flow/compositor_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ RasterStatus CompositorContext::ScopedFrame::Raster(
if (post_preroll_result == PostPrerollResult::kResubmitFrame) {
return RasterStatus::kResubmit;
}
if (post_preroll_result == PostPrerollResult::kSkipAndRetryFrame) {
return RasterStatus::kSkipAndRetry;
}
// Clearing canvas after preroll reduces one render target switch when preroll
// paints some raster cache.
if (canvas()) {
Expand Down
19 changes: 16 additions & 3 deletions flow/compositor_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,25 @@ class LayerTree;
enum class RasterStatus {
// Frame has successfully rasterized.
kSuccess,
// Frame needs to be resubmitted for rasterization. This is
// currently only called when thread configuration change occurs.
// Frame is submitted twice. This is only used on Android when
// switching the background surface to FlutterImageView.
//
// On Android, the first frame doesn't make the image available
// to the ImageReader right away. The second frame does.
//
// TODO(egarciad): https://github.com/flutter/flutter/issues/65652
kResubmit,
// Frame is dropped and a new frame with the same layer tree is
// attempted.
//
// This is currently used to wait for the thread merger to merge
// the raster and platform threads.
//
// Since the thread merger may be disabled,
kSkipAndRetry,
// Frame has been successfully rasterized, but "there are additional items in
// the pipeline waiting to be consumed. This is currently
// only called when thread configuration change occurs.
// only used when thread configuration change occurs.
kEnqueuePipeline,
// Failed to rasterize the frame.
kFailed
Expand Down
12 changes: 11 additions & 1 deletion flow/embedded_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,17 @@ class EmbeddedViewParams {
SkRect final_bounding_rect_;
};

enum class PostPrerollResult { kResubmitFrame, kSuccess };
enum class PostPrerollResult {
// Frame has successfully rasterized.
kSuccess,
// Frame is submitted twice. This is currently only used when
// thread configuration change occurs.
kResubmitFrame,
// Frame is dropped and a new frame with the same layer tree is
// attempted. This is currently only used when thread configuration
// change occurs.
kSkipAndRetryFrame
};

// Facilitates embedding of platform views within the flow layer tree.
//
Expand Down
12 changes: 8 additions & 4 deletions shell/common/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,10 @@ void Rasterizer::Draw(fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline) {
PipelineConsumeResult consume_result = pipeline->Consume(consumer);
// if the raster status is to resubmit the frame, we push the frame to the
// front of the queue and also change the consume status to more available.
if (raster_status == RasterStatus::kResubmit) {

auto should_resubmit_frame = raster_status == RasterStatus::kResubmit ||
raster_status == RasterStatus::kSkipAndRetry;
if (should_resubmit_frame) {
auto front_continuation = pipeline->ProduceIfEmpty();
bool result =
front_continuation.Complete(std::move(resubmitted_layer_tree_));
Expand All @@ -186,7 +189,6 @@ void Rasterizer::Draw(fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline) {
// Merging the thread as we know the next `Draw` should be run on the platform
// thread.
if (surface_ != nullptr && surface_->GetExternalViewEmbedder() != nullptr) {
auto should_resubmit_frame = raster_status == RasterStatus::kResubmit;
surface_->GetExternalViewEmbedder()->EndFrame(should_resubmit_frame,
raster_thread_merger_);
}
Expand Down Expand Up @@ -332,7 +334,8 @@ RasterStatus Rasterizer::DoDraw(
RasterStatus raster_status = DrawToSurface(*layer_tree);
if (raster_status == RasterStatus::kSuccess) {
last_layer_tree_ = std::move(layer_tree);
} else if (raster_status == RasterStatus::kResubmit) {
} else if (raster_status == RasterStatus::kResubmit ||
raster_status == RasterStatus::kSkipAndRetry) {
resubmitted_layer_tree_ = std::move(layer_tree);
return raster_status;
}
Expand Down Expand Up @@ -457,7 +460,8 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) {

if (compositor_frame) {
RasterStatus raster_status = compositor_frame->Raster(layer_tree, false);
if (raster_status == RasterStatus::kFailed) {
if (raster_status == RasterStatus::kFailed ||
raster_status == RasterStatus::kSkipAndRetry) {
return raster_status;
}
if (external_view_embedder != nullptr) {
Expand Down
14 changes: 5 additions & 9 deletions shell/common/shell_test_external_view_embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@ ShellTestExternalViewEmbedder::ShellTestExternalViewEmbedder(
bool support_thread_merging)
: end_frame_call_back_(end_frame_call_back),
post_preroll_result_(post_preroll_result),
support_thread_merging_(support_thread_merging) {
resubmit_once_ = false;
}
support_thread_merging_(support_thread_merging),
submitted_frame_count_(0) {}

void ShellTestExternalViewEmbedder::UpdatePostPrerollResult(
PostPrerollResult post_preroll_result) {
post_preroll_result_ = post_preroll_result;
}

void ShellTestExternalViewEmbedder::SetResubmitOnce() {
resubmit_once_ = true;
int ShellTestExternalViewEmbedder::GetSubmittedFrameCount() {
return submitted_frame_count_;
}

// |ExternalViewEmbedder|
Expand All @@ -40,10 +39,6 @@ void ShellTestExternalViewEmbedder::PrerollCompositeEmbeddedView(
PostPrerollResult ShellTestExternalViewEmbedder::PostPrerollAction(
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
FML_DCHECK(raster_thread_merger);
if (resubmit_once_) {
resubmit_once_ = false;
return PostPrerollResult::kResubmitFrame;
}
return post_preroll_result_;
}

Expand All @@ -62,6 +57,7 @@ void ShellTestExternalViewEmbedder::SubmitFrame(
GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame) {
frame->Submit();
submitted_frame_count_++;
}

// |ExternalViewEmbedder|
Expand Down
10 changes: 6 additions & 4 deletions shell/common/shell_test_external_view_embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder {
// returns the new `post_preroll_result`.
void UpdatePostPrerollResult(PostPrerollResult post_preroll_result);

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

private:
// |ExternalViewEmbedder|
Expand Down Expand Up @@ -74,11 +74,13 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder {
bool SupportsDynamicThreadMerging() override;

const EndFrameCallBack end_frame_call_back_;

PostPrerollResult post_preroll_result_;
bool resubmit_once_;

bool support_thread_merging_;

std::atomic<int> submitted_frame_count_;

FML_DISALLOW_COPY_AND_ASSIGN(ShellTestExternalViewEmbedder);
};

Expand Down
107 changes: 102 additions & 5 deletions shell/common/shell_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -617,8 +617,7 @@ TEST_F(ShellTest,
};
auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
end_frame_callback, PostPrerollResult::kSuccess, true);
// Set resubmit once to trigger thread merging.
external_view_embedder->SetResubmitOnce();

auto shell = CreateShell(std::move(settings), GetTaskRunnersForFixture(),
false, external_view_embedder);

Expand Down Expand Up @@ -674,18 +673,25 @@ TEST_F(ShellTest,
const size_t ThreadMergingLease = 10;
auto settings = CreateSettingsForFixture();
fml::AutoResetWaitableEvent end_frame_latch;
std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;

auto end_frame_callback =
[&](bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
if (should_resubmit_frame && !raster_thread_merger->IsMerged()) {
raster_thread_merger->MergeWithLease(ThreadMergingLease);

ASSERT_TRUE(raster_thread_merger->IsMerged());
external_view_embedder->UpdatePostPrerollResult(
PostPrerollResult::kSuccess);
}
end_frame_latch.Signal();
};
auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
end_frame_callback, PostPrerollResult::kSuccess, true);
// Set resubmit once to trigger thread merging.
external_view_embedder->SetResubmitOnce();
external_view_embedder->UpdatePostPrerollResult(
PostPrerollResult::kResubmitFrame);
auto shell = CreateShell(std::move(settings), GetTaskRunnersForFixture(),
false, external_view_embedder);

Expand Down Expand Up @@ -796,7 +802,8 @@ TEST_F(ShellTest,

// Pump a frame with `PostPrerollResult::kResubmitFrame` to start merging
// threads
external_view_embedder->SetResubmitOnce();
external_view_embedder->UpdatePostPrerollResult(
PostPrerollResult::kResubmitFrame);
PumpOneFrame(shell.get(), 100, 100, builder);

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

// TODO(https://github.com/flutter/flutter/issues/59816): Enable on fuchsia.
TEST_F(ShellTest,
#if defined(OS_FUCHSIA)
DISABLED_SkipAndSubmitFrame
#else
SkipAndSubmitFrame
#endif
) {
auto settings = CreateSettingsForFixture();
fml::AutoResetWaitableEvent end_frame_latch;
std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;

auto end_frame_callback =
[&](bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
external_view_embedder->UpdatePostPrerollResult(
PostPrerollResult::kSuccess);
end_frame_latch.Signal();
};
external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
end_frame_callback, PostPrerollResult::kSkipAndRetryFrame, true);

auto shell = CreateShell(std::move(settings), GetTaskRunnersForFixture(),
false, external_view_embedder);

PlatformViewNotifyCreated(shell.get());

auto configuration = RunConfiguration::InferFromSettings(settings);
configuration.SetEntrypoint("emptyMain");
RunEngine(shell.get(), std::move(configuration));

ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());

PumpOneFrame(shell.get());

// `EndFrame` changed the post preroll result to `kSuccess`.
end_frame_latch.Wait();
ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());

PumpOneFrame(shell.get());
end_frame_latch.Wait();
ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount());

DestroyShell(std::move(shell));
}

// TODO(https://github.com/flutter/flutter/issues/59816): Enable on fuchsia.
TEST_F(ShellTest,
#if defined(OS_FUCHSIA)
DISABLED_ResubmitFrame
#else
ResubmitFrame
#endif
) {
auto settings = CreateSettingsForFixture();
fml::AutoResetWaitableEvent end_frame_latch;
std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;

auto end_frame_callback =
[&](bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
external_view_embedder->UpdatePostPrerollResult(
PostPrerollResult::kSuccess);
end_frame_latch.Signal();
};
external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
end_frame_callback, PostPrerollResult::kResubmitFrame, true);

auto shell = CreateShell(std::move(settings), GetTaskRunnersForFixture(),
false, external_view_embedder);

PlatformViewNotifyCreated(shell.get());

auto configuration = RunConfiguration::InferFromSettings(settings);
configuration.SetEntrypoint("emptyMain");
RunEngine(shell.get(), std::move(configuration));

ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());

PumpOneFrame(shell.get());
// `EndFrame` changed the post preroll result to `kSuccess`.
end_frame_latch.Wait();
ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount());

end_frame_latch.Wait();
ASSERT_EQ(2, external_view_embedder->GetSubmittedFrameCount());

DestroyShell(std::move(shell));
}

TEST(SettingsTest, FrameTimingSetsAndGetsProperly) {
// Ensure that all phases are in kPhases.
ASSERT_EQ(sizeof(FrameTiming::kPhases),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,6 @@ void AndroidExternalViewEmbedder::SubmitFrame(
std::unique_ptr<SurfaceFrame> frame) {
TRACE_EVENT0("flutter", "AndroidExternalViewEmbedder::SubmitFrame");

if (should_run_rasterizer_on_platform_thread_) {
// Don't submit the current frame if the frame will be resubmitted.
return;
}
if (!FrameHasPlatformLayers()) {
frame->Submit();
return;
Expand Down Expand Up @@ -217,27 +213,25 @@ AndroidExternalViewEmbedder::CreateSurfaceIfNeeded(GrDirectContext* context,
// |ExternalViewEmbedder|
PostPrerollResult AndroidExternalViewEmbedder::PostPrerollAction(
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
// This frame may remove existing platform views that aren't contained
// in `composition_order_`.
//
// If this frame doesn't have platform views, it's still required to keep
// the rasterizer running on the platform thread for at least one more
// frame.
//
// To keep the rasterizer running on the platform thread one more frame,
// `kDefaultMergedLeaseDuration` must be at least `1`.
if (!FrameHasPlatformLayers()) {
return PostPrerollResult::kSuccess;
}
if (raster_thread_merger->IsMerged()) {
raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
} else {
// Merge the raster and platform threads in `EndFrame`.
should_run_rasterizer_on_platform_thread_ = true;
if (!raster_thread_merger->IsMerged()) {
// The raster thread merger may be disabled if the rasterizer is being
// created or teared down.
//
// In such cases, the current frame is dropped, and a new frame is attempted
// with the same layer tree.
//
// Eventually, the frame is submitted once this method returns `kSuccess`.
// At that point, the raster tasks are handled on the platform thread.
raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
CancelFrame();
return PostPrerollResult::kResubmitFrame;
return PostPrerollResult::kSkipAndRetryFrame;
}
raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
// Surface switch requires to resubmit the frame.
// TODO(egarciad): https://github.com/flutter/flutter/issues/65652
if (previous_frame_view_count_ == 0) {
return PostPrerollResult::kResubmitFrame;
}
Expand Down Expand Up @@ -291,17 +285,6 @@ void AndroidExternalViewEmbedder::CancelFrame() {
void AndroidExternalViewEmbedder::EndFrame(
bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
if (should_resubmit_frame && should_run_rasterizer_on_platform_thread_) {
raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
if (raster_thread_merger->IsMerged()) {
// The raster thread merger may be disabled if the rasterizer is being
// teared down.
//
// Therefore, set `should_run_rasterizer_on_platform_thread_` to `false`
// only if the thread merger was able to set the lease.
should_run_rasterizer_on_platform_thread_ = false;
}
}
surface_pool_->RecycleLayers();
// JNI method must be called on the platform thread.
if (raster_thread_merger->IsOnPlatformThread()) {
Expand Down
Loading

0 comments on commit 4654fc6

Please sign in to comment.