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
2 changes: 1 addition & 1 deletion flow/surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ bool Surface::EnableRasterCache() const {
return true;
}

impeller::AiksContext* Surface::GetAiksContext() const {
std::shared_ptr<impeller::AiksContext> Surface::GetAiksContext() const {
return nullptr;
}

Expand Down
2 changes: 1 addition & 1 deletion flow/surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class Surface {

virtual bool EnableRasterCache() const;

virtual impeller::AiksContext* GetAiksContext() const;
virtual std::shared_ptr<impeller::AiksContext> GetAiksContext() const;

/// Capture the `SurfaceData` currently present in the surface.
///
Expand Down
7 changes: 6 additions & 1 deletion shell/common/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> Rasterizer::GetSnapshotDelegate()
return weak_factory_.GetWeakPtr();
}

void Rasterizer::SetImpellerContext(
std::weak_ptr<impeller::Context> impeller_context) {
impeller_context_ = std::move(impeller_context);
}

void Rasterizer::Setup(std::unique_ptr<Surface> surface) {
surface_ = std::move(surface);

Expand Down Expand Up @@ -542,7 +547,7 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe(
.supports_readback, // surface supports pixel reads
raster_thread_merger_, // thread merger
frame->GetDisplayListBuilder().get(), // display list builder
surface_->GetAiksContext() // aiks context
surface_->GetAiksContext().get() // aiks context
);
if (compositor_frame) {
compositor_context_->raster_cache().BeginFrame();
Expand Down
28 changes: 28 additions & 0 deletions shell/common/rasterizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,25 @@
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/fml/time/time_delta.h"
#include "flutter/fml/time/time_point.h"
#if IMPELLER_SUPPORTS_RENDERING
// GN is having trouble understanding how this works in the Fuchsia builds.
#include "flutter/impeller/aiks/aiks_context.h" // nogncheck
#include "flutter/impeller/renderer/context.h" // nogncheck
#endif // IMPELLER_SUPPORTS_RENDERING
#include "flutter/lib/ui/snapshot_delegate.h"
#include "flutter/shell/common/pipeline.h"
#include "flutter/shell/common/snapshot_controller.h"
#include "flutter/shell/common/snapshot_surface_producer.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"

#if !IMPELLER_SUPPORTS_RENDERING
namespace impeller {
class Context;
class AiksContext;
} // namespace impeller
#endif // !IMPELLER_SUPPORTS_RENDERING

namespace flutter {

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -137,6 +149,8 @@ class Rasterizer final : public SnapshotDelegate,
///
~Rasterizer();

void SetImpellerContext(std::weak_ptr<impeller::Context> impeller_context);

//----------------------------------------------------------------------------
/// @brief Rasterizers may be created well before an on-screen surface is
/// available for rendering. Shells usually create a rasterizer in
Expand Down Expand Up @@ -506,6 +520,19 @@ class Rasterizer final : public SnapshotDelegate,
return surface_;
}

// |SnapshotController::Delegate|
std::shared_ptr<impeller::AiksContext> GetAiksContext() const override {
#if IMPELLER_SUPPORTS_RENDERING
if (surface_) {
return surface_->GetAiksContext();
}
if (auto context = impeller_context_.lock()) {
return std::make_shared<impeller::AiksContext>(context);
}
#endif
return nullptr;
}

// |SnapshotController::Delegate|
const std::unique_ptr<SnapshotSurfaceProducer>& GetSnapshotSurfaceProducer()
const override {
Expand Down Expand Up @@ -541,6 +568,7 @@ class Rasterizer final : public SnapshotDelegate,

Delegate& delegate_;
MakeGpuImageBehavior gpu_image_behavior_;
std::weak_ptr<impeller::Context> impeller_context_;
std::unique_ptr<Surface> surface_;
std::unique_ptr<SnapshotSurfaceProducer> snapshot_surface_producer_;
std::unique_ptr<flutter::CompositorContext> compositor_context_;
Expand Down
23 changes: 13 additions & 10 deletions shell/common/shell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -186,30 +186,33 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
!settings.skia_deterministic_rendering_on_cpu),
is_gpu_disabled));

// Create the platform view on the platform thread (this thread).
auto platform_view = on_create_platform_view(*shell.get());
if (!platform_view || !platform_view->GetWeakPtr()) {
return nullptr;
}

// Create the rasterizer on the raster thread.
std::promise<std::unique_ptr<Rasterizer>> rasterizer_promise;
auto rasterizer_future = rasterizer_promise.get_future();
std::promise<fml::TaskRunnerAffineWeakPtr<SnapshotDelegate>>
snapshot_delegate_promise;
auto snapshot_delegate_future = snapshot_delegate_promise.get_future();
fml::TaskRunner::RunNowOrPostTask(
task_runners.GetRasterTaskRunner(), [&rasterizer_promise, //
&snapshot_delegate_promise,
on_create_rasterizer, //
shell = shell.get() //
task_runners.GetRasterTaskRunner(),
[&rasterizer_promise, //
&snapshot_delegate_promise,
on_create_rasterizer, //
shell = shell.get(), //
impeller_context = platform_view->GetImpellerContext() //
]() {
TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem");
std::unique_ptr<Rasterizer> rasterizer(on_create_rasterizer(*shell));
rasterizer->SetImpellerContext(impeller_context);
snapshot_delegate_promise.set_value(rasterizer->GetSnapshotDelegate());
rasterizer_promise.set_value(std::move(rasterizer));
});

// Create the platform view on the platform thread (this thread).
auto platform_view = on_create_platform_view(*shell.get());
if (!platform_view || !platform_view->GetWeakPtr()) {
return nullptr;
}

// Ask the platform view for the vsync waiter. This will be used by the engine
// to create the animator.
auto vsync_waiter = platform_view->CreateVSyncWaiter();
Expand Down
3 changes: 3 additions & 0 deletions shell/common/shell_test_platform_view_metal.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ class ShellTestPlatformViewMetal final : public ShellTestPlatformView,
// |PlatformView|
std::unique_ptr<Surface> CreateRenderingSurface() override;

// |PlatformView|
std::shared_ptr<impeller::Context> GetImpellerContext() const override;

// |GPUSurfaceMetalDelegate|
GPUCAMetalLayerHandle GetCAMetalLayer(
const SkISize& frame_info) const override;
Expand Down
32 changes: 27 additions & 5 deletions shell/common/shell_test_platform_view_metal.mm
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
#include <utility>

#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/shell/gpu/gpu_surface_metal_impeller.h"
#include "flutter/shell/gpu/gpu_surface_metal_skia.h"
#include "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h"
#include "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h"

namespace flutter {
Expand All @@ -29,12 +31,18 @@
// non-Objective-C TUs.
class DarwinContextMetal {
public:
DarwinContextMetal()
: context_([[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice]),
offscreen_texture_(CreateOffscreenTexture([context_.get() device])) {}
explicit DarwinContextMetal(bool impeller)
: context_(impeller ? nil : [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice]),
impeller_context_(impeller ? [[FlutterDarwinContextMetalImpeller alloc] init] : nil),
offscreen_texture_(CreateOffscreenTexture(
impeller ? [impeller_context_ context]->GetMTLDevice() : [context_ device])) {}

~DarwinContextMetal() = default;

fml::scoped_nsobject<FlutterDarwinContextMetalImpeller> impeller_context() const {
return impeller_context_;
}

fml::scoped_nsobject<FlutterDarwinContextMetalSkia> context() const { return context_; }

fml::scoped_nsprotocol<id<MTLTexture>> offscreen_texture() const { return offscreen_texture_; }
Expand All @@ -48,6 +56,7 @@ GPUMTLTextureInfo offscreen_texture_info() const {

private:
const fml::scoped_nsobject<FlutterDarwinContextMetalSkia> context_;
const fml::scoped_nsobject<FlutterDarwinContextMetalImpeller> impeller_context_;
const fml::scoped_nsprotocol<id<MTLTexture>> offscreen_texture_;

FML_DISALLOW_COPY_AND_ASSIGN(DarwinContextMetal);
Expand All @@ -61,11 +70,15 @@ GPUMTLTextureInfo offscreen_texture_info() const {
std::shared_ptr<ShellTestExternalViewEmbedder> shell_test_external_view_embedder)
: ShellTestPlatformView(delegate, task_runners),
GPUSurfaceMetalDelegate(MTLRenderTargetType::kMTLTexture),
metal_context_(std::make_unique<DarwinContextMetal>()),
metal_context_(std::make_unique<DarwinContextMetal>(GetSettings().enable_impeller)),
create_vsync_waiter_(std::move(create_vsync_waiter)),
vsync_clock_(std::move(vsync_clock)),
shell_test_external_view_embedder_(std::move(shell_test_external_view_embedder)) {
FML_CHECK([metal_context_->context() mainContext] != nil);
if (GetSettings().enable_impeller) {
FML_CHECK([metal_context_->impeller_context() context] != nil);
} else {
FML_CHECK([metal_context_->context() mainContext] != nil);
}
}

ShellTestPlatformViewMetal::~ShellTestPlatformViewMetal() = default;
Expand Down Expand Up @@ -93,10 +106,19 @@ GPUMTLTextureInfo offscreen_texture_info() const {

// |PlatformView|
std::unique_ptr<Surface> ShellTestPlatformViewMetal::CreateRenderingSurface() {
if (GetSettings().enable_impeller) {
return std::make_unique<GPUSurfaceMetalImpeller>(this,
[metal_context_->impeller_context() context]);
}
return std::make_unique<GPUSurfaceMetalSkia>(this, [metal_context_->context() mainContext],
MsaaSampleCount::kNone);
}

// |PlatformView|
std::shared_ptr<impeller::Context> ShellTestPlatformViewMetal::GetImpellerContext() const {
return [metal_context_->impeller_context() context];
}

// |GPUSurfaceMetalDelegate|
GPUCAMetalLayerHandle ShellTestPlatformViewMetal::GetCAMetalLayer(const SkISize& frame_info) const {
FML_CHECK(false) << "A Metal Delegate configured with MTLRenderTargetType::kMTLTexture was asked "
Expand Down
47 changes: 47 additions & 0 deletions shell/common/shell_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3986,6 +3986,53 @@ TEST_F(ShellTest, PictureToImageSync) {
DestroyShell(std::move(shell));
}

TEST_F(ShellTest, PictureToImageSyncImpellerNoSurface) {
#if !SHELL_ENABLE_METAL
// This test uses the Metal backend.
GTEST_SKIP();
#endif // !SHELL_ENABLE_METAL
auto settings = CreateSettingsForFixture();
settings.enable_impeller = true;
std::unique_ptr<Shell> shell =
CreateShell(settings, //
GetTaskRunnersForFixture(), //
false, //
nullptr, //
false, //
ShellTestPlatformView::BackendType::kMetalBackend //
);

AddNativeCallback("NativeOnBeforeToImageSync",
CREATE_NATIVE_ENTRY([&](auto args) {
// nop
}));

fml::CountDownLatch latch(2);
AddNativeCallback("NotifyNative", CREATE_NATIVE_ENTRY([&](auto args) {
// Teardown and set up rasterizer again.
PlatformViewNotifyDestroyed(shell.get());
PlatformViewNotifyCreated(shell.get());
latch.CountDown();
}));

ASSERT_NE(shell, nullptr);
ASSERT_TRUE(shell->IsSetup());
auto configuration = RunConfiguration::InferFromSettings(settings);

// Important: Do not create the platform view yet!
// This test is making sure that the rasterizer can create the texture
// as expected without a surface.

configuration.SetEntrypoint("toImageSync");
RunEngine(shell.get(), std::move(configuration));
PumpOneFrame(shell.get());

latch.Wait();

PlatformViewNotifyDestroyed(shell.get());
DestroyShell(std::move(shell));
}

#if SHELL_ENABLE_GL
// This test uses the GL backend and refers to symbols in egl.h
TEST_F(ShellTest, PictureToImageSyncWithTrampledContext) {
Expand Down
5 changes: 5 additions & 0 deletions shell/common/snapshot_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
#include "flutter/lib/ui/snapshot_delegate.h"
#include "flutter/shell/common/snapshot_surface_producer.h"

namespace impeller {
class AiksContext;
}

namespace flutter {

class SnapshotController {
Expand All @@ -20,6 +24,7 @@ class SnapshotController {
public:
virtual ~Delegate() = default;
virtual const std::unique_ptr<Surface>& GetSurface() const = 0;
virtual std::shared_ptr<impeller::AiksContext> GetAiksContext() const = 0;
virtual const std::unique_ptr<SnapshotSurfaceProducer>&
GetSnapshotSurfaceProducer() const = 0;
virtual std::shared_ptr<const fml::SyncSwitch> GetIsGpuDisabledSyncSwitch()
Expand Down
7 changes: 2 additions & 5 deletions shell/common/snapshot_controller_impeller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,8 @@ sk_sp<DlImage> SnapshotControllerImpeller::DoMakeRasterSnapshot(
impeller::DisplayListDispatcher dispatcher;
display_list->Dispatch(dispatcher);
impeller::Picture picture = dispatcher.EndRecordingAsPicture();
if (GetDelegate().GetSurface() &&
GetDelegate().GetSurface()->GetAiksContext()) {
impeller::AiksContext* context =
GetDelegate().GetSurface()->GetAiksContext();

auto context = GetDelegate().GetAiksContext();
if (context) {
auto max_size = context->GetContext()
->GetResourceAllocator()
->GetMaxTextureSizeSupported();
Expand Down
5 changes: 3 additions & 2 deletions shell/gpu/gpu_surface_gl_impeller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,9 @@ bool GPUSurfaceGLImpeller::EnableRasterCache() const {
}

// |Surface|
impeller::AiksContext* GPUSurfaceGLImpeller::GetAiksContext() const {
return aiks_context_.get();
std::shared_ptr<impeller::AiksContext> GPUSurfaceGLImpeller::GetAiksContext()
const {
return aiks_context_;
}

} // namespace flutter
2 changes: 1 addition & 1 deletion shell/gpu/gpu_surface_gl_impeller.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class GPUSurfaceGLImpeller final : public Surface {
bool EnableRasterCache() const override;

// |Surface|
impeller::AiksContext* GetAiksContext() const override;
std::shared_ptr<impeller::AiksContext> GetAiksContext() const override;

FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceGLImpeller);
};
Expand Down
2 changes: 1 addition & 1 deletion shell/gpu/gpu_surface_metal_impeller.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalImpeller : public Surface {
bool EnableRasterCache() const override;

// |Surface|
impeller::AiksContext* GetAiksContext() const override;
std::shared_ptr<impeller::AiksContext> GetAiksContext() const override;

FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceMetalImpeller);
};
Expand Down
4 changes: 2 additions & 2 deletions shell/gpu/gpu_surface_metal_impeller.mm
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@
}

// |Surface|
impeller::AiksContext* GPUSurfaceMetalImpeller::GetAiksContext() const {
return aiks_context_.get();
std::shared_ptr<impeller::AiksContext> GPUSurfaceMetalImpeller::GetAiksContext() const {
return aiks_context_;
}

Surface::SurfaceData GPUSurfaceMetalImpeller::GetSurfaceData() const {
Expand Down
5 changes: 3 additions & 2 deletions shell/gpu/gpu_surface_vulkan_impeller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ bool GPUSurfaceVulkanImpeller::EnableRasterCache() const {
}

// |Surface|
impeller::AiksContext* GPUSurfaceVulkanImpeller::GetAiksContext() const {
return aiks_context_.get();
std::shared_ptr<impeller::AiksContext>
GPUSurfaceVulkanImpeller::GetAiksContext() const {
return aiks_context_;
}

} // namespace flutter
2 changes: 1 addition & 1 deletion shell/gpu/gpu_surface_vulkan_impeller.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class GPUSurfaceVulkanImpeller final : public Surface {
bool EnableRasterCache() const override;

// |Surface|
impeller::AiksContext* GetAiksContext() const override;
std::shared_ptr<impeller::AiksContext> GetAiksContext() const override;

FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceVulkanImpeller);
};
Expand Down