Flutter Engine
The Flutter Engine
Instance Methods | Class Methods | Protected Attributes | List of all members
FlutterSurfaceManager Class Reference

#import <FlutterSurfaceManager.h>

Inheritance diagram for FlutterSurfaceManager:

Instance Methods

(nullable instancetype) - initWithDevice:commandQueue:layer:delegate:
 
(nonnull FlutterSurface *) - surfaceForSize:
 
(void) - presentSurfaces:atTime:notify:
 
(instancetype) - initWithDevice:commandQueue:layer:delegate: [implementation]
 
(FlutterBackBufferCache *) - backBufferCache [implementation]
 
(NSArray *) - frontSurfaces [implementation]
 
(NSArray *) - layers [implementation]
 
(BOOL- enableSurfaceDebugInfo [implementation]
 
(void) - commit: [implementation]
 
(void) - presentSurfaces:atTime:notify: [implementation]
 

Class Methods

(static CGSize) + GetRequiredFrameSize [implementation]
 

Protected Attributes

id< MTLDevice > _device
 
id< MTLCommandQueue > _commandQueue
 
CALayer * _containingLayer
 
__weak id< FlutterSurfaceManagerDelegate_delegate
 
FlutterBackBufferCache_backBufferCache
 
NSMutableArray< FlutterSurface * > * _frontSurfaces
 
NSMutableArray< CALayer * > * _layers
 
NSNumber * _enableSurfaceDebugInfo
 
CATextLayer * _infoLayer
 
CFTimeInterval _lastPresentationTime
 

Detailed Description

FlutterSurfaceManager is responsible for providing and presenting Core Animation render surfaces and managing sublayers.

Owned by FlutterView.

Definition at line 44 of file FlutterSurfaceManager.h.

Method Documentation

◆ backBufferCache

- (FlutterBackBufferCache *) backBufferCache
implementation

Provided by category FlutterSurfaceManager(Private).

Definition at line 38 of file FlutterSurfaceManager.mm.

121 {
122 return _backBufferCache;
123}
FlutterBackBufferCache * _backBufferCache

◆ commit:

- (void) commit: (NSArray< FlutterSurfacePresentInfo * > *)  surfaces
implementation

Updates underlying CALayers with the contents of the surfaces to present.

Definition at line 38 of file FlutterSurfaceManager.mm.

152 :(NSArray<FlutterSurfacePresentInfo*>*)surfaces {
153 FML_DCHECK([NSThread isMainThread]);
154
155 // Release all unused back buffer surfaces and replace them with front surfaces.
156 [_backBufferCache returnSurfaces:_frontSurfaces];
157
158 // Front surfaces will be replaced by currently presented surfaces.
159 [_frontSurfaces removeAllObjects];
160 for (FlutterSurfacePresentInfo* info in surfaces) {
161 [_frontSurfaces addObject:info.surface];
162 }
163
164 // Add or remove layers to match the count of surfaces to present.
165 while (_layers.count > _frontSurfaces.count) {
166 [_layers.lastObject removeFromSuperlayer];
167 [_layers removeLastObject];
168 }
169 while (_layers.count < _frontSurfaces.count) {
170 CALayer* layer = [CALayer layer];
171 [_containingLayer addSublayer:layer];
172 [_layers addObject:layer];
173 }
174
175 bool enableSurfaceDebugInfo = self.enableSurfaceDebugInfo;
176
177 // Update contents of surfaces.
178 for (size_t i = 0; i < surfaces.count; ++i) {
179 FlutterSurfacePresentInfo* info = surfaces[i];
180 CALayer* layer = _layers[i];
181 CGFloat scale = _containingLayer.contentsScale;
182 if (i == 0) {
183 layer.frame = CGRectMake(info.offset.x / scale, info.offset.y / scale,
184 info.surface.size.width / scale, info.surface.size.height / scale);
185 layer.contents = (__bridge id)info.surface.ioSurface;
186 } else {
187 layer.frame = CGRectZero;
188 NSColor* borderColor = enableSurfaceDebugInfo ? GetBorderColorForLayer(i - 1) : nil;
189 UpdateContentSubLayers(layer, info.surface.ioSurface, scale, info.surface.size, borderColor,
190 info.paintRegion);
191 }
192 layer.zPosition = info.zIndex;
193 }
194
196 if (_infoLayer == nil) {
197 _infoLayer = [[CATextLayer alloc] init];
198 [_containingLayer addSublayer:_infoLayer];
199 _infoLayer.fontSize = 15;
200 _infoLayer.foregroundColor = [NSColor yellowColor].CGColor;
201 _infoLayer.frame = CGRectMake(15, 15, 300, 100);
202 _infoLayer.contentsScale = _containingLayer.contentsScale;
203 _infoLayer.zPosition = 100000;
204 }
205 _infoLayer.string = [NSString stringWithFormat:@"Surface count: %li", _layers.count];
206 }
207}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
static void UpdateContentSubLayers(CALayer *layer, IOSurfaceRef surface, CGFloat scale, CGSize surfaceSize, NSColor *borderColor, const std::vector< FlutterRect > &paintRegion)
static NSColor * GetBorderColorForLayer(int layer)
#define FML_DCHECK(condition)
Definition: logging.h:103
NSMutableArray< FlutterSurface * > * _frontSurfaces
NSMutableArray< CALayer * > * _layers
const Scalar scale
const uintptr_t id

