mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Rasterizer is initialized with an external view embedder (flutter/engine#22405)
This allows us to not rely on surface methods for getting the external view embedder. Conflicts: shell/common/rasterizer.cc shell/common/rasterizer_unittests.cc
This commit is contained in:
parent
4026f4ae32
commit
417c869d6b
@ -563,6 +563,8 @@ 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_;
|
||||
@ -575,8 +577,6 @@ class PlatformView {
|
||||
// GPU task runner.
|
||||
virtual std::unique_ptr<Surface> CreateRenderingSurface();
|
||||
|
||||
virtual std::shared_ptr<ExternalViewEmbedder> CreateExternalViewEmbedder();
|
||||
|
||||
private:
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(PlatformView);
|
||||
};
|
||||
|
||||
@ -76,8 +76,8 @@ void Rasterizer::Setup(std::unique_ptr<Surface> surface) {
|
||||
user_override_resource_cache_bytes_);
|
||||
}
|
||||
compositor_context_->OnGrContextCreated();
|
||||
if (surface_->GetExternalViewEmbedder() &&
|
||||
surface_->GetExternalViewEmbedder()->SupportsDynamicThreadMerging() &&
|
||||
if (external_view_embedder_ &&
|
||||
external_view_embedder_->SupportsDynamicThreadMerging() &&
|
||||
!raster_thread_merger_) {
|
||||
const auto platform_id =
|
||||
delegate_.GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId();
|
||||
@ -191,9 +191,9 @@ void Rasterizer::Draw(fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline,
|
||||
}
|
||||
|
||||
// EndFrame should perform cleanups for the external_view_embedder.
|
||||
if (surface_ != nullptr && surface_->GetExternalViewEmbedder() != nullptr) {
|
||||
surface_->GetExternalViewEmbedder()->EndFrame(should_resubmit_frame,
|
||||
raster_thread_merger_);
|
||||
if (external_view_embedder_) {
|
||||
external_view_embedder_->EndFrame(should_resubmit_frame,
|
||||
raster_thread_merger_);
|
||||
}
|
||||
|
||||
// Consume as many pipeline items as possible. But yield the event loop
|
||||
@ -423,14 +423,12 @@ 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 != nullptr) {
|
||||
external_view_embedder->BeginFrame(
|
||||
if (external_view_embedder_) {
|
||||
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`.
|
||||
@ -453,13 +451,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, // 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_.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
|
||||
);
|
||||
|
||||
if (compositor_frame) {
|
||||
@ -468,11 +466,11 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) {
|
||||
raster_status == RasterStatus::kSkipAndRetry) {
|
||||
return raster_status;
|
||||
}
|
||||
if (external_view_embedder != nullptr &&
|
||||
if (external_view_embedder_ &&
|
||||
(!raster_thread_merger_ || raster_thread_merger_->IsMerged())) {
|
||||
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();
|
||||
}
|
||||
@ -653,6 +651,11 @@ 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;
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#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"
|
||||
@ -349,6 +350,16 @@ 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`.
|
||||
@ -437,6 +448,7 @@ 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,
|
||||
|
||||
@ -113,9 +113,9 @@ TEST(RasterizerTest,
|
||||
auto rasterizer = std::make_unique<Rasterizer>(delegate);
|
||||
auto surface = std::make_unique<MockSurface>();
|
||||
|
||||
MockExternalViewEmbedder external_view_embedder;
|
||||
EXPECT_CALL(*surface, GetExternalViewEmbedder())
|
||||
.WillRepeatedly(Return(&external_view_embedder));
|
||||
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,
|
||||
@ -123,15 +123,15 @@ TEST(RasterizerTest,
|
||||
EXPECT_CALL(*surface, AcquireFrame(SkISize()))
|
||||
.WillOnce(Return(ByMove(std::move(surface_frame))));
|
||||
|
||||
EXPECT_CALL(external_view_embedder,
|
||||
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, SubmitFrame).Times(1);
|
||||
EXPECT_CALL(
|
||||
external_view_embedder,
|
||||
*external_view_embedder,
|
||||
EndFrame(/*should_resubmit_frame=*/false,
|
||||
/*raster_thread_merger=*/fml::RefPtr<fml::RasterThreadMerger>(
|
||||
nullptr)))
|
||||
@ -170,10 +170,10 @@ TEST(
|
||||
EXPECT_CALL(delegate, OnFrameRasterized(_));
|
||||
auto rasterizer = std::make_unique<Rasterizer>(delegate);
|
||||
auto surface = std::make_unique<MockSurface>();
|
||||
MockExternalViewEmbedder external_view_embedder;
|
||||
EXPECT_CALL(*surface, GetExternalViewEmbedder())
|
||||
.WillRepeatedly(Return(&external_view_embedder));
|
||||
EXPECT_CALL(external_view_embedder, SupportsDynamicThreadMerging)
|
||||
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,
|
||||
@ -181,14 +181,14 @@ TEST(
|
||||
EXPECT_CALL(*surface, AcquireFrame(SkISize()))
|
||||
.WillOnce(Return(ByMove(std::move(surface_frame))));
|
||||
|
||||
EXPECT_CALL(external_view_embedder,
|
||||
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=*/_))
|
||||
EXPECT_CALL(*external_view_embedder, SubmitFrame).Times(0);
|
||||
EXPECT_CALL(*external_view_embedder, EndFrame(/*should_resubmit_frame=*/false,
|
||||
/*raster_thread_merger=*/_))
|
||||
.Times(1);
|
||||
|
||||
rasterizer->Setup(std::move(surface));
|
||||
@ -229,26 +229,26 @@ TEST(
|
||||
auto rasterizer = std::make_unique<Rasterizer>(delegate);
|
||||
auto surface = std::make_unique<MockSurface>();
|
||||
|
||||
MockExternalViewEmbedder external_view_embedder;
|
||||
EXPECT_CALL(*surface, GetExternalViewEmbedder())
|
||||
.WillRepeatedly(Return(&external_view_embedder));
|
||||
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)
|
||||
EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging)
|
||||
.WillRepeatedly(Return(true));
|
||||
|
||||
EXPECT_CALL(external_view_embedder,
|
||||
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=*/_))
|
||||
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));
|
||||
|
||||
@ -547,6 +547,10 @@ 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();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user