diff --git a/engine/src/flutter/shell/common/shell_test_platform_view_metal.mm b/engine/src/flutter/shell/common/shell_test_platform_view_metal.mm index 41322490f8..94345527bc 100644 --- a/engine/src/flutter/shell/common/shell_test_platform_view_metal.mm +++ b/engine/src/flutter/shell/common/shell_test_platform_view_metal.mm @@ -113,8 +113,9 @@ PointerDataDispatcherMaker ShellTestPlatformViewMetal::GetDispatcherMaker() { // |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]); } diff --git a/engine/src/flutter/shell/gpu/gpu_surface_metal_impeller.h b/engine/src/flutter/shell/gpu/gpu_surface_metal_impeller.h index 893390090a..02407fd639 100644 --- a/engine/src/flutter/shell/gpu/gpu_surface_metal_impeller.h +++ b/engine/src/flutter/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/engine/src/flutter/shell/gpu/gpu_surface_metal_impeller.mm b/engine/src/flutter/shell/gpu/gpu_surface_metal_impeller.mm index ff765afc21..79b6c20a3e 100644 --- a/engine/src/flutter/shell/gpu/gpu_surface_metal_impeller.mm +++ b/engine/src/flutter/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 @@ static_assert(!__has_feature(objc_arc), "ARC must be disabled."); 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 = @@ -167,12 +167,14 @@ std::unique_ptr GPUSurfaceMetalImpeller::AcquireFrameFromCAMetalLa impeller::IRect cull_rect = surface->coverage(); SkIRect sk_cull_rect = SkIRect::MakeWH(cull_rect.GetWidth(), cull_rect.GetHeight()); surface->SetFrameBoundary(surface_frame.submit_info().frame_boundary); + + const bool reset_host_buffer = surface_frame.submit_info().frame_boundary; auto render_result = impeller::RenderToOnscreen(aiks_context->GetContentContext(), // surface->GetTargetRenderPassDescriptor(), // display_list, // sk_cull_rect, // - /*reset_host_buffer=*/true // + /*reset_host_buffer=*/reset_host_buffer // ); if (!render_result) { return false; diff --git a/engine/src/flutter/shell/gpu/gpu_surface_metal_impeller_unittests.mm b/engine/src/flutter/shell/gpu/gpu_surface_metal_impeller_unittests.mm index 16632279eb..4c37c83c02 100644 --- a/engine/src/flutter/shell/gpu/gpu_surface_metal_impeller_unittests.mm +++ b/engine/src/flutter/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 { @@ -64,15 +66,16 @@ TEST(GPUSurfaceMetalImpeller, InvalidImpellerContextCreatesCausesSurfaceToBeInva 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()); @@ -83,8 +86,8 @@ TEST(GPUSurfaceMetalImpeller, AcquireFrameFromCAMetalLayerNullChecksDrawable) { 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()); @@ -97,14 +100,13 @@ TEST(GPUSurfaceMetalImpeller, AcquireFrameFromCAMetalLayerDoesNotRetainThis) { 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, nullptr)); ASSERT_TRUE(surface->IsValid()); @@ -116,13 +118,13 @@ TEST(GPUSurfaceMetalImpeller, DoesNotResetHostBufferBasedOnFrameBoundary) { 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,19 @@ TEST(GPUSurfaceMetalImpeller, CreatesImpellerCaptureScope) { delegate->SetDevice(); auto context = CreateImpellerContext(); + auto aiks_context = std::make_shared(context, nullptr); 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}); diff --git a/engine/src/flutter/shell/platform/darwin/ios/ios_context.h b/engine/src/flutter/shell/platform/darwin/ios/ios_context.h index ef9dcca778..e2c789d0b1 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/ios_context.h +++ b/engine/src/flutter/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/engine/src/flutter/shell/platform/darwin/ios/ios_context.mm b/engine/src/flutter/shell/platform/darwin/ios/ios_context.mm index ac6db41aa5..762847e8af 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/ios_context.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/ios_context.mm @@ -63,4 +63,8 @@ std::shared_ptr IOSContext::GetImpellerContext() const { return nullptr; } +std::shared_ptr IOSContext::GetAiksContext() const { + return nullptr; +} + } // namespace flutter diff --git a/engine/src/flutter/shell/platform/darwin/ios/ios_context_metal_impeller.h b/engine/src/flutter/shell/platform/darwin/ios/ios_context_metal_impeller.h index 5e2ed7a32d..b5293da6e5 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/ios_context_metal_impeller.h +++ b/engine/src/flutter/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/engine/src/flutter/shell/platform/darwin/ios/ios_context_metal_impeller.mm b/engine/src/flutter/shell/platform/darwin/ios/ios_context_metal_impeller.mm index 92a59a8326..b3846b1988 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/ios_context_metal_impeller.mm +++ b/engine/src/flutter/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,12 @@ namespace flutter { 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 +47,11 @@ std::shared_ptr IOSContextMetalImpeller::GetImpellerContext() 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/engine/src/flutter/shell/platform/darwin/ios/ios_surface.h b/engine/src/flutter/shell/platform/darwin/ios/ios_surface.h index 78394f2578..96970a465b 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/ios_surface.h +++ b/engine/src/flutter/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/engine/src/flutter/shell/platform/darwin/ios/ios_surface_metal_impeller.h b/engine/src/flutter/shell/platform/darwin/ios/ios_surface_metal_impeller.h index 888f393535..86c5171caa 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/ios_surface_metal_impeller.h +++ b/engine/src/flutter/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/engine/src/flutter/shell/platform/darwin/ios/ios_surface_metal_impeller.mm b/engine/src/flutter/shell/platform/darwin/ios/ios_surface_metal_impeller.mm index 8d1a75d6f1..89b7e72910 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/ios_surface_metal_impeller.mm +++ b/engine/src/flutter/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 @@ IOSSurfaceMetalImpeller::IOSSurfaceMetalImpeller(const fml::scoped_nsobjectGetImpellerContext() : 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 @@ void IOSSurfaceMetalImpeller::UpdateStorageSizeIfNecessary() { 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/engine/src/flutter/shell/platform/embedder/embedder_surface_metal_impeller.h b/engine/src/flutter/shell/platform/embedder/embedder_surface_metal_impeller.h index 109870aa6f..3589f7facd 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_surface_metal_impeller.h +++ b/engine/src/flutter/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/engine/src/flutter/shell/platform/embedder/embedder_surface_metal_impeller.mm b/engine/src/flutter/shell/platform/embedder/embedder_surface_metal_impeller.mm index d1d1265dd9..6365388861 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_surface_metal_impeller.mm +++ b/engine/src/flutter/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 @@ std::unique_ptr EmbedderSurfaceMetalImpeller::CreateGPUSurface() 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;