From 87da0c7aa740689193d0e830f777724ed3f7cc80 Mon Sep 17 00:00:00 2001 From: Kaushik Iska Date: Mon, 25 Jan 2021 14:50:21 -0600 Subject: [PATCH] [macos] Support smooth resizing for Metal (#23924) Coordinate command buffer submission with Core Animation scheduling to ensure smooth resizing. Fixes: https://github.com/flutter/flutter/issues/74056 --- .../Source/FlutterResizableBackingStoreProvider.mm | 7 ++++++- .../darwin/macos/framework/Source/FlutterView.mm | 10 +++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm b/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm index eef7e29315880..2297bc91c3ee3 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm @@ -78,14 +78,19 @@ - (FlutterRenderBackingStore*)backingStore { } - (void)resizeSynchronizerFlush:(nonnull FlutterResizeSynchronizer*)synchronizer { - // TODO (kaushikiska): Support smooth resizing on Metal. + // no-op when using Metal rendering backend. } - (void)resizeSynchronizerCommit:(nonnull FlutterResizeSynchronizer*)synchronizer { + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + id commandBuffer = [_commandQueue commandBuffer]; [commandBuffer commit]; [commandBuffer waitUntilScheduled]; [_surfaceManager swapBuffers]; + + [CATransaction commit]; } @end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.mm b/shell/platform/darwin/macos/framework/Source/FlutterView.mm index 79f1e09ec3bc1..9043b72769f8b 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.mm @@ -27,6 +27,7 @@ - (instancetype)initWithMTLDevice:(id)device self = [super initWithFrame:NSZeroRect]; if (self) { [self setWantsLayer:YES]; + [self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawDuringViewResize]; _reshapeListener = reshapeListener; _resizableBackingStoreProvider = [[FlutterMetalResizableBackingStoreProvider alloc] initWithDevice:device @@ -44,7 +45,14 @@ + (Class)layerClass { } - (CALayer*)makeBackingLayer { - return [CAMetalLayer layer]; + CAMetalLayer* metalLayer = [CAMetalLayer layer]; + // This is set to true to synchronize the presentation of the layer and its contents with Core + // Animation. When presenting the texture see `[FlutterMetalResizableBackingStoreProvider + // resizeSynchronizerCommit:]` we start a CATransaction and wait for the command buffer to be + // scheduled. This ensures that the resizing process is smooth. + metalLayer.presentsWithTransaction = YES; + metalLayer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable; + return metalLayer; } #endif