iOS: add null check on create impeller context (flutter/engine#56952)

In the case where `CreateImpellerContext` encounters an error while creating an `impeller::ContextMTL`, we logged an error, returned nullptr, then immediately dereferenced the null pointer. Now, rather than crash due to a segfault, we now intentionally abort with an appropriate error message.

This adds checks in the `FlutterDarwinContextMetalImpeller` initialiser that aborts with an appropriate error message if impeller context creation fails, Metal device creation fails, or texture cache creation fails.

Rather than bailing out and returning nil from the initialiser to pass the buck to the caller, we terminate since without a graphics context, the app won't be able to render anything to begin with.

Issue: https://github.com/flutter/flutter/issues/157489
Issue: [b/378790930](http://b/378790930)

No test changes since this just changes an accidental crash to an intentional crash.

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
Chris Bracken 2024-12-06 11:32:25 -08:00 committed by GitHub
parent 87af85b89c
commit f5db949a32

View File

@ -25,14 +25,8 @@ static std::shared_ptr<impeller::ContextMTL> CreateImpellerContext(
std::make_shared<fml::NonOwnedMapping>(impeller_framebuffer_blend_shaders_data,
impeller_framebuffer_blend_shaders_length),
};
auto context = impeller::ContextMTL::Create(shader_mappings, is_gpu_disabled_sync_switch,
"Impeller Library");
if (!context) {
FML_LOG(ERROR) << "Could not create Metal Impeller Context.";
return nullptr;
}
return context;
return impeller::ContextMTL::Create(shader_mappings, is_gpu_disabled_sync_switch,
"Impeller Library");
}
@implementation FlutterDarwinContextMetalImpeller
@ -41,11 +35,9 @@ static std::shared_ptr<impeller::ContextMTL> CreateImpellerContext(
self = [super init];
if (self != nil) {
_context = CreateImpellerContext(is_gpu_disabled_sync_switch);
FML_CHECK(_context) << "Could not create Metal Impeller Context.";
id<MTLDevice> device = _context->GetMTLDevice();
if (!device) {
FML_DLOG(ERROR) << "Could not acquire Metal device.";
return nil;
}
FML_CHECK(device) << "Could not acquire Metal device.";
CVMetalTextureCacheRef textureCache;
CVReturn cvReturn = CVMetalTextureCacheCreate(kCFAllocatorDefault, // allocator
@ -55,10 +47,7 @@ static std::shared_ptr<impeller::ContextMTL> CreateImpellerContext(
&textureCache // [out] cache
);
if (cvReturn != kCVReturnSuccess) {
FML_DLOG(ERROR) << "Could not create Metal texture cache.";
return nil;
}
FML_CHECK(cvReturn == kCVReturnSuccess) << "Could not acquire Metal device.";
_textureCache.Reset(textureCache);
}
return self;