From eaa5fe4b74d201c74ad82900ff0dd485d3776ec4 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 21 Sep 2023 14:16:18 -0700 Subject: [PATCH] [Impeller] Use final cmd buffer to present drawable. (flutter/engine#46023) If we're not running with a transaction then we don't need to block on waitUntilScheduled on any platform. I think this should always work, as the problems we had before were due to always using drawable present. But this helper method schedules the drawable presentation after the cmd buffer is scheduled - which is what we're doing with waitUntilScheduled anyway - just non blocking from our perspective. Fixes https://github.com/flutter/flutter/issues/131520 --- .../renderer/backend/metal/surface_mtl.mm | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/engine/src/flutter/impeller/renderer/backend/metal/surface_mtl.mm b/engine/src/flutter/impeller/renderer/backend/metal/surface_mtl.mm index 526e66f4c5..7244fc3b2a 100644 --- a/engine/src/flutter/impeller/renderer/backend/metal/surface_mtl.mm +++ b/engine/src/flutter/impeller/renderer/backend/metal/surface_mtl.mm @@ -248,13 +248,22 @@ bool SurfaceMTL::Present() const { } if (drawable_) { - TRACE_EVENT0("flutter", "waitUntilScheduled"); id command_buffer = ContextMTL::Cast(context.get()) ->CreateMTLCommandBuffer("Present Waiter Command Buffer"); - [command_buffer commit]; - [command_buffer waitUntilScheduled]; - [drawable_ present]; + // If the threads have been merged, or there is a pending frame capture, + // then block on cmd buffer scheduling to ensure that the + // transaction/capture work correctly. + if ([[NSThread currentThread] isMainThread] || + [[MTLCaptureManager sharedCaptureManager] isCapturing]) { + TRACE_EVENT0("flutter", "waitUntilScheduled"); + [command_buffer commit]; + [command_buffer waitUntilScheduled]; + [drawable_ present]; + } else { + [command_buffer presentDrawable:drawable_]; + [command_buffer commit]; + } } return true;