From 790af8a5b0ccda91fe9d6dbabe5c33370fdcfe8a 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 eef7e293158..2297bc91c3e 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm @@ -78,14 +78,19 @@ } - (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 79f1e09ec3b..9043b72769f 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.mm @@ -27,6 +27,7 @@ self = [super initWithFrame:NSZeroRect]; if (self) { [self setWantsLayer:YES]; + [self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawDuringViewResize]; _reshapeListener = reshapeListener; _resizableBackingStoreProvider = [[FlutterMetalResizableBackingStoreProvider alloc] initWithDevice:device @@ -44,7 +45,14 @@ } - (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