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

MacOS: Release backbuffer surface when idle (#27189)

上级 ef9ac753
...@@ -49,6 +49,12 @@ ...@@ -49,6 +49,12 @@
bufferIndex:(size_t)index bufferIndex:(size_t)index
size:(CGSize)size; 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 @end
/** /**
......
...@@ -17,6 +17,9 @@ enum { ...@@ -17,6 +17,9 @@ enum {
kFlutterSurfaceManagerBufferCount, kFlutterSurfaceManagerBufferCount,
}; };
// BackBuffer will be released after kIdleDelay if there is no activity.
static const double kIdleDelay = 1.0;
@implementation FlutterIOSurfaceManager { @implementation FlutterIOSurfaceManager {
CALayer* _containingLayer; // provided (parent layer) CALayer* _containingLayer; // provided (parent layer)
CALayer* _contentLayer; CALayer* _contentLayer;
...@@ -46,8 +49,10 @@ enum { ...@@ -46,8 +49,10 @@ enum {
} }
_surfaceSize = size; _surfaceSize = size;
for (int i = 0; i < kFlutterSurfaceManagerBufferCount; ++i) { for (int i = 0; i < kFlutterSurfaceManagerBufferCount; ++i) {
[_ioSurfaces[i] recreateIOSurfaceWithSize:size]; if (_ioSurfaces[i] != nil) {
[_delegate onUpdateSurface:_ioSurfaces[i] bufferIndex:i size:size]; [_ioSurfaces[i] recreateIOSurfaceWithSize:size];
[_delegate onUpdateSurface:_ioSurfaces[i] bufferIndex:i size:size];
}
} }
} }
...@@ -60,6 +65,36 @@ enum { ...@@ -60,6 +65,36 @@ enum {
std::swap(_ioSurfaces[kFlutterSurfaceManagerBackBuffer], std::swap(_ioSurfaces[kFlutterSurfaceManagerBackBuffer],
_ioSurfaces[kFlutterSurfaceManagerFrontBuffer]); _ioSurfaces[kFlutterSurfaceManagerFrontBuffer]);
[_delegate onSwapBuffers]; [_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 { - (nonnull FlutterRenderBackingStore*)renderBuffer {
...@@ -84,14 +119,12 @@ enum { ...@@ -84,14 +119,12 @@ enum {
if (self) { if (self) {
super.delegate = self; super.delegate = self;
_openGLContext = openGLContext; _openGLContext = openGLContext;
_frameBuffers[0] = [[FlutterFrameBufferProvider alloc] initWithOpenGLContext:_openGLContext];
_frameBuffers[1] = [[FlutterFrameBufferProvider alloc] initWithOpenGLContext:_openGLContext];
} }
return self; return self;
} }
- (FlutterRenderBackingStore*)renderBuffer { - (FlutterRenderBackingStore*)renderBuffer {
[self ensureBackBuffer];
uint32_t fboID = [_frameBuffers[kFlutterSurfaceManagerBackBuffer] glFrameBufferId]; uint32_t fboID = [_frameBuffers[kFlutterSurfaceManagerBackBuffer] glFrameBufferId];
return [[FlutterOpenGLRenderBackingStore alloc] initWithFrameBufferID:fboID]; return [[FlutterOpenGLRenderBackingStore alloc] initWithFrameBufferID:fboID];
} }
...@@ -104,12 +137,20 @@ enum { ...@@ -104,12 +137,20 @@ enum {
- (void)onUpdateSurface:(FlutterIOSurfaceHolder*)surface - (void)onUpdateSurface:(FlutterIOSurfaceHolder*)surface
bufferIndex:(size_t)index bufferIndex:(size_t)index
size:(CGSize)size { size:(CGSize)size {
if (_frameBuffers[index] == nil) {
_frameBuffers[index] =
[[FlutterFrameBufferProvider alloc] initWithOpenGLContext:_openGLContext];
}
MacOSGLContextSwitch context_switch(_openGLContext); MacOSGLContextSwitch context_switch(_openGLContext);
GLuint fbo = [_frameBuffers[index] glFrameBufferId]; GLuint fbo = [_frameBuffers[index] glFrameBufferId];
GLuint texture = [_frameBuffers[index] glTextureId]; GLuint texture = [_frameBuffers[index] glTextureId];
[surface bindSurfaceToTexture:texture fbo:fbo size:size]; [surface bindSurfaceToTexture:texture fbo:fbo size:size];
} }
- (void)onSurfaceReleased:(size_t)index {
_frameBuffers[index] = nil;
}
@end @end
@implementation FlutterMetalSurfaceManager { @implementation FlutterMetalSurfaceManager {
...@@ -132,6 +173,7 @@ enum { ...@@ -132,6 +173,7 @@ enum {
} }
- (FlutterRenderBackingStore*)renderBuffer { - (FlutterRenderBackingStore*)renderBuffer {
[self ensureBackBuffer];
id<MTLTexture> texture = _textures[kFlutterSurfaceManagerBackBuffer]; id<MTLTexture> texture = _textures[kFlutterSurfaceManagerBackBuffer];
return [[FlutterMetalRenderBackingStore alloc] initWithTexture:texture]; return [[FlutterMetalRenderBackingStore alloc] initWithTexture:texture];
} }
...@@ -157,4 +199,8 @@ enum { ...@@ -157,4 +199,8 @@ enum {
plane:0]; plane:0];
} }
- (void)onSurfaceReleased:(size_t)index {
_textures[index] = nil;
}
@end @end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册