◆ enableSurfaceDebugInfo

- (BOOL) enableSurfaceDebugInfo
implementation

Definition at line 38 of file FlutterSurfaceManager.mm.

141 {
142 if (_enableSurfaceDebugInfo == nil) {
144 [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FLTEnableSurfaceDebugInfo"];
145 if (_enableSurfaceDebugInfo == nil) {
147 }
148 }
149 return [_enableSurfaceDebugInfo boolValue];
150}

◆ frontSurfaces

- (NSArray *) frontSurfaces
implementation

Provided by category FlutterSurfaceManager(Private).

Definition at line 38 of file FlutterSurfaceManager.mm.

125 {
126 return _frontSurfaces;
127}

◆ GetRequiredFrameSize

+ (static CGSize) GetRequiredFrameSize (NSArray< FlutterSurfacePresentInfo * > *)  surfaces
implementation

Definition at line 209 of file FlutterSurfaceManager.mm.

209 {
210 CGSize size = CGSizeZero;
211 for (FlutterSurfacePresentInfo* info in surfaces) {
212 size = CGSizeMake(std::max(size.width, info.offset.x + info.surface.size.width),
213 std::max(size.height, info.offset.y + info.surface.size.height));
214 }
215 return size;
216}
static float max(float r, float g, float b)
Definition: hsl.cpp:49
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
Definition: switches.h:259

◆ initWithDevice:commandQueue:layer:delegate: [1/2]

- (instancetype) initWithDevice: (id<MTLDevice>)  device
commandQueue: (id<MTLCommandQueue>)  commandQueue
layer: (CALayer*)  containingLayer
delegate: (__weak id<FlutterSurfaceManagerDelegate>)  delegate 
implementation

Definition at line 38 of file FlutterSurfaceManager.mm.

104 :(id<MTLDevice>)device
105 commandQueue:(id<MTLCommandQueue>)commandQueue
106 layer:(CALayer*)containingLayer
107 delegate:(__weak id<FlutterSurfaceManagerDelegate>)delegate {
108 if (self = [super init]) {
109 _device = device;
110 _commandQueue = commandQueue;
111 _containingLayer = containingLayer;
112 _delegate = delegate;
113
115 _frontSurfaces = [NSMutableArray array];
116 _layers = [NSMutableArray array];
117 }
118 return self;
119}
VkDevice device
Definition: main.cc:53
id< MTLCommandQueue > _commandQueue
__weak id< FlutterSurfaceManagerDelegate > _delegate
static bool init()

◆ initWithDevice:commandQueue:layer:delegate: [2/2]

- (nullable instancetype) initWithDevice: (nonnull id< MTLDevice >)  device
commandQueue: (nonnull id< MTLCommandQueue >)  commandQueue
layer: (nonnull CALayer *)  containingLayer
delegate: (nonnull id< FlutterSurfaceManagerDelegate >)  delegate 

Initializes and returns a surface manager that renders to a child layer (referred to as the content layer) of the containing layer.

◆ layers

- (NSArray *) layers
implementation

Provided by category FlutterSurfaceManager(Private).

Definition at line 38 of file FlutterSurfaceManager.mm.

129 {
130 return _layers;
131}

◆ presentSurfaces:atTime:notify: [1/2]

- (void) presentSurfaces: (nonnull NSArray< FlutterSurfacePresentInfo * > *)  surfaces
atTime: (CFTimeInterval)  presentationTime
notify: (nullable dispatch_block_t)  notify 

Sets the provided surfaces as contents of FlutterView. Will create, update and remove sublayers as needed.

Must be called on raster thread. This will schedule a commit on the platform thread and block the raster thread until the commit is done. The notify block will be invoked on the platform thread and can be used to perform additional work, such as mutating platform views. It is guaranteed be called in the same CATransaction.

◆ presentSurfaces:atTime:notify: [2/2]

- (void) presentSurfaces: (NSArray<FlutterSurfacePresentInfo*>*)  surfaces
atTime: (CFTimeInterval)  presentationTime
notify: (dispatch_block_t)  notify 
implementation

Definition at line 209 of file FlutterSurfaceManager.mm.

218 :(NSArray<FlutterSurfacePresentInfo*>*)surfaces
219 atTime:(CFTimeInterval)presentationTime
220 notify:(dispatch_block_t)notify {
221 id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
222 [commandBuffer commit];
223 [commandBuffer waitUntilScheduled];
224
225 dispatch_block_t presentBlock = ^{
226 // Get the actual dimensions of the frame (relevant for thread synchronizer).
227 CGSize size = GetRequiredFrameSize(surfaces);
228 [_delegate onPresent:size
229 withBlock:^{
230 _lastPresentationTime = presentationTime;
231 [self commit:surfaces];
232 if (notify != nil) {
233 notify();
234 }
235 }];
236 };
237
238 if (presentationTime > 0) {
239 // Enforce frame pacing. It seems that the target timestamp of CVDisplayLink does not
240 // exactly correspond to core animation deadline. Especially with 120hz, setting the frame
241 // contents too close after previous target timestamp will result in uneven frame pacing.
242 // Empirically setting the content in the second half of frame interval seems to work
243 // well for both 60hz and 120hz.
244 //
245 // This schedules a timer on current (raster) thread runloop. Raster thread at
246 // this point should be idle (the next frame vsync has not been signalled yet).
247 //
248 // Alternative could be simply blocking the raster thread, but that would show
249 // as a average_frame_rasterizer_time_millis regresson.
250 CFTimeInterval minPresentationTime = (presentationTime + _lastPresentationTime) / 2.0;
251 CFTimeInterval now = CACurrentMediaTime();
252 if (now < minPresentationTime) {
253 NSTimer* timer = [NSTimer timerWithTimeInterval:minPresentationTime - now
254 repeats:NO
255 block:^(NSTimer* timer) {
256 presentBlock();
257 }];
258 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
259 return;
260 }
261 }
262 presentBlock();
263}
static CGSize GetRequiredFrameSize(NSArray< FlutterSurfacePresentInfo * > *surfaces)
CFTimeInterval _lastPresentationTime

◆ surfaceForSize:

- (FlutterSurface *) surfaceForSize: (CGSize)  size

Returns a back buffer surface of the given size to which Flutter can render content. A cached surface will be returned if available; otherwise a new one will be created.

Must be called on raster thread.

Definition at line 38 of file FlutterSurfaceManager.mm.

133 :(CGSize)size {
134 FlutterSurface* surface = [_backBufferCache removeSurfaceForSize:size];
135 if (surface == nil) {
136 surface = [[FlutterSurface alloc] initWithSize:size device:_device];
137 }
138 return surface;
139}
VkSurfaceKHR surface
Definition: main.cc:49

Member Data Documentation

◆ _backBufferCache

- (FlutterBackBufferCache*) _backBufferCache
protected

Definition at line 25 of file FlutterSurfaceManager.mm.

◆ _commandQueue

- (id<MTLCommandQueue>) _commandQueue
protected

Definition at line 19 of file FlutterSurfaceManager.mm.

◆ _containingLayer

- (CALayer*) _containingLayer
protected

Definition at line 20 of file FlutterSurfaceManager.mm.

◆ _delegate

- (__weak id<FlutterSurfaceManagerDelegate>) _delegate
protected

Definition at line 21 of file FlutterSurfaceManager.mm.

◆ _device

- (id<MTLDevice>) _device
protected

Definition at line 18 of file FlutterSurfaceManager.mm.

◆ _enableSurfaceDebugInfo

- (NSNumber*) _enableSurfaceDebugInfo
protected

Definition at line 35 of file FlutterSurfaceManager.mm.

◆ _frontSurfaces

- (NSMutableArray<FlutterSurface*>*) _frontSurfaces
protected

Definition at line 28 of file FlutterSurfaceManager.mm.

◆ _infoLayer

- (CATextLayer*) _infoLayer
protected

Definition at line 36 of file FlutterSurfaceManager.mm.

◆ _lastPresentationTime

- (CFTimeInterval) _lastPresentationTime
protected

Definition at line 38 of file FlutterSurfaceManager.mm.

◆ _layers

- (NSMutableArray<CALayer*>*) _layers
protected

Definition at line 31 of file FlutterSurfaceManager.mm.


The documentation for this class was generated from the following files: