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; } 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..d2de660fd43be 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,16 @@ return false; } - [drawable_ present]; + auto context = context_.lock(); + if (!context) { + return false; + } + + id command_buffer = + ContextMTL::Cast(context.get())->CreateMTLCommandBuffer(); + [command_buffer presentDrawable:drawable_]; + [command_buffer commit]; + return true; } #pragma GCC diagnostic pop