diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngineTest_mrc.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngineTest_mrc.mm index cc2f46f9dd275..f5595bffb99d3 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngineTest_mrc.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngineTest_mrc.mm @@ -30,8 +30,17 @@ - (void)testSpawnsShareGpuContext { XCTAssertNotNil(spawn); XCTAssertTrue([engine iosPlatformView] != nullptr); XCTAssertTrue([spawn iosPlatformView] != nullptr); - XCTAssertEqual([engine iosPlatformView]->GetIosContext(), - [spawn iosPlatformView]->GetIosContext()); + std::shared_ptr engine_context = [engine iosPlatformView]->GetIosContext(); + std::shared_ptr spawn_context = [spawn iosPlatformView]->GetIosContext(); + XCTAssertEqual(engine_context, spawn_context); + // If this assert fails it means we may be using the software or OpenGL + // renderer when we were expecting Metal. For software rendering, this is + // expected to be nullptr. For OpenGL, implementing this is an outstanding + // change see https://github.com/flutter/flutter/issues/73744. + XCTAssertTrue(engine_context->GetMainContext() != nullptr); + XCTAssertEqual(engine_context->GetMainContext(), spawn_context->GetMainContext()); + [engine release]; + [spawn release]; } @end diff --git a/shell/platform/darwin/ios/ios_context.h b/shell/platform/darwin/ios/ios_context.h index 6b2bf5e766c5b..c08b6b9c729d3 100644 --- a/shell/platform/darwin/ios/ios_context.h +++ b/shell/platform/darwin/ios/ios_context.h @@ -106,6 +106,20 @@ class IOSContext { int64_t texture_id, fml::scoped_nsobject> texture) = 0; + //---------------------------------------------------------------------------- + /// @brief Accessor for the Skia context associated with IOSSurfaces and + /// the raster thread. + /// @details There can be any number of resource contexts but this is the + /// one context that will be used by surfaces to draw to the + /// screen from the raster thread. + /// @returns `nullptr` on failure. + /// @attention The software context doesn't have a Skia context, so this + /// value will be nullptr. + /// @see For contexts which are used for offscreen work like loading + /// textures see IOSContext::CreateResourceContext. + /// + virtual sk_sp GetMainContext() const = 0; + protected: IOSContext(); diff --git a/shell/platform/darwin/ios/ios_context_gl.h b/shell/platform/darwin/ios/ios_context_gl.h index 69260e1903efa..823f13a14c59a 100644 --- a/shell/platform/darwin/ios/ios_context_gl.h +++ b/shell/platform/darwin/ios/ios_context_gl.h @@ -32,6 +32,9 @@ class IOSContextGL final : public IOSContext { // |IOSContext| sk_sp CreateResourceContext() override; + // |IOSContext| + sk_sp GetMainContext() const override; + // |IOSContext| std::unique_ptr MakeCurrent() override; diff --git a/shell/platform/darwin/ios/ios_context_gl.mm b/shell/platform/darwin/ios/ios_context_gl.mm index 4de8f11935ffa..d803174cba2ca 100644 --- a/shell/platform/darwin/ios/ios_context_gl.mm +++ b/shell/platform/darwin/ios/ios_context_gl.mm @@ -43,6 +43,16 @@ GrBackend::kOpenGL_GrBackend, GPUSurfaceGLDelegate::GetDefaultPlatformGLInterface()); } +// |IOSContext| +sk_sp IOSContextGL::GetMainContext() const { + /// TODO(73744): Currently the GPUSurfaceGL creates the main context for + /// OpenGL. With Metal the IOSContextMetal creates the main context and is + /// shared across surfaces. We should refactor the OpenGL Context/Surfaces to + /// behave like the Metal equivalents. Until then engines in the same group + /// will have a heavier memory cost if they are using OpenGL. + return nullptr; +} + // |IOSContext| std::unique_ptr IOSContextGL::MakeCurrent() { return std::make_unique( diff --git a/shell/platform/darwin/ios/ios_context_metal.h b/shell/platform/darwin/ios/ios_context_metal.h index 35fecb0507c2e..ebda072bea0e9 100644 --- a/shell/platform/darwin/ios/ios_context_metal.h +++ b/shell/platform/darwin/ios/ios_context_metal.h @@ -24,7 +24,8 @@ class IOSContextMetal final : public IOSContext { fml::scoped_nsobject GetDarwinContext() const; - sk_sp GetMainContext() const; + // |IOSContext| + sk_sp GetMainContext() const override; sk_sp GetResourceContext() const; diff --git a/shell/platform/darwin/ios/ios_context_software.h b/shell/platform/darwin/ios/ios_context_software.h index 4407be6033cc7..3731bd3ed6ed5 100644 --- a/shell/platform/darwin/ios/ios_context_software.h +++ b/shell/platform/darwin/ios/ios_context_software.h @@ -20,6 +20,9 @@ class IOSContextSoftware final : public IOSContext { // |IOSContext| sk_sp CreateResourceContext() override; + // |IOSContext| + sk_sp GetMainContext() const override; + // |IOSContext| std::unique_ptr MakeCurrent() override; diff --git a/shell/platform/darwin/ios/ios_context_software.mm b/shell/platform/darwin/ios/ios_context_software.mm index 261fdc44a450a..7005b5046406d 100644 --- a/shell/platform/darwin/ios/ios_context_software.mm +++ b/shell/platform/darwin/ios/ios_context_software.mm @@ -16,6 +16,11 @@ return nullptr; } +// |IOSContext| +sk_sp IOSContextSoftware::GetMainContext() const { + return nullptr; +} + // |IOSContext| std::unique_ptr IOSContextSoftware::MakeCurrent() { // This only makes sense for context that need to be bound to a specific thread.