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 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: 2 additions & 2 deletions shell/common/platform_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,8 +582,6 @@ class PlatformView {
ComputePlatformResolvedLocales(
const std::vector<std::string>& supported_locale_data);

virtual std::shared_ptr<ExternalViewEmbedder> CreateExternalViewEmbedder();

protected:
PlatformView::Delegate& delegate_;
const TaskRunners task_runners_;
Expand All @@ -596,6 +594,8 @@ class PlatformView {
// GPU task runner.
virtual std::unique_ptr<Surface> CreateRenderingSurface();

virtual std::shared_ptr<ExternalViewEmbedder> CreateExternalViewEmbedder();

private:
FML_DISALLOW_COPY_AND_ASSIGN(PlatformView);
};
Expand Down
47 changes: 22 additions & 25 deletions shell/common/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ void Rasterizer::Setup(std::unique_ptr<Surface> surface) {
user_override_resource_cache_bytes_);
}
compositor_context_->OnGrContextCreated();
if (external_view_embedder_ &&
external_view_embedder_->SupportsDynamicThreadMerging() &&
if (surface_->GetExternalViewEmbedder() &&
surface_->GetExternalViewEmbedder()->SupportsDynamicThreadMerging() &&
!raster_thread_merger_) {
const auto platform_id =
delegate_.GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId();
Expand Down Expand Up @@ -190,10 +190,11 @@ void Rasterizer::Draw(fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline,
consume_result = PipelineConsumeResult::MoreAvailable;
}

// EndFrame should perform cleanups for the external_view_embedder.
if (external_view_embedder_) {
external_view_embedder_->EndFrame(should_resubmit_frame,
raster_thread_merger_);
// Merging the thread as we know the next `Draw` should be run on the platform
// thread.
if (surface_ != nullptr && surface_->GetExternalViewEmbedder() != nullptr) {
surface_->GetExternalViewEmbedder()->EndFrame(should_resubmit_frame,
raster_thread_merger_);
}

// Consume as many pipeline items as possible. But yield the event loop
Expand Down Expand Up @@ -423,12 +424,14 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) {
// for instrumentation.
compositor_context_->ui_time().SetLapTime(layer_tree.build_time());

auto* external_view_embedder = surface_->GetExternalViewEmbedder();

SkCanvas* embedder_root_canvas = nullptr;
if (external_view_embedder_) {
external_view_embedder_->BeginFrame(
if (external_view_embedder != nullptr) {
external_view_embedder->BeginFrame(
layer_tree.frame_size(), surface_->GetContext(),
layer_tree.device_pixel_ratio(), raster_thread_merger_);
embedder_root_canvas = external_view_embedder_->GetRootCanvas();
embedder_root_canvas = external_view_embedder->GetRootCanvas();
}

// On Android, the external view embedder deletes surfaces in `BeginFrame`.
Expand All @@ -451,13 +454,13 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) {
embedder_root_canvas ? embedder_root_canvas : frame->SkiaCanvas();

auto compositor_frame = compositor_context_->AcquireFrame(
surface_->GetContext(), // skia GrContext
root_surface_canvas, // root surface canvas
external_view_embedder_.get(), // external view embedder
root_surface_transformation, // root surface transformation
true, // instrumentation enabled
frame->supports_readback(), // surface supports pixel reads
raster_thread_merger_ // thread merger
surface_->GetContext(), // skia GrContext
root_surface_canvas, // root surface canvas
external_view_embedder, // external view embedder
root_surface_transformation, // root surface transformation
true, // instrumentation enabled
frame->supports_readback(), // surface supports pixel reads
raster_thread_merger_ // thread merger
);

if (compositor_frame) {
Expand All @@ -466,11 +469,10 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) {
raster_status == RasterStatus::kSkipAndRetry) {
return raster_status;
}
if (external_view_embedder_ != nullptr &&
(!raster_thread_merger_ || raster_thread_merger_->IsMerged())) {
if (external_view_embedder != nullptr) {
FML_DCHECK(!frame->IsSubmitted());
external_view_embedder_->SubmitFrame(surface_->GetContext(),
std::move(frame));
external_view_embedder->SubmitFrame(surface_->GetContext(),
std::move(frame));
} else {
frame->Submit();
}
Expand Down Expand Up @@ -651,11 +653,6 @@ void Rasterizer::SetNextFrameCallback(const fml::closure& callback) {
next_frame_callback_ = callback;
}

void Rasterizer::SetExternalViewEmbedder(
const std::shared_ptr<ExternalViewEmbedder>& view_embedder) {
external_view_embedder_ = view_embedder;
}

void Rasterizer::FireNextFrameCallbackIfPresent() {
if (!next_frame_callback_) {
return;
Expand Down
12 changes: 0 additions & 12 deletions shell/common/rasterizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <memory>
#include <optional>

#include "flow/embedded_views.h"
#include "flutter/common/settings.h"
#include "flutter/common/task_runners.h"
#include "flutter/flow/compositor_context.h"
Expand Down Expand Up @@ -350,16 +349,6 @@ class Rasterizer final : public SnapshotDelegate {
///
void SetNextFrameCallback(const fml::closure& callback);

//----------------------------------------------------------------------------
/// @brief Set the External View Embedder. This is done on shell
/// initialization. This is non-null on platforms that support
/// embedding externally composited views.
///
/// @param[in] view_embedder The external view embedder object.
///
void SetExternalViewEmbedder(
const std::shared_ptr<ExternalViewEmbedder>& view_embedder);

//----------------------------------------------------------------------------
/// @brief Returns a pointer to the compositor context used by this
/// rasterizer. This pointer will never be `nullptr`.
Expand Down Expand Up @@ -448,7 +437,6 @@ class Rasterizer final : public SnapshotDelegate {
std::optional<size_t> max_cache_bytes_;
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger_;
fml::TaskRunnerAffineWeakPtrFactory<Rasterizer> weak_factory_;
std::shared_ptr<ExternalViewEmbedder> external_view_embedder_;

// |SnapshotDelegate|
sk_sp<SkImage> MakeRasterSnapshot(sk_sp<SkPicture> picture,
Expand Down
152 changes: 12 additions & 140 deletions shell/common/rasterizer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#define FML_USED_ON_EMBEDDER

#include "flutter/shell/common/rasterizer.h"

#include "flutter/shell/common/thread_host.h"
#include "flutter/testing/testing.h"
#include "gmock/gmock.h"

using testing::_;
using testing::ByMove;
using testing::Return;
using testing::ReturnRef;

Expand Down Expand Up @@ -95,65 +92,7 @@ TEST(RasterizerTest, drawEmptyPipeline) {
latch.Wait();
}

TEST(RasterizerTest,
drawWithExternalViewEmbedder_ExternalViewEmbedderSubmitFrameCalled) {
std::string test_name =
::testing::UnitTest::GetInstance()->current_test_info()->name();
ThreadHost thread_host("io.flutter.test." + test_name + ".",
ThreadHost::Type::Platform | ThreadHost::Type::GPU |
ThreadHost::Type::IO | ThreadHost::Type::UI);
TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(),
thread_host.raster_thread->GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());
MockDelegate delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));
EXPECT_CALL(delegate, OnFrameRasterized(_));
auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();
std::shared_ptr<MockExternalViewEmbedder> external_view_embedder =
std::make_shared<MockExternalViewEmbedder>();
rasterizer->SetExternalViewEmbedder(external_view_embedder);

auto surface_frame = std::make_unique<SurfaceFrame>(
/*surface=*/nullptr, /*supports_readback=*/true,
/*submit_callback=*/[](const SurfaceFrame&, SkCanvas*) { return true; });
EXPECT_CALL(*surface, AcquireFrame(SkISize()))
.WillOnce(Return(ByMove(std::move(surface_frame))));

EXPECT_CALL(*external_view_embedder,
BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr,
/*device_pixel_ratio=*/2.0,
/*raster_thread_merger=*/
fml::RefPtr<fml::RasterThreadMerger>(nullptr)))
.Times(1);
EXPECT_CALL(*external_view_embedder, SubmitFrame).Times(1);
EXPECT_CALL(
*external_view_embedder,
EndFrame(/*should_resubmit_frame=*/false,
/*raster_thread_merger=*/fml::RefPtr<fml::RasterThreadMerger>(
nullptr)))
.Times(1);

rasterizer->Setup(std::move(surface));
fml::AutoResetWaitableEvent latch;
thread_host.raster_thread->GetTaskRunner()->PostTask([&] {
auto pipeline = fml::AdoptRef(new Pipeline<LayerTree>(/*depth=*/10));
auto layer_tree = std::make_unique<LayerTree>(/*frame_size=*/SkISize(),
/*device_pixel_ratio=*/2.0f);
bool result = pipeline->Produce().Complete(std::move(layer_tree));
EXPECT_TRUE(result);
auto no_discard = [](LayerTree&) { return false; };
rasterizer->Draw(pipeline, no_discard);
latch.Signal();
});
latch.Wait();
}

TEST(
RasterizerTest,
drawWithExternalViewEmbedderAndThreadMergerNotMerged_ExternalViewEmbedderSubmitFrameNotCalled) {
TEST(RasterizerTest, drawWithExternalViewEmbedder) {
std::string test_name =
::testing::UnitTest::GetInstance()->current_test_info()->name();
ThreadHost thread_host("io.flutter.test." + test_name + ".",
Expand All @@ -169,27 +108,14 @@ TEST(
EXPECT_CALL(delegate, OnFrameRasterized(_));
auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();
std::shared_ptr<MockExternalViewEmbedder> external_view_embedder =
std::make_shared<MockExternalViewEmbedder>();
rasterizer->SetExternalViewEmbedder(external_view_embedder);
EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging)
.WillRepeatedly(Return(true));
auto surface_frame = std::make_unique<SurfaceFrame>(
/*surface=*/nullptr, /*supports_readback=*/true,
/*submit_callback=*/[](const SurfaceFrame&, SkCanvas*) { return true; });
EXPECT_CALL(*surface, AcquireFrame(SkISize()))
.WillOnce(Return(ByMove(std::move(surface_frame))));

EXPECT_CALL(*external_view_embedder,
BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr,
/*device_pixel_ratio=*/2.0,
/*raster_thread_merger=*/_))
.Times(1);
EXPECT_CALL(*external_view_embedder, SubmitFrame).Times(0);
EXPECT_CALL(*external_view_embedder, EndFrame(/*should_resubmit_frame=*/false,
/*raster_thread_merger=*/_))
.Times(1);

MockExternalViewEmbedder external_view_embedder;
EXPECT_CALL(*surface, GetExternalViewEmbedder())
.WillRepeatedly(Return(&external_view_embedder));
EXPECT_CALL(external_view_embedder,
BeginFrame(SkISize(), nullptr, 2.0,
fml::RefPtr<fml::RasterThreadMerger>(nullptr)));
EXPECT_CALL(external_view_embedder,
EndFrame(false, fml::RefPtr<fml::RasterThreadMerger>(nullptr)));
rasterizer->Setup(std::move(surface));
fml::AutoResetWaitableEvent latch;
thread_host.raster_thread->GetTaskRunner()->PostTask([&] {
Expand All @@ -198,66 +124,12 @@ TEST(
/*device_pixel_ratio=*/2.0f);
bool result = pipeline->Produce().Complete(std::move(layer_tree));
EXPECT_TRUE(result);
auto no_discard = [](LayerTree&) { return false; };
std::function<bool(LayerTree&)> no_discard = [](LayerTree&) {
return false;
};
rasterizer->Draw(pipeline, no_discard);
latch.Signal();
});
latch.Wait();
}

TEST(
RasterizerTest,
drawWithExternalViewEmbedderAndThreadsMerged_ExternalViewEmbedderSubmitFrameCalled) {
std::string test_name =
::testing::UnitTest::GetInstance()->current_test_info()->name();
ThreadHost thread_host("io.flutter.test." + test_name + ".",
ThreadHost::Type::Platform | ThreadHost::Type::GPU |
ThreadHost::Type::IO | ThreadHost::Type::UI);
fml::MessageLoop::EnsureInitializedForCurrentThread();
TaskRunners task_runners("test",
fml::MessageLoop::GetCurrent().GetTaskRunner(),
fml::MessageLoop::GetCurrent().GetTaskRunner(),
thread_host.ui_thread->GetTaskRunner(),
thread_host.io_thread->GetTaskRunner());

MockDelegate delegate;
EXPECT_CALL(delegate, GetTaskRunners())
.WillRepeatedly(ReturnRef(task_runners));
EXPECT_CALL(delegate, OnFrameRasterized(_));

auto rasterizer = std::make_unique<Rasterizer>(delegate);
auto surface = std::make_unique<MockSurface>();

std::shared_ptr<MockExternalViewEmbedder> external_view_embedder =
std::make_shared<MockExternalViewEmbedder>();
rasterizer->SetExternalViewEmbedder(external_view_embedder);

auto surface_frame = std::make_unique<SurfaceFrame>(
/*surface=*/nullptr, /*supports_readback=*/true,
/*submit_callback=*/[](const SurfaceFrame&, SkCanvas*) { return true; });
EXPECT_CALL(*surface, AcquireFrame(SkISize()))
.WillOnce(Return(ByMove(std::move(surface_frame))));
EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging)
.WillRepeatedly(Return(true));

EXPECT_CALL(*external_view_embedder,
BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr,
/*device_pixel_ratio=*/2.0,
/*raster_thread_merger=*/_))
.Times(1);
EXPECT_CALL(*external_view_embedder, SubmitFrame).Times(1);
EXPECT_CALL(*external_view_embedder, EndFrame(/*should_resubmit_frame=*/false,
/*raster_thread_merger=*/_))
.Times(1);

rasterizer->Setup(std::move(surface));

auto pipeline = fml::AdoptRef(new Pipeline<LayerTree>(/*depth=*/10));
auto layer_tree = std::make_unique<LayerTree>(/*frame_size=*/SkISize(),
/*device_pixel_ratio=*/2.0f);
bool result = pipeline->Produce().Complete(std::move(layer_tree));
EXPECT_TRUE(result);
auto no_discard = [](LayerTree&) { return false; };
rasterizer->Draw(pipeline, no_discard);
}
} // namespace flutter
4 changes: 0 additions & 4 deletions shell/common/shell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -547,10 +547,6 @@ bool Shell::Setup(std::unique_ptr<PlatformView> platform_view,
rasterizer_ = std::move(rasterizer);
io_manager_ = std::move(io_manager);

// Set the external view embedder for the rasterizer.
auto view_embedder = platform_view_->CreateExternalViewEmbedder();
rasterizer_->SetExternalViewEmbedder(view_embedder);

// The weak ptr must be generated in the platform thread which owns the unique
// ptr.
weak_engine_ = engine_->GetWeakPtr();
Expand Down
Loading