From b90ef012c1b8287138cd6d4f3175afb0e362ed98 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 30 Mar 2023 14:39:25 -0700 Subject: [PATCH 1/3] [Impeller] iOS/macOS: Only wait for command scheduling prior to present --- impeller/renderer/backend/metal/context_mtl.h | 2 ++ impeller/renderer/backend/metal/context_mtl.mm | 4 ++++ impeller/renderer/backend/metal/surface_mtl.h | 5 ++++- impeller/renderer/backend/metal/surface_mtl.mm | 17 ++++++++++++----- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/impeller/renderer/backend/metal/context_mtl.h b/impeller/renderer/backend/metal/context_mtl.h index ac5de3a66bac9..21e7582e69511 100644 --- a/impeller/renderer/backend/metal/context_mtl.h +++ b/impeller/renderer/backend/metal/context_mtl.h @@ -64,6 +64,8 @@ class ContextMTL final : public Context, // |Context| bool UpdateOffscreenLayerPixelFormat(PixelFormat format) override; + id CreateMTLCommandBuffer() const; + private: id device_ = nullptr; id command_queue_ = nullptr; diff --git a/impeller/renderer/backend/metal/context_mtl.mm b/impeller/renderer/backend/metal/context_mtl.mm index 9bee27963f740..01daff97be2e6 100644 --- a/impeller/renderer/backend/metal/context_mtl.mm +++ b/impeller/renderer/backend/metal/context_mtl.mm @@ -290,4 +290,8 @@ static bool DeviceSupportsComputeSubgroups(id device) { return true; } +id ContextMTL::CreateMTLCommandBuffer() const { + return [command_queue_ commandBuffer]; +} + } // namespace impeller diff --git a/impeller/renderer/backend/metal/surface_mtl.h b/impeller/renderer/backend/metal/surface_mtl.h index e641dd6c23299..157e4e6e84454 100644 --- a/impeller/renderer/backend/metal/surface_mtl.h +++ b/impeller/renderer/backend/metal/surface_mtl.h @@ -43,9 +43,12 @@ class SurfaceMTL final : public Surface { id drawable() const { return drawable_; } private: + std::weak_ptr context_; id drawable_ = nil; - SurfaceMTL(const RenderTarget& target, id drawable); + SurfaceMTL(const std::weak_ptr& context, + const RenderTarget& target, + id drawable); // |Surface| bool Present() const override; diff --git a/impeller/renderer/backend/metal/surface_mtl.mm b/impeller/renderer/backend/metal/surface_mtl.mm index dccdac147f4e9..a7021cc5c7e53 100644 --- a/impeller/renderer/backend/metal/surface_mtl.mm +++ b/impeller/renderer/backend/metal/surface_mtl.mm @@ -6,6 +6,7 @@ #include "flutter/fml/trace_event.h" #include "impeller/base/validation.h" +#include "impeller/renderer/backend/metal/context_mtl.h" #include "impeller/renderer/backend/metal/formats_mtl.h" #include "impeller/renderer/backend/metal/texture_mtl.h" #include "impeller/renderer/render_target.h" @@ -111,12 +112,14 @@ render_target_desc.SetStencilAttachment(stencil0); // The constructor is private. So make_unique may not be used. - return std::unique_ptr( - new SurfaceMTL(render_target_desc, current_drawable)); + return std::unique_ptr(new SurfaceMTL( + context->weak_from_this(), render_target_desc, current_drawable)); } -SurfaceMTL::SurfaceMTL(const RenderTarget& target, id drawable) - : Surface(target), drawable_(drawable) {} +SurfaceMTL::SurfaceMTL(const std::weak_ptr& context, + const RenderTarget& target, + id drawable) + : Surface(target), context_(context), drawable_(drawable) {} // |Surface| SurfaceMTL::~SurfaceMTL() = default; @@ -127,7 +130,11 @@ return false; } - [drawable_ present]; + id command_buffer = + ContextMTL::Cast(context_.lock().get())->CreateMTLCommandBuffer(); + [command_buffer presentDrawable:drawable_]; + [command_buffer commit]; + return true; } #pragma GCC diagnostic pop From 3174bc19d0608208afa58856d4858cd0a566236c Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 30 Mar 2023 15:17:55 -0700 Subject: [PATCH 2/3] Add weak check --- impeller/renderer/backend/metal/surface_mtl.mm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/impeller/renderer/backend/metal/surface_mtl.mm b/impeller/renderer/backend/metal/surface_mtl.mm index a7021cc5c7e53..d2de660fd43be 100644 --- a/impeller/renderer/backend/metal/surface_mtl.mm +++ b/impeller/renderer/backend/metal/surface_mtl.mm @@ -130,8 +130,13 @@ return false; } + auto context = context_.lock(); + if (!context) { + return false; + } + id command_buffer = - ContextMTL::Cast(context_.lock().get())->CreateMTLCommandBuffer(); + ContextMTL::Cast(context.get())->CreateMTLCommandBuffer(); [command_buffer presentDrawable:drawable_]; [command_buffer commit]; From f0fd1a76458b24312014f4e41eed190816614f80 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 30 Mar 2023 15:29:49 -0700 Subject: [PATCH 3/3] Remove waitUntilScheduled --- .../backend/metal/command_buffer_mtl.mm | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/impeller/renderer/backend/metal/command_buffer_mtl.mm b/impeller/renderer/backend/metal/command_buffer_mtl.mm index 144ce2c330ef1..3c204a2821fd3 100644 --- a/impeller/renderer/backend/metal/command_buffer_mtl.mm +++ b/impeller/renderer/backend/metal/command_buffer_mtl.mm @@ -167,27 +167,6 @@ static bool LogMTLCommandBufferErrorIfPresent(id buffer) { [buffer_ commit]; -#if (FML_OS_MACOSX || FML_OS_IOS_SIMULATOR) - // We're using waitUntilScheduled on macOS and iOS simulator to force a hard - // barrier between the execution of different command buffers. This forces all - // renderable texture access to be synchronous (i.e. a write from a previous - // command buffer will not get scheduled to happen at the same time as a read - // in a future command buffer). - // - // Metal hazard tracks shared memory resources by default, and we don't need - // to do any additional work to synchronize access to MTLTextures and - // MTLBuffers on iOS devices with UMA. However, shared textures are disallowed - // on macOS according to the documentation: - // https://developer.apple.com/documentation/metal/mtlstoragemode/shared - // And so this is a stopgap solution that has been present in Impeller since - // multi-pass rendering/SaveLayer support was first set up. - // - // TODO(bdero): Remove this for all targets once a solution for resource - // tracking that works everywhere is established: - // https://github.com/flutter/flutter/issues/120406 - [buffer_ waitUntilScheduled]; -#endif - buffer_ = nil; return true; }