未验证 提交 1de3b877 编写于 作者: M Matej Knopp 提交者: GitHub

MacOS: Release backbuffer surface when idle (#27189)

上级 ef9ac753
......@@ -49,6 +49,12 @@
bufferIndex:(size_t)index
size:(CGSize)size;
/**
* Tells the delegate that IOSurface with given index has been released. Delegate should free
* all resources associated with the surface
*/
- (void)onSurfaceReleased:(size_t)index;
@end
/**
......
......@@ -17,6 +17,9 @@ enum {
kFlutterSurfaceManagerBufferCount,
};
// BackBuffer will be released after kIdleDelay if there is no activity.
static const double kIdleDelay = 1.0;
@implementation FlutterIOSurfaceManager {
CALayer* _containingLayer; // provided (parent layer)
CALayer* _contentLayer;
......@@ -46,8 +49,10 @@ enum {
}
_surfaceSize = size;
for (int i = 0; i < kFlutterSurfaceManagerBufferCount; ++i) {
[_ioSurfaces[i] recreateIOSurfaceWithSize:size];
[_delegate onUpdateSurface:_ioSurfaces[i] bufferIndex:i size:size];
if (_ioSurfaces[i] != nil) {
[_ioSurfaces[i] recreateIOSurfaceWithSize:size];
[_delegate onUpdateSurface:_ioSurfaces[i] bufferIndex:i size:size];
}
}
}
......@@ -60,6 +65,36 @@ enum {
std::swap(_ioSurfaces[kFlutterSurfaceManagerBackBuffer],
_ioSurfaces[kFlutterSurfaceManagerFrontBuffer]);
[_delegate onSwapBuffers];
dispatch_async(dispatch_get_main_queue(), ^{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onIdle) object:nil];
[self performSelector:@selector(onIdle) withObject:nil afterDelay:kIdleDelay];
});
}
- (void)onIdle {
@synchronized(self) {
// Release the back buffer and notify delegate. The buffer will be restored
// on demand in ensureBackBuffer
_ioSurfaces[kFlutterSurfaceManagerBackBuffer] = nil;
[self.delegate onSurfaceReleased:kFlutterSurfaceManagerBackBuffer];
}
}
- (void)ensureBackBuffer {
@synchronized(self) {
if (_ioSurfaces[kFlutterSurfaceManagerBackBuffer] == nil) {
// Restore previously released backbuffer
_ioSurfaces[kFlutterSurfaceManagerBackBuffer] = [[FlutterIOSurfaceHolder alloc] init];
[_ioSurfaces[kFlutterSurfaceManagerBackBuffer] recreateIOSurfaceWithSize:_surfaceSize];
[_delegate onUpdateSurface:_ioSurfaces[kFlutterSurfaceManagerBackBuffer]
bufferIndex:kFlutterSurfaceManagerBackBuffer
size:_surfaceSize];
}
};
dispatch_async(dispatch_get_main_queue(), ^{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onIdle) object:nil];
});
}
- (nonnull FlutterRenderBackingStore*)renderBuffer {
......@@ -84,14 +119,12 @@ enum {
if (self) {
super.delegate = self;
_openGLContext = openGLContext;
_frameBuffers[0] = [[FlutterFrameBufferProvider alloc] initWithOpenGLContext:_openGLContext];
_frameBuffers[1] = [[FlutterFrameBufferProvider alloc] initWithOpenGLContext:_openGLContext];
}
return self;
}
- (FlutterRenderBackingStore*)renderBuffer {
[self ensureBackBuffer];
uint32_t fboID = [_frameBuffers[kFlutterSurfaceManagerBackBuffer] glFrameBufferId];
return [[FlutterOpenGLRenderBackingStore alloc] initWithFrameBufferID:fboID];
}
......@@ -104,12 +137,20 @@ enum {
- (void)onUpdateSurface:(FlutterIOSurfaceHolder*)surface
bufferIndex:(size_t)index
size:(CGSize)size {
if (_frameBuffers[index] == nil) {
_frameBuffers[index] =
[[FlutterFrameBufferProvider alloc] initWithOpenGLContext:_openGLContext];
}
MacOSGLContextSwitch context_switch(_openGLContext);
GLuint fbo = [_frameBuffers[index] glFrameBufferId];
GLuint texture = [_frameBuffers[index] glTextureId];
[surface bindSurfaceToTexture:texture fbo:fbo size:size];
}
- (void)onSurfaceReleased:(size_t)index {
_frameBuffers[index] = nil;
}
@end
@implementation FlutterMetalSurfaceManager {
......@@ -132,6 +173,7 @@ enum {
}
- (FlutterRenderBackingStore*)renderBuffer {
[self ensureBackBuffer];
id<MTLTexture> texture = _textures[kFlutterSurfaceManagerBackBuffer];
return [[FlutterMetalRenderBackingStore alloc] initWithTexture:texture];
}
......@@ -157,4 +199,8 @@ enum {
plane:0];
}
- (void)onSurfaceReleased:(size_t)index {
_textures[index] = nil;
}
@end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册