5#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h"
11#include "flutter/fml/logging.h"
12#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterSurface.h"
50 [NSColor yellowColor],
52 [NSColor magentaColor],
54 [NSColor purpleColor],
55 [NSColor orangeColor],
58 return colors[layer % colors.count];
68 const std::vector<FlutterRect>& paintRegion) {
70 while (layer.sublayers.count > paintRegion.size()) {
71 [layer.sublayers.lastObject removeFromSuperlayer];
74 while (layer.sublayers.count < paintRegion.size()) {
75 CALayer* newLayer = [CALayer layer];
76 [layer addSublayer:newLayer];
79 for (
size_t i = 0;
i < paintRegion.size();
i++) {
80 CALayer* subLayer = [layer.sublayers objectAtIndex:i];
81 const auto&
rect = paintRegion[i];
85 double width = surfaceSize.width;
86 double height = surfaceSize.height;
88 subLayer.contentsRect =
92 if (borderColor != nil) {
94 subLayer.borderColor = borderColor.CGColor;
95 subLayer.borderWidth = 1.0;
104- (instancetype)initWithDevice:(
id<MTLDevice>)device
105 commandQueue:(
id<MTLCommandQueue>)commandQueue
106 layer:(CALayer*)containingLayer
116 _layers = [NSMutableArray array];
144 [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FLTEnableSurfaceDebugInfo"];
149 return [_enableSurfaceDebugInfo boolValue];
156 [_backBufferCache returnSurfaces:_frontSurfaces];
159 [_frontSurfaces removeAllObjects];
161 [_frontSurfaces addObject:info.surface];
166 [_layers.lastObject removeFromSuperlayer];
167 [_layers removeLastObject];
170 CALayer* layer = [CALayer layer];
171 [_containingLayer addSublayer:layer];
172 [_layers addObject:layer];
178 for (
size_t i = 0;
i < surfaces.count; ++
i) {
185 layer.contents = (__bridge
id)
info.surface.ioSurface;
187 layer.frame = CGRectZero;
192 layer.zPosition =
info.zIndex;
198 [_containingLayer addSublayer:_infoLayer];
200 _infoLayer.foregroundColor = [NSColor yellowColor].CGColor;
201 _infoLayer.frame = CGRectMake(15, 15, 300, 100);
205 _infoLayer.string = [NSString stringWithFormat:@"Surface count: %li", _layers.count];
210 CGSize
size = CGSizeZero;
219 atTime:(CFTimeInterval)presentationTime
220 notify:(dispatch_block_t)notify {
221 id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
222 [commandBuffer commit];
223 [commandBuffer waitUntilScheduled];
225 dispatch_block_t presentBlock = ^{
228 [_delegate onPresent:size
230 _lastPresentationTime = presentationTime;
231 [
self commit:surfaces];
238 if (presentationTime > 0) {
251 CFTimeInterval now = CACurrentMediaTime();
252 if (now < minPresentationTime) {
253 NSTimer* timer = [NSTimer timerWithTimeInterval:minPresentationTime - now
255 block:^(NSTimer* timer) {
258 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
284- (instancetype)
init {
286 self->_surfaces = [[NSMutableArray alloc] init];
287 self->_surfaceAge = [NSMapTable weakToStrongObjectsMapTable];
293 NSNumber* age = [_surfaceAge objectForKey:surface];
294 return age != nil ? age.intValue : 0;
298 [_surfaceAge setObject:@(age) forKey:surface];
302 @
synchronized(
self) {
305 [_surfaces removeAllObjects];
315 (res == nil || [
self ageForSurface:res] > [
self ageForSurface:
surface])) {
320 [_surfaces removeObject:res];
326- (void)returnSurfaces:(nonnull NSArray<
FlutterSurface*>*)returnedSurfaces {
327 @
synchronized(
self) {
329 [
self setAge:0 forSurface:surface];
332 [
self setAge:[
self ageForSurface:surface] + 1 forSurface:surface];
335 [_surfaces addObjectsFromArray:returnedSurfaces];
342 [_surfaces filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(FlutterSurface* surface,
343 NSDictionary* bindings) {
344 return [
self ageForSurface:surface] < kSurfaceEvictionAge;
349 [
self performSelectorOnMainThread:@selector(reschedule) withObject:nil waitUntilDone:NO];
353 @
synchronized(
self) {
359 @
synchronized(
self) {
360 [_surfaces removeAllObjects];
365 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onIdle) object:nil];
366 [
self performSelector:@selector(onIdle) withObject:nil afterDelay:kIdleDelay];
370 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onIdle) object:nil];
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static void UpdateContentSubLayers(CALayer *layer, IOSurfaceRef surface, CGFloat scale, CGSize surfaceSize, NSColor *borderColor, const std::vector< FlutterRect > &paintRegion)
static NSColor * GetBorderColorForLayer(int layer)
static const double kIdleDelay
static const int kSurfaceEvictionAge
NSArray< CALayer * > * layers
FlutterBackBufferCache * backBufferCache
NSArray< FlutterSurface * > * frontSurfaces
#define FML_DCHECK(condition)
static float max(float r, float g, float b)
NSMutableArray< FlutterSurface * > * _surfaces
NSMapTable< FlutterSurface *, NSNumber * > * _surfaceAge
static CGSize GetRequiredFrameSize(NSArray< FlutterSurfacePresentInfo * > *surfaces)
CALayer * _containingLayer
id< MTLCommandQueue > _commandQueue
NSMutableArray< FlutterSurface * > * _frontSurfaces
BOOL enableSurfaceDebugInfo()
__weak id< FlutterSurfaceManagerDelegate > _delegate
FlutterBackBufferCache * _backBufferCache
CFTimeInterval _lastPresentationTime
NSMutableArray< CALayer * > * _layers
NSNumber * _enableSurfaceDebugInfo
sk_sp< SkBlender > blender SkRect rect
PODArray< SkColor > colors
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size