Made sure not to turn on wide gamut support without impeller. (flutter/engine#41460)

fixes https://github.com/flutter/flutter/issues/125430

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
gaaclarke 2023-04-25 15:27:21 -07:00 committed by GitHub
parent c43684dcc4
commit c2ebd9ebc2
6 changed files with 48 additions and 15 deletions

View File

@ -439,4 +439,8 @@ flutter::Settings FLTDefaultSettingsForBundle(NSBundle* bundle, NSProcessInfo* p
return _settings.enable_wide_gamut;
}
- (BOOL)isImpellerEnabled {
return _settings.enable_impeller;
}
@end

View File

@ -20,6 +20,7 @@ flutter::Settings FLTDefaultSettingsForBundle(NSBundle* _Nullable bundle = nil,
@interface FlutterDartProject ()
@property(nonatomic, readonly) BOOL isWideGamutEnabled;
@property(nonatomic, readonly) BOOL isImpellerEnabled;
/**
* This is currently used for *only for tests* to override settings.

View File

@ -1402,6 +1402,10 @@ static void SetEntryPoint(flutter::Settings* settings, NSString* entrypoint, NSS
return _dartProject.get();
}
- (BOOL)isUsingImpeller {
return self.project.isImpellerEnabled;
}
@end
@implementation FlutterEngineRegistrar {

View File

@ -17,6 +17,8 @@
@protocol FlutterViewEngineDelegate <NSObject>
@property(nonatomic, readonly) BOOL isUsingImpeller;
- (flutter::Rasterizer::Screenshot)takeScreenshot:(flutter::Rasterizer::ScreenshotType)type
asBase64Encoded:(BOOL)base64Encode;

View File

@ -16,19 +16,6 @@
#import "flutter/shell/platform/darwin/ios/ios_surface_software.h"
#include "third_party/skia/include/utils/mac/SkCGUtils.h"
static BOOL IsWideGamutSupported() {
#if TARGET_OS_SIMULATOR
// As of Xcode 14.1, the wide gamut surface pixel formats are not supported by
// the simulator.
return NO;
#else
// This predicates the decision on the capabilities of the iOS device's
// display. This means external displays will not support wide gamut if the
// device's display doesn't support it. It practice that should be never.
return UIScreen.mainScreen.traitCollection.displayGamut != UIDisplayGamutSRGB;
#endif
}
@implementation FlutterView {
id<FlutterViewEngineDelegate> _delegate;
BOOL _isWideGamutEnabled;
@ -49,6 +36,30 @@ static BOOL IsWideGamutSupported() {
return nil;
}
- (UIScreen*)screen {
if (@available(iOS 13.0, *)) {
return self.window.windowScene.screen;
}
return UIScreen.mainScreen;
}
- (BOOL)isWideGamutSupported {
#if TARGET_OS_SIMULATOR
// As of Xcode 14.1, the wide gamut surface pixel formats are not supported by
// the simulator.
return NO;
#endif
if (![_delegate isUsingImpeller]) {
return NO;
}
// This predicates the decision on the capabilities of the iOS device's
// display. This means external displays will not support wide gamut if the
// device's display doesn't support it. It practice that should be never.
return self.screen.traitCollection.displayGamut != UIDisplayGamutSRGB;
}
- (instancetype)initWithDelegate:(id<FlutterViewEngineDelegate>)delegate
opaque:(BOOL)opaque
enableWideGamut:(BOOL)isWideGamutEnabled {
@ -63,7 +74,7 @@ static BOOL IsWideGamutSupported() {
if (self) {
_delegate = delegate;
_isWideGamutEnabled = isWideGamutEnabled;
if (_isWideGamutEnabled && !IsWideGamutSupported()) {
if (_isWideGamutEnabled && self.isWideGamutSupported) {
FML_DLOG(WARNING) << "Rendering wide gamut colors is turned on but isn't "
"supported, downgrading the color gamut to sRGB.";
}
@ -92,7 +103,7 @@ static BOOL IsWideGamutSupported() {
layer.contentsScale = screenScale;
layer.rasterizationScale = screenScale;
layer.framebufferOnly = flutter::Settings::kSurfaceDataAccessible ? NO : YES;
if (_isWideGamutEnabled && IsWideGamutSupported()) {
if (_isWideGamutEnabled && self.isWideGamutSupported) {
CGColorSpaceRef srgb = CGColorSpaceCreateWithName(kCGColorSpaceExtendedSRGB);
layer.colorspace = srgb;
CFRelease(srgb);

View File

@ -9,6 +9,7 @@
@interface FakeDelegate : NSObject <FlutterViewEngineDelegate>
@property(nonatomic) BOOL callbackCalled;
@property(nonatomic, assign) BOOL isUsingImpeller;
@end
@implementation FakeDelegate {
@ -55,4 +56,14 @@
XCTAssertNotNil(view.backgroundColor);
}
- (void)testIgnoreWideColorWithoutImpeller {
FakeDelegate* delegate = [[FakeDelegate alloc] init];
delegate.isUsingImpeller = NO;
FlutterView* view = [[FlutterView alloc] initWithDelegate:delegate opaque:NO enableWideGamut:YES];
[view layoutSubviews];
XCTAssertTrue([view.layer isKindOfClass:NSClassFromString(@"CAMetalLayer")]);
CAMetalLayer* layer = (CAMetalLayer*)view.layer;
XCTAssertEqual(layer.pixelFormat, MTLPixelFormatBGRA8Unorm);
}
@end