Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 5 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->SupportDynamicThreadMerging(), true);
}

} // 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