From 0de644b49721c04482832a10054efabd585ceca6 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 24 Sep 2024 08:18:44 -0700 Subject: [PATCH 1/5] [Impeller] one aiks context per app. --- shell/gpu/gpu_surface_metal_impeller.h | 2 +- shell/gpu/gpu_surface_metal_impeller.mm | 19 +++++++++++-------- shell/platform/darwin/ios/ios_context.h | 3 +++ shell/platform/darwin/ios/ios_context.mm | 4 ++++ .../darwin/ios/ios_context_metal_impeller.h | 5 +++++ .../darwin/ios/ios_context_metal_impeller.mm | 14 +++++++++++++- shell/platform/darwin/ios/ios_surface.h | 4 ---- .../darwin/ios/ios_surface_metal_impeller.h | 1 + .../darwin/ios/ios_surface_metal_impeller.mm | 12 ++++++++---- .../embedder_surface_metal_impeller.h | 2 ++ .../embedder_surface_metal_impeller.mm | 9 ++++++++- 11 files changed, 56 insertions(+), 19 deletions(-) diff --git a/shell/gpu/gpu_surface_metal_impeller.h b/shell/gpu/gpu_surface_metal_impeller.h index 58a269dee20c2..c01139cb3a951 100644 --- a/shell/gpu/gpu_surface_metal_impeller.h +++ b/shell/gpu/gpu_surface_metal_impeller.h @@ -21,7 +21,7 @@ class IMPELLER_CA_METAL_LAYER_AVAILABLE GPUSurfaceMetalImpeller : public Surface { public: GPUSurfaceMetalImpeller(GPUSurfaceMetalDelegate* delegate, - const std::shared_ptr& context, + const std::shared_ptr& context, bool render_to_surface = true); // |Surface| diff --git a/shell/gpu/gpu_surface_metal_impeller.mm b/shell/gpu/gpu_surface_metal_impeller.mm index 6e8c43763e092..0e47cb3c49720 100644 --- a/shell/gpu/gpu_surface_metal_impeller.mm +++ b/shell/gpu/gpu_surface_metal_impeller.mm @@ -8,6 +8,7 @@ #import #include "flow/surface.h" #include "flow/surface_frame.h" +#include "impeller/aiks/aiks_context.h" #include "flutter/common/settings.h" #include "flutter/fml/make_copyable.h" @@ -21,14 +22,13 @@ namespace flutter { -GPUSurfaceMetalImpeller::GPUSurfaceMetalImpeller(GPUSurfaceMetalDelegate* delegate, - const std::shared_ptr& context, - bool render_to_surface) +GPUSurfaceMetalImpeller::GPUSurfaceMetalImpeller( + GPUSurfaceMetalDelegate* delegate, + const std::shared_ptr& context, + bool render_to_surface) : delegate_(delegate), render_target_type_(delegate->GetRenderTargetType()), - aiks_context_( - std::make_shared(context, - impeller::TypographerContextSkia::Make())), + aiks_context_(context), render_to_surface_(render_to_surface) { // If this preference is explicitly set, we allow for disabling partial repaint. NSNumber* disablePartialRepaint = @@ -170,6 +170,7 @@ impeller::RenderTarget render_target = surface->GetTargetRenderPassDescriptor(); surface->SetFrameBoundary(surface_frame.submit_info().frame_boundary); + const bool reset_host_buffer = surface_frame.submit_info().frame_boundary; #if EXPERIMENTAL_CANVAS impeller::TextFrameDispatcher collector(aiks_context->GetContentContext(), impeller::Matrix()); @@ -182,7 +183,9 @@ display_list->Dispatch(impeller_dispatcher, sk_cull_rect); impeller_dispatcher.FinishRecording(); aiks_context->GetContentContext().GetLazyGlyphAtlas()->ResetTextFrames(); - aiks_context->GetContentContext().GetTransientsBuffer().Reset(); + if (reset_host_buffer) { + aiks_context->GetContentContext().GetTransientsBuffer().Reset(); + } if (!surface->PreparePresent()) { return false; @@ -193,7 +196,7 @@ impeller::DlDispatcher impeller_dispatcher(cull_rect); display_list->Dispatch(impeller_dispatcher, sk_cull_rect); auto picture = impeller_dispatcher.EndRecordingAsPicture(); - auto result = aiks_context->Render(picture, render_target, /*reset_host_buffer=*/true); + auto result = aiks_context->Render(picture, render_target, reset_host_buffer); if (!surface->PreparePresent()) { return false; diff --git a/shell/platform/darwin/ios/ios_context.h b/shell/platform/darwin/ios/ios_context.h index ef9dcca778df7..e2c789d0b1975 100644 --- a/shell/platform/darwin/ios/ios_context.h +++ b/shell/platform/darwin/ios/ios_context.h @@ -15,6 +15,7 @@ #include "flutter/fml/synchronization/sync_switch.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h" #import "flutter/shell/platform/darwin/ios/rendering_api_selection.h" +#include "impeller/aiks/aiks_context.h" #include "third_party/skia/include/gpu/ganesh/GrDirectContext.h" namespace impeller { @@ -140,6 +141,8 @@ class IOSContext { virtual std::shared_ptr GetImpellerContext() const; + virtual std::shared_ptr GetAiksContext() const; + protected: explicit IOSContext(); diff --git a/shell/platform/darwin/ios/ios_context.mm b/shell/platform/darwin/ios/ios_context.mm index ac6db41aa57b7..762847e8af780 100644 --- a/shell/platform/darwin/ios/ios_context.mm +++ b/shell/platform/darwin/ios/ios_context.mm @@ -63,4 +63,8 @@ return nullptr; } +std::shared_ptr IOSContext::GetAiksContext() const { + return nullptr; +} + } // namespace flutter diff --git a/shell/platform/darwin/ios/ios_context_metal_impeller.h b/shell/platform/darwin/ios/ios_context_metal_impeller.h index 5e2ed7a32dee9..b5293da6e56a1 100644 --- a/shell/platform/darwin/ios/ios_context_metal_impeller.h +++ b/shell/platform/darwin/ios/ios_context_metal_impeller.h @@ -9,6 +9,7 @@ #include "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h" #include "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h" #include "flutter/shell/platform/darwin/ios/ios_context.h" +#include "impeller/aiks/aiks_context.h" namespace impeller { @@ -34,6 +35,7 @@ class IOSContextMetalImpeller final : public IOSContext { private: fml::scoped_nsobject darwin_context_metal_impeller_; + std::shared_ptr aiks_context_; // |IOSContext| sk_sp CreateResourceContext() override; @@ -49,6 +51,9 @@ class IOSContextMetalImpeller final : public IOSContext { // |IOSContext| std::shared_ptr GetImpellerContext() const override; + // |IOSContext| + std::shared_ptr GetAiksContext() const override; + FML_DISALLOW_COPY_AND_ASSIGN(IOSContextMetalImpeller); }; diff --git a/shell/platform/darwin/ios/ios_context_metal_impeller.mm b/shell/platform/darwin/ios/ios_context_metal_impeller.mm index 92a59a8326c96..7e338b7430745 100644 --- a/shell/platform/darwin/ios/ios_context_metal_impeller.mm +++ b/shell/platform/darwin/ios/ios_context_metal_impeller.mm @@ -3,8 +3,11 @@ // found in the LICENSE file. #import "flutter/shell/platform/darwin/ios/ios_context_metal_impeller.h" + #include "flutter/impeller/entity/mtl/entity_shaders.h" #import "flutter/shell/platform/darwin/ios/ios_external_texture_metal.h" +#include "impeller/aiks/aiks_context.h" +#include "impeller/typographer/backends/skia/typographer_context_skia.h" FLUTTER_ASSERT_ARC @@ -13,7 +16,11 @@ IOSContextMetalImpeller::IOSContextMetalImpeller( const std::shared_ptr& is_gpu_disabled_sync_switch) : darwin_context_metal_impeller_(fml::scoped_nsobject{ - [[FlutterDarwinContextMetalImpeller alloc] init:is_gpu_disabled_sync_switch]}) {} + [[FlutterDarwinContextMetalImpeller alloc] init:is_gpu_disabled_sync_switch]}) { + if (darwin_context_metal_impeller_.get().context) + aiks_context_ = std::make_shared( + darwin_context_metal_impeller_.get().context, impeller::TypographerContextSkia::Make()); +} IOSContextMetalImpeller::~IOSContextMetalImpeller() = default; @@ -39,6 +46,11 @@ return darwin_context_metal_impeller_.get().context; } +// |IOSContext| +std::shared_ptr IOSContextMetalImpeller::GetAiksContext() const { + return aiks_context_; +} + // |IOSContext| std::unique_ptr IOSContextMetalImpeller::MakeCurrent() { // This only makes sense for contexts that need to be bound to a specific thread. diff --git a/shell/platform/darwin/ios/ios_surface.h b/shell/platform/darwin/ios/ios_surface.h index 78394f25781c6..96970a465b531 100644 --- a/shell/platform/darwin/ios/ios_surface.h +++ b/shell/platform/darwin/ios/ios_surface.h @@ -18,10 +18,6 @@ namespace flutter { -// Returns true if the app explicitly specified to use the iOS view embedding -// mechanism which is still in a release preview. -bool IsIosEmbeddedViewsPreviewEnabled(); - class IOSSurface { public: static std::unique_ptr Create(std::shared_ptr context, diff --git a/shell/platform/darwin/ios/ios_surface_metal_impeller.h b/shell/platform/darwin/ios/ios_surface_metal_impeller.h index 888f3935355e3..86c5171caac23 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_impeller.h +++ b/shell/platform/darwin/ios/ios_surface_metal_impeller.h @@ -30,6 +30,7 @@ class SK_API_AVAILABLE_CA_METAL_LAYER IOSSurfaceMetalImpeller final private: fml::scoped_nsobject layer_; const std::shared_ptr impeller_context_; + std::shared_ptr aiks_context_; bool is_valid_ = false; // |IOSSurface| diff --git a/shell/platform/darwin/ios/ios_surface_metal_impeller.mm b/shell/platform/darwin/ios/ios_surface_metal_impeller.mm index 8d1a75d6f1893..89b7e729108f5 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_impeller.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_impeller.mm @@ -7,6 +7,9 @@ #include "flutter/impeller/renderer/backend/metal/formats_mtl.h" #include "flutter/impeller/renderer/context.h" #include "flutter/shell/gpu/gpu_surface_metal_impeller.h" +#include "impeller/aiks/aiks_context.h" +#include "impeller/typographer/backends/skia/typographer_context_skia.h" +#include "impeller/typographer/typographer_context.h" FLUTTER_ASSERT_ARC @@ -17,8 +20,9 @@ : IOSSurface(context), GPUSurfaceMetalDelegate(MTLRenderTargetType::kCAMetalLayer), layer_(layer), - impeller_context_(context ? context->GetImpellerContext() : nullptr) { - if (!impeller_context_) { + impeller_context_(context ? context->GetImpellerContext() : nullptr), + aiks_context_(context ? context->GetAiksContext() : nullptr) { + if (!impeller_context_ || !aiks_context_) { return; } is_valid_ = true; @@ -41,8 +45,8 @@ std::unique_ptr IOSSurfaceMetalImpeller::CreateGPUSurface(GrDirectContext*) { impeller_context_->UpdateOffscreenLayerPixelFormat( impeller::FromMTLPixelFormat(layer_.get().pixelFormat)); - return std::make_unique(this, // - impeller_context_ // + return std::make_unique(this, // + aiks_context_ // ); } diff --git a/shell/platform/embedder/embedder_surface_metal_impeller.h b/shell/platform/embedder/embedder_surface_metal_impeller.h index 109870aa6f129..3589f7facddd9 100644 --- a/shell/platform/embedder/embedder_surface_metal_impeller.h +++ b/shell/platform/embedder/embedder_surface_metal_impeller.h @@ -12,6 +12,7 @@ #include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" #include "flutter/shell/platform/embedder/embedder_surface.h" #include "fml/concurrent_message_loop.h" +#include "impeller/aiks/aiks_context.h" namespace impeller { class Context; @@ -41,6 +42,7 @@ class EmbedderSurfaceMetalImpeller final : public EmbedderSurface, MetalDispatchTable metal_dispatch_table_; std::shared_ptr external_view_embedder_; std::shared_ptr context_; + std::shared_ptr aiks_context_; // |EmbedderSurface| bool IsValid() const override; diff --git a/shell/platform/embedder/embedder_surface_metal_impeller.mm b/shell/platform/embedder/embedder_surface_metal_impeller.mm index d1d1265dd99d7..63653888618cc 100644 --- a/shell/platform/embedder/embedder_surface_metal_impeller.mm +++ b/shell/platform/embedder/embedder_surface_metal_impeller.mm @@ -12,10 +12,13 @@ #include "flutter/shell/gpu/gpu_surface_metal_delegate.h" #include "flutter/shell/gpu/gpu_surface_metal_impeller.h" #import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h" +#include "impeller/aiks/aiks_context.h" #include "impeller/entity/mtl/entity_shaders.h" #include "impeller/entity/mtl/framebuffer_blend_shaders.h" #include "impeller/entity/mtl/modern_shaders.h" #include "impeller/renderer/backend/metal/context_mtl.h" +#include "impeller/typographer/backends/skia/typographer_context_skia.h" +#include "impeller/typographer/typographer_context.h" FLUTTER_ASSERT_NOT_ARC @@ -60,9 +63,13 @@ if (!IsValid()) { return nullptr; } + if (!aiks_context_) { + aiks_context_ = + std::make_shared(context_, impeller::TypographerContextSkia::Make()); + } const bool render_to_surface = !external_view_embedder_; - auto surface = std::make_unique(this, context_, render_to_surface); + auto surface = std::make_unique(this, aiks_context_, render_to_surface); if (!surface->IsValid()) { return nullptr; From 7d285a6f71a2d9c2b55a3a1d4b6a376e95234979 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 24 Sep 2024 10:13:26 -0700 Subject: [PATCH 2/5] ++ --- .../gpu_surface_metal_impeller_unittests.mm | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/shell/gpu/gpu_surface_metal_impeller_unittests.mm b/shell/gpu/gpu_surface_metal_impeller_unittests.mm index 16632279ebaac..b0afbb6a1729d 100644 --- a/shell/gpu/gpu_surface_metal_impeller_unittests.mm +++ b/shell/gpu/gpu_surface_metal_impeller_unittests.mm @@ -7,10 +7,12 @@ #include "flutter/shell/gpu/gpu_surface_metal_impeller.h" #include "gtest/gtest.h" +#include "impeller/aiks/aiks_context.h" #include "impeller/entity/mtl/entity_shaders.h" #include "impeller/entity/mtl/framebuffer_blend_shaders.h" #include "impeller/entity/mtl/modern_shaders.h" #include "impeller/renderer/backend/metal/context_mtl.h" +#include "impeller/typographer/typographer_context.h" namespace flutter { namespace testing { @@ -97,14 +99,14 @@ GPUCAMetalLayerHandle GetCAMetalLayer(const SkISize& frame_info) const override ASSERT_TRUE(frame->Submit()); } -// Because each overlay surface gets its own HostBuffer, we always need to reset. -TEST(GPUSurfaceMetalImpeller, DoesNotResetHostBufferBasedOnFrameBoundary) { +TEST(GPUSurfaceMetalImpeller, ResetHostBufferBasedOnFrameBoundary) { auto delegate = std::make_shared(); delegate->SetDevice(); auto context = CreateImpellerContext(); - std::unique_ptr surface = - std::make_unique(delegate.get(), context); + std::unique_ptr surface = std::make_unique( + delegate.get(), + std::make_shared(context, impeller::TypographerContextSkia::Make())); ASSERT_TRUE(surface->IsValid()); @@ -116,13 +118,13 @@ GPUCAMetalLayerHandle GetCAMetalLayer(const SkISize& frame_info) const override frame->set_submit_info({.frame_boundary = false}); ASSERT_TRUE(frame->Submit()); - EXPECT_EQ(host_buffer.GetStateForTest().current_frame, 1u); + EXPECT_EQ(host_buffer.GetStateForTest().current_frame, 0u); frame = surface->AcquireFrame(SkISize::Make(100, 100)); frame->set_submit_info({.frame_boundary = true}); ASSERT_TRUE(frame->Submit()); - EXPECT_EQ(host_buffer.GetStateForTest().current_frame, 2u); + EXPECT_EQ(host_buffer.GetStateForTest().current_frame, 1u); } #ifdef IMPELLER_DEBUG @@ -131,18 +133,20 @@ GPUCAMetalLayerHandle GetCAMetalLayer(const SkISize& frame_info) const override delegate->SetDevice(); auto context = CreateImpellerContext(); + auto aiks_context = + std::make_shared(context, impeller::TypographerContextSkia::Make()); EXPECT_FALSE(context->GetCaptureManager()->CaptureScopeActive()); std::unique_ptr surface = - std::make_unique(delegate.get(), context); + std::make_unique(delegate.get(), aiks_context); auto frame_1 = surface->AcquireFrame(SkISize::Make(100, 100)); frame_1->set_submit_info({.frame_boundary = false}); EXPECT_TRUE(context->GetCaptureManager()->CaptureScopeActive()); std::unique_ptr surface_2 = - std::make_unique(delegate.get(), context); + std::make_unique(delegate.get(), aiks_context); auto frame_2 = surface->AcquireFrame(SkISize::Make(100, 100)); frame_2->set_submit_info({.frame_boundary = true}); From 625f597c0e26a0954b81d181435f92c25c53abe0 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 24 Sep 2024 10:39:09 -0700 Subject: [PATCH 3/5] ++ --- .../gpu/gpu_surface_metal_impeller_unittests.mm | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/shell/gpu/gpu_surface_metal_impeller_unittests.mm b/shell/gpu/gpu_surface_metal_impeller_unittests.mm index b0afbb6a1729d..4c37c83c027d7 100644 --- a/shell/gpu/gpu_surface_metal_impeller_unittests.mm +++ b/shell/gpu/gpu_surface_metal_impeller_unittests.mm @@ -66,15 +66,16 @@ GPUCAMetalLayerHandle GetCAMetalLayer(const SkISize& frame_info) const override TEST(GPUSurfaceMetalImpeller, CanCreateValidSurface) { auto delegate = std::make_shared(); - auto surface = std::make_shared(delegate.get(), CreateImpellerContext()); + auto surface = std::make_shared( + delegate.get(), std::make_shared(CreateImpellerContext(), nullptr)); ASSERT_TRUE(surface->IsValid()); } TEST(GPUSurfaceMetalImpeller, AcquireFrameFromCAMetalLayerNullChecksDrawable) { auto delegate = std::make_shared(); - std::shared_ptr surface = - std::make_shared(delegate.get(), CreateImpellerContext()); + std::shared_ptr surface = std::make_shared( + delegate.get(), std::make_shared(CreateImpellerContext(), nullptr)); ASSERT_TRUE(surface->IsValid()); @@ -85,8 +86,8 @@ GPUCAMetalLayerHandle GetCAMetalLayer(const SkISize& frame_info) const override TEST(GPUSurfaceMetalImpeller, AcquireFrameFromCAMetalLayerDoesNotRetainThis) { auto delegate = std::make_shared(); delegate->SetDevice(); - std::unique_ptr surface = - std::make_unique(delegate.get(), CreateImpellerContext()); + std::unique_ptr surface = std::make_unique( + delegate.get(), std::make_shared(CreateImpellerContext(), nullptr)); ASSERT_TRUE(surface->IsValid()); @@ -105,8 +106,7 @@ GPUCAMetalLayerHandle GetCAMetalLayer(const SkISize& frame_info) const override auto context = CreateImpellerContext(); std::unique_ptr surface = std::make_unique( - delegate.get(), - std::make_shared(context, impeller::TypographerContextSkia::Make())); + delegate.get(), std::make_shared(context, nullptr)); ASSERT_TRUE(surface->IsValid()); @@ -133,8 +133,7 @@ GPUCAMetalLayerHandle GetCAMetalLayer(const SkISize& frame_info) const override delegate->SetDevice(); auto context = CreateImpellerContext(); - auto aiks_context = - std::make_shared(context, impeller::TypographerContextSkia::Make()); + auto aiks_context = std::make_shared(context, nullptr); EXPECT_FALSE(context->GetCaptureManager()->CaptureScopeActive()); From 20b0a308d2d85f40dc5e78122253dbe01c055b56 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 24 Sep 2024 10:52:59 -0700 Subject: [PATCH 4/5] ++ --- shell/common/shell_test_platform_view_metal.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/shell/common/shell_test_platform_view_metal.mm b/shell/common/shell_test_platform_view_metal.mm index 41322490f8252..94345527bcc31 100644 --- a/shell/common/shell_test_platform_view_metal.mm +++ b/shell/common/shell_test_platform_view_metal.mm @@ -113,8 +113,9 @@ GPUMTLTextureInfo offscreen_texture_info() const { // |PlatformView| std::unique_ptr ShellTestPlatformViewMetal::CreateRenderingSurface() { if (GetSettings().enable_impeller) { - return std::make_unique(this, - [metal_context_->impeller_context() context]); + auto context = [metal_context_->impeller_context() context]; + return std::make_unique( + this, std::make_shared(context, nullptr)); } return std::make_unique(this, [metal_context_->context() mainContext]); } From a64ae0f545f1a87f7e0efc31b68b9dc4d70999ce Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 24 Sep 2024 12:25:38 -0700 Subject: [PATCH 5/5] Update ios_context_metal_impeller.mm --- shell/platform/darwin/ios/ios_context_metal_impeller.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/platform/darwin/ios/ios_context_metal_impeller.mm b/shell/platform/darwin/ios/ios_context_metal_impeller.mm index 7e338b7430745..b3846b1988740 100644 --- a/shell/platform/darwin/ios/ios_context_metal_impeller.mm +++ b/shell/platform/darwin/ios/ios_context_metal_impeller.mm @@ -17,9 +17,10 @@ const std::shared_ptr& is_gpu_disabled_sync_switch) : darwin_context_metal_impeller_(fml::scoped_nsobject{ [[FlutterDarwinContextMetalImpeller alloc] init:is_gpu_disabled_sync_switch]}) { - if (darwin_context_metal_impeller_.get().context) + if (darwin_context_metal_impeller_.get().context) { aiks_context_ = std::make_shared( darwin_context_metal_impeller_.get().context, impeller::TypographerContextSkia::Make()); + } } IOSContextMetalImpeller::~IOSContextMetalImpeller() = default;