Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Only create raster_thread_merge when explicitly requested by the embedding platform #20487

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions flow/embedded_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,8 @@ const std::vector<std::shared_ptr<Mutator>>::const_iterator MutatorsStack::End()
return vector_.end();
};

bool ExternalViewEmbedder::SupportsDynamicThreadMerging() {
return false;
}

} // namespace flutter
14 changes: 14 additions & 0 deletions flow/embedded_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,10 @@ class ExternalViewEmbedder {
// sets the stage for the next pre-roll.
virtual void CancelFrame() = 0;

// Indicates the begining of a frame.
//
// The `raster_thread_merger` will be null if |SupportsDynamicThreadMerging|
// returns false.
virtual void BeginFrame(
SkISize frame_size,
GrDirectContext* context,
Expand Down Expand Up @@ -306,10 +310,20 @@ class ExternalViewEmbedder {
// A new frame on the platform thread starts immediately. If the GPU thread
// still has some task running, there could be two frames being rendered
// concurrently, which causes undefined behaviors.
//
// The `raster_thread_merger` will be null if |SupportsDynamicThreadMerging|
// returns false.
virtual void EndFrame(
bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {}

// Whether the embedder should support dynamic thread merging.
//
// Returning `true` results a |RasterThreadMerger| instance to be created.
// * See also |BegineFrame| and |EndFrame| for getting the
// |RasterThreadMerger| instance.
virtual bool SupportsDynamicThreadMerging();

FML_DISALLOW_COPY_AND_ASSIGN(ExternalViewEmbedder);

}; // ExternalViewEmbedder
Expand Down
3 changes: 2 additions & 1 deletion shell/common/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ void Rasterizer::Setup(std::unique_ptr<Surface> surface) {
#if !defined(OS_FUCHSIA)
// TODO(sanjayc77): https://github.com/flutter/flutter/issues/53179. Add
// support for raster thread merger for Fuchsia.
if (surface_->GetExternalViewEmbedder()) {
if (surface_->GetExternalViewEmbedder() &&
surface_->GetExternalViewEmbedder()->SupportsDynamicThreadMerging()) {
const auto platform_id =
task_runners_.GetPlatformTaskRunner()->GetTaskQueueId();
const auto gpu_id = task_runners_.GetRasterTaskRunner()->GetTaskQueueId();
Expand Down
6 changes: 5 additions & 1 deletion shell/common/shell_test_external_view_embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,16 @@ void ShellTestExternalViewEmbedder::SubmitFrame(
void ShellTestExternalViewEmbedder::EndFrame(
bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
end_frame_call_back_(should_resubmit_frame);
end_frame_call_back_(should_resubmit_frame, raster_thread_merger);
}

// |ExternalViewEmbedder|
SkCanvas* ShellTestExternalViewEmbedder::GetRootCanvas() {
return nullptr;
}

bool ShellTestExternalViewEmbedder::SupportsDynamicThreadMerging() {
return support_thread_merging_;
}

} // namespace flutter
14 changes: 11 additions & 3 deletions shell/common/shell_test_external_view_embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ namespace flutter {
///
class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder {
public:
using EndFrameCallBack = std::function<void(bool)>;
using EndFrameCallBack =
std::function<void(bool, fml::RefPtr<fml::RasterThreadMerger>)>;

ShellTestExternalViewEmbedder(const EndFrameCallBack& end_frame_call_back,
PostPrerollResult post_preroll_result)
PostPrerollResult post_preroll_result,
bool support_thread_merging)
: end_frame_call_back_(end_frame_call_back),
post_preroll_result_(post_preroll_result) {}
post_preroll_result_(post_preroll_result),
support_thread_merging_(support_thread_merging) {}

~ShellTestExternalViewEmbedder() = default;

Expand Down Expand Up @@ -62,9 +65,14 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder {
// |ExternalViewEmbedder|
SkCanvas* GetRootCanvas() override;

// |ExternalViewEmbedder|
bool SupportsDynamicThreadMerging() override;

const EndFrameCallBack end_frame_call_back_;
const PostPrerollResult post_preroll_result_;

bool support_thread_merging_;

FML_DISALLOW_COPY_AND_ASSIGN(ShellTestExternalViewEmbedder);
};

Expand Down
63 changes: 57 additions & 6 deletions shell/common/shell_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -478,18 +478,69 @@ TEST_F(ShellTest, FrameRasterizedCallbackIsCalled) {
#if !defined(OS_FUCHSIA)
// TODO(sanjayc77): https://github.com/flutter/flutter/issues/53179. Add
// support for raster thread merger for Fuchsia.
TEST_F(ShellTest, ExternalEmbedderNoThreadMerger) {
auto settings = CreateSettingsForFixture();
fml::AutoResetWaitableEvent endFrameLatch;
bool end_frame_called = false;
auto end_frame_callback =
[&](bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
ASSERT_TRUE(raster_thread_merger.get() == nullptr);
ASSERT_FALSE(should_resubmit_frame);
end_frame_called = true;
endFrameLatch.Signal();
};
auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
end_frame_callback, PostPrerollResult::kResubmitFrame, false);
auto shell = CreateShell(std::move(settings), GetTaskRunnersForFixture(),
false, external_view_embedder);

// Create the surface needed by rasterizer
PlatformViewNotifyCreated(shell.get());

auto configuration = RunConfiguration::InferFromSettings(settings);
configuration.SetEntrypoint("emptyMain");

RunEngine(shell.get(), std::move(configuration));

LayerTreeBuilder builder = [&](std::shared_ptr<ContainerLayer> root) {
SkPictureRecorder recorder;
SkCanvas* recording_canvas =
recorder.beginRecording(SkRect::MakeXYWH(0, 0, 80, 80));
recording_canvas->drawRect(SkRect::MakeXYWH(0, 0, 80, 80),
SkPaint(SkColor4f::FromColor(SK_ColorRED)));
auto sk_picture = recorder.finishRecordingAsPicture();
fml::RefPtr<SkiaUnrefQueue> queue = fml::MakeRefCounted<SkiaUnrefQueue>(
this->GetCurrentTaskRunner(), fml::TimeDelta::FromSeconds(0));
auto picture_layer = std::make_shared<PictureLayer>(
SkPoint::Make(10, 10),
flutter::SkiaGPUObject<SkPicture>({sk_picture, queue}), false, false);
root->Add(picture_layer);
};

PumpOneFrame(shell.get(), 100, 100, builder);
endFrameLatch.Wait();

ASSERT_TRUE(end_frame_called);

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

TEST_F(ShellTest,
ExternalEmbedderEndFrameIsCalledWhenPostPrerollResultIsResubmit) {
auto settings = CreateSettingsForFixture();
fml::AutoResetWaitableEvent endFrameLatch;
bool end_frame_called = false;
auto end_frame_callback = [&](bool should_resubmit_frame) {
ASSERT_TRUE(should_resubmit_frame);
end_frame_called = true;
endFrameLatch.Signal();
};
auto end_frame_callback =
[&](bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
ASSERT_TRUE(raster_thread_merger.get() != nullptr);
ASSERT_TRUE(should_resubmit_frame);
end_frame_called = true;
endFrameLatch.Signal();
};
auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
end_frame_callback, PostPrerollResult::kResubmitFrame);
end_frame_callback, PostPrerollResult::kResubmitFrame, true);
auto shell = CreateShell(std::move(settings), GetTaskRunnersForFixture(),
false, external_view_embedder);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,4 +295,9 @@ void AndroidExternalViewEmbedder::EndFrame(
}
}

// |ExternalViewEmbedder|
bool AndroidExternalViewEmbedder::SupportsDynamicThreadMerging() {
return true;
}

} // namespace flutter
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder {
bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) override;

bool SupportsDynamicThreadMerging() override;

// Gets the rect based on the device pixel ratio of a platform view displayed
// on the screen.
SkRect GetViewRect(int view_id) const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -556,5 +556,13 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) {
raster_thread_merger);
}

TEST(AndroidExternalViewEmbedder, SupportsDynamicThreadMerging) {
auto jni_mock = std::make_shared<JNIMock>();

auto embedder =
std::make_unique<AndroidExternalViewEmbedder>(nullptr, jni_mock, nullptr);
ASSERT_TRUE(embedder->SupportsDynamicThreadMerging());
}

} // namespace testing
} // namespace flutter
3 changes: 3 additions & 0 deletions shell/platform/darwin/ios/ios_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ class IOSSurface : public ExternalViewEmbedder {
void EndFrame(bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) override;

// |ExternalViewEmbedder|
bool SupportsDynamicThreadMerging() override;

public:
FML_DISALLOW_COPY_AND_ASSIGN(IOSSurface);
};
Expand Down
5 changes: 5 additions & 0 deletions shell/platform/darwin/ios/ios_surface.mm
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,9 @@ bool IsIosEmbeddedViewsPreviewEnabled() {
return platform_views_controller_->EndFrame(should_resubmit_frame, raster_thread_merger);
}

// |ExternalViewEmbedder|
bool IOSSurface::SupportsDynamicThreadMerging() {
return true;
}

} // namespace flutter