7 #include "flutter/common/settings.h"
8 #include "flutter/common/task_runners.h"
9 #include "flutter/flow/layers/layer_tree.h"
10 #include "flutter/fml/platform/darwin/cf_utils.h"
11 #include "flutter/fml/synchronization/waitable_event.h"
12 #include "flutter/fml/trace_event.h"
13 #include "flutter/shell/common/platform_view.h"
14 #include "flutter/shell/common/rasterizer.h"
17 #include "third_party/skia/include/utils/mac/SkCGUtils.h"
20 id<FlutterViewEngineDelegate> _delegate;
24 - (instancetype)init {
25 NSAssert(NO,
@"FlutterView must initWithDelegate");
30 NSAssert(NO,
@"FlutterView must initWithDelegate");
35 NSAssert(NO,
@"FlutterView must initWithDelegate");
40 if (@available(iOS 13.0, *)) {
41 return self.window.windowScene.screen;
43 return UIScreen.mainScreen;
46 - (BOOL)isWideGamutSupported {
47 if (![_delegate isUsingImpeller]) {
51 FML_DCHECK(
self.screen);
56 return self.screen.traitCollection.displayGamut != UIDisplayGamutSRGB;
61 enableWideGamut:(BOOL)isWideGamutEnabled {
62 if (delegate == nil) {
63 NSLog(
@"FlutterView delegate was nil.");
68 self = [
super initWithFrame:CGRectNull];
73 self.layer.opaque = opaque;
79 self.backgroundColor = UIColor.clearColor;
85 static void PrintWideGamutWarningOnce() {
86 static BOOL did_print = NO;
90 FML_DLOG(WARNING) <<
"Rendering wide gamut colors is turned on but isn't "
91 "supported, downgrading the color gamut to sRGB.";
95 - (void)layoutSubviews {
96 if ([
self.layer isKindOfClass:NSClassFromString(
@"CAMetalLayer")]) {
99 #pragma clang diagnostic push
100 #pragma clang diagnostic ignored "-Wunguarded-availability-new"
101 CAMetalLayer* layer = (CAMetalLayer*)
self.layer;
102 #pragma clang diagnostic pop
103 CGFloat screenScale = [UIScreen mainScreen].scale;
104 layer.allowsGroupOpacity = YES;
105 layer.contentsScale = screenScale;
106 layer.rasterizationScale = screenScale;
107 layer.framebufferOnly = flutter::Settings::kSurfaceDataAccessible ? NO : YES;
108 BOOL isWideGamutSupported =
self.isWideGamutSupported;
110 CGColorSpaceRef srgb = CGColorSpaceCreateWithName(kCGColorSpaceExtendedSRGB);
111 layer.colorspace = srgb;
117 layer.pixelFormat = MTLPixelFormatRGBA16Float;
119 PrintWideGamutWarningOnce();
123 [
super layoutSubviews];
128 + (BOOL)forceSoftwareRendering {
132 + (void)setForceSoftwareRendering:(BOOL)forceSoftwareRendering {
136 + (Class)layerClass {
141 - (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context {
142 TRACE_EVENT0(
"flutter",
"SnapshotFlutterView");
144 if (layer !=
self.layer || context ==
nullptr) {
148 auto screenshot = [_delegate takeScreenshot:flutter::Rasterizer::ScreenshotType::UncompressedImage
151 if (!screenshot.data || screenshot.data->isEmpty() || screenshot.frame_size.isEmpty()) {
155 NSData* data = [NSData dataWithBytes:const_cast<void*>(screenshot.data->data())
156 length:screenshot.data->size()];
158 fml::CFRef<CGDataProviderRef> image_data_provider(
159 CGDataProviderCreateWithCFData(
reinterpret_cast<CFDataRef
>(data)));
161 fml::CFRef<CGColorSpaceRef> colorspace(CGColorSpaceCreateDeviceRGB());
163 fml::CFRef<CGImageRef> image(CGImageCreate(
164 screenshot.frame_size.width(),
165 screenshot.frame_size.height(),
168 4 * screenshot.frame_size.width(),
170 static_cast<CGBitmapInfo
>(
171 static_cast<uint32_t
>(kCGImageAlphaPremultipliedLast) |
172 static_cast<uint32_t
>(kCGBitmapByteOrder32Big)),
176 kCGRenderingIntentDefault
179 const CGRect frame_rect =
180 CGRectMake(0.0, 0.0, screenshot.frame_size.width(), screenshot.frame_size.height());
182 CGContextSaveGState(context);
183 CGContextTranslateCTM(context, 0.0, CGBitmapContextGetHeight(context));
184 CGContextScaleCTM(context, 1.0, -1.0);
185 CGContextDrawImage(context, frame_rect, image);
186 CGContextRestoreGState(context);
189 - (BOOL)isAccessibilityElement {
198 [_delegate flutterViewAccessibilityDidCall];