[Impeller] iOS/macOS: Only wait for command scheduling prior to present (flutter/engine#40781)
This commit is contained in:
@@ -167,27 +167,6 @@ bool CommandBufferMTL::OnSubmitCommands(CompletionCallback callback) {
|
||||
|
||||
[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;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,8 @@ class ContextMTL final : public Context,
|
||||
// |Context|
|
||||
bool UpdateOffscreenLayerPixelFormat(PixelFormat format) override;
|
||||
|
||||
id<MTLCommandBuffer> CreateMTLCommandBuffer() const;
|
||||
|
||||
private:
|
||||
id<MTLDevice> device_ = nullptr;
|
||||
id<MTLCommandQueue> command_queue_ = nullptr;
|
||||
|
||||
@@ -291,4 +291,8 @@ bool ContextMTL::UpdateOffscreenLayerPixelFormat(PixelFormat format) {
|
||||
return true;
|
||||
}
|
||||
|
||||
id<MTLCommandBuffer> ContextMTL::CreateMTLCommandBuffer() const {
|
||||
return [command_queue_ commandBuffer];
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@@ -43,9 +43,12 @@ class SurfaceMTL final : public Surface {
|
||||
id<MTLDrawable> drawable() const { return drawable_; }
|
||||
|
||||
private:
|
||||
std::weak_ptr<Context> context_;
|
||||
id<MTLDrawable> drawable_ = nil;
|
||||
|
||||
SurfaceMTL(const RenderTarget& target, id<MTLDrawable> drawable);
|
||||
SurfaceMTL(const std::weak_ptr<Context>& context,
|
||||
const RenderTarget& target,
|
||||
id<MTLDrawable> drawable);
|
||||
|
||||
// |Surface|
|
||||
bool Present() const override;
|
||||
|
||||
@@ -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 @@ std::unique_ptr<SurfaceMTL> SurfaceMTL::WrapCurrentMetalLayerDrawable(
|
||||
render_target_desc.SetStencilAttachment(stencil0);
|
||||
|
||||
// The constructor is private. So make_unique may not be used.
|
||||
return std::unique_ptr<SurfaceMTL>(
|
||||
new SurfaceMTL(render_target_desc, current_drawable));
|
||||
return std::unique_ptr<SurfaceMTL>(new SurfaceMTL(
|
||||
context->weak_from_this(), render_target_desc, current_drawable));
|
||||
}
|
||||
|
||||
SurfaceMTL::SurfaceMTL(const RenderTarget& target, id<MTLDrawable> drawable)
|
||||
: Surface(target), drawable_(drawable) {}
|
||||
SurfaceMTL::SurfaceMTL(const std::weak_ptr<Context>& context,
|
||||
const RenderTarget& target,
|
||||
id<MTLDrawable> drawable)
|
||||
: Surface(target), context_(context), drawable_(drawable) {}
|
||||
|
||||
// |Surface|
|
||||
SurfaceMTL::~SurfaceMTL() = default;
|
||||
@@ -127,7 +130,16 @@ bool SurfaceMTL::Present() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
[drawable_ present];
|
||||
auto context = context_.lock();
|
||||
if (!context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
id<MTLCommandBuffer> command_buffer =
|
||||
ContextMTL::Cast(context.get())->CreateMTLCommandBuffer();
|
||||
[command_buffer presentDrawable:drawable_];
|
||||
[command_buffer commit];
|
||||
|
||||
return true;
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
Reference in New Issue
Block a user