Flutter macOS Embedder
FlutterBackBufferCache Class Reference

#import <FlutterSurfaceManager.h>

Inheritance diagram for FlutterBackBufferCache:

Instance Methods

(nullable FlutterSurface *) - removeSurfaceForSize:
 
(void) - returnSurfaces:
 
(NSUInteger) - count
 

Detailed Description

Cache of back buffers to prevent unnecessary IOSurface allocations.

Definition at line 81 of file FlutterSurfaceManager.h.

Method Documentation

◆ count

- (NSUInteger) count

Returns number of surfaces currently in cache. Used for tests.

Definition at line 352 of file FlutterSurfaceManager.mm.

352  {
353  @synchronized(self) {
354  return _surfaces.count;
355  }
356 }

Referenced by flutter::testing::TEST().

◆ removeSurfaceForSize:

- (nullable FlutterSurface *) removeSurfaceForSize: (CGSize)  size

Removes surface with given size from cache (if available) and returns it.

Definition at line 301 of file FlutterSurfaceManager.mm.

301  :(CGSize)size {
302  @synchronized(self) {
303  // Purge all cached surfaces if the size has changed.
304  if (_surfaces.firstObject != nil && !CGSizeEqualToSize(_surfaces.firstObject.size, size)) {
305  [_surfaces removeAllObjects];
306  }
307 
308  FlutterSurface* res;
309 
310  // Returns youngest surface that is not in use. Returning youngest surface ensures
311  // that the cache doesn't keep more surfaces than it needs to, as the unused surfaces
312  // kept in cache will have their age kept increasing until purged (inside [returnSurfaces:]).
313  for (FlutterSurface* surface in _surfaces) {
314  if (!surface.isInUse &&
315  (res == nil || [self ageForSurface:res] > [self ageForSurface:surface])) {
316  res = surface;
317  }
318  }
319  if (res != nil) {
320  [_surfaces removeObject:res];
321  }
322  return res;
323  }
324 }

References FlutterSurface::isInUse.

◆ returnSurfaces:

- (void) returnSurfaces: (nonnull NSArray<FlutterSurface*>*)  surfaces

Removes all cached surfaces replacing them with new ones.

Definition at line 326 of file FlutterSurfaceManager.mm.

326  :(nonnull NSArray<FlutterSurface*>*)returnedSurfaces {
327  @synchronized(self) {
328  for (FlutterSurface* surface in returnedSurfaces) {
329  [self setAge:0 forSurface:surface];
330  }
331  for (FlutterSurface* surface in _surfaces) {
332  [self setAge:[self ageForSurface:surface] + 1 forSurface:surface];
333  }
334 
335  [_surfaces addObjectsFromArray:returnedSurfaces];
336 
337  // Purge all surface with age = kSurfaceEvictionAge. Reaching this age can mean two things:
338  // - Surface is still in use and we can't return it. This can happen in some edge
339  // cases where the compositor holds on to the surface for much longer than expected.
340  // - Surface is not in use but it hasn't been requested from the cache for a while.
341  // This means there are too many surfaces in the cache.
342  [_surfaces filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(FlutterSurface* surface,
343  NSDictionary* bindings) {
344  return [self ageForSurface:surface] < kSurfaceEvictionAge;
345  }]];
346  }
347 
348  // performSelector:withObject:afterDelay needs to be performed on RunLoop thread
349  [self performSelectorOnMainThread:@selector(reschedule) withObject:nil waitUntilDone:NO];
350 }

The documentation for this class was generated from the following files:
FlutterSurface
Definition: FlutterSurface.h:16