diff --git a/impeller/renderer/backend/metal/command_buffer_mtl.mm b/impeller/renderer/backend/metal/command_buffer_mtl.mm index 3c204a2821fd3..144ce2c330ef1 100644 --- a/impeller/renderer/backend/metal/command_buffer_mtl.mm +++ b/impeller/renderer/backend/metal/command_buffer_mtl.mm @@ -167,6 +167,27 @@ 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; } diff --git a/impeller/renderer/backend/metal/context_mtl.h b/impeller/renderer/backend/metal/context_mtl.h index b266b1c0d7102..26ba5ace3fead 100644 --- a/impeller/renderer/backend/metal/context_mtl.h +++ b/impeller/renderer/backend/metal/context_mtl.h @@ -64,8 +64,6 @@ 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 fb1215ffdf22d..f72d3162438af 100644 --- a/impeller/renderer/backend/metal/context_mtl.mm +++ b/impeller/renderer/backend/metal/context_mtl.mm @@ -291,8 +291,4 @@ 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 157e4e6e84454..e641dd6c23299 100644 --- a/impeller/renderer/backend/metal/surface_mtl.h +++ b/impeller/renderer/backend/metal/surface_mtl.h @@ -43,12 +43,9 @@ class SurfaceMTL final : public Surface { id drawable() const { return drawable_; } private: - std::weak_ptr context_; id drawable_ = nil; - SurfaceMTL(const std::weak_ptr& context, - const RenderTarget& target, - id drawable); + SurfaceMTL(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 d2de660fd43be..dccdac147f4e9 100644 --- a/impeller/renderer/backend/metal/surface_mtl.mm +++ b/impeller/renderer/backend/metal/surface_mtl.mm @@ -6,7 +6,6 @@ #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" @@ -112,14 +111,12 @@ render_target_desc.SetStencilAttachment(stencil0); // The constructor is private. So make_unique may not be used. - return std::unique_ptr(new SurfaceMTL( - context->weak_from_this(), render_target_desc, current_drawable)); + return std::unique_ptr( + new SurfaceMTL(render_target_desc, current_drawable)); } -SurfaceMTL::SurfaceMTL(const std::weak_ptr& context, - const RenderTarget& target, - id drawable) - : Surface(target), context_(context), drawable_(drawable) {} +SurfaceMTL::SurfaceMTL(const RenderTarget& target, id drawable) + : Surface(target), drawable_(drawable) {} // |Surface| SurfaceMTL::~SurfaceMTL() = default; @@ -130,16 +127,7 @@ return false; } - auto context = context_.lock(); - if (!context) { - return false; - } - - id command_buffer = - ContextMTL::Cast(context.get())->CreateMTLCommandBuffer(); - [command_buffer presentDrawable:drawable_]; - [command_buffer commit]; - + [drawable_ present]; return true; } #pragma GCC diagnostic pop