7 #include "flutter/fml/trace_event.h"
18 static_assert(__has_feature(objc_arc),
"ARC must be enabled.");
21 - (void)flutterPrepareForPresent:(nonnull
id<MTLCommandBuffer>)commandBuffer;
26 #pragma GCC diagnostic push
27 #pragma GCC diagnostic ignored "-Wunguarded-availability-new"
30 const std::shared_ptr<Context>& context,
31 CAMetalLayer* layer) {
32 TRACE_EVENT0(
"impeller",
"SurfaceMTL::WrapCurrentMetalLayerDrawable");
34 if (context ==
nullptr || !context->IsValid() || layer == nil) {
38 id<CAMetalDrawable> current_drawable = nil;
40 TRACE_EVENT0(
"impeller",
"WaitForNextDrawable");
41 current_drawable = [layer nextDrawable];
44 if (!current_drawable) {
48 return current_drawable;
52 const std::shared_ptr<SwapchainTransientsMTL>& transients,
53 id<MTLTexture> texture,
55 std::optional<IRect> clip_rect) {
64 transients->SetSizeAndFormat(root_size, format);
68 resolve_tex_desc.
size = root_size;
69 resolve_tex_desc.
usage =
75 std::shared_ptr<Texture> resolve_tex;
77 resolve_tex = transients->GetResolveTexture();
83 color0.
texture = transients->GetMSAATexture();
95 depth0.
texture = transients->GetDepthStencilTexture();
103 stencil0.
texture = transients->GetDepthStencilTexture();
110 return render_target;
114 const std::shared_ptr<Context>& context,
115 id<CAMetalDrawable> drawable,
116 const std::shared_ptr<SwapchainTransientsMTL>& transients,
117 std::optional<IRect> clip_rect) {
123 const std::shared_ptr<Context>& context,
124 id<MTLTexture> texture,
125 const std::shared_ptr<SwapchainTransientsMTL>& transients,
126 std::optional<IRect> clip_rect,
127 id<CAMetalDrawable> drawable) {
128 bool partial_repaint_blit_required = ShouldPerformPartialRepaint(clip_rect);
134 transients, texture, partial_repaint_blit_required, clip_rect);
135 if (!render_target) {
142 auto source_texture = partial_repaint_blit_required
143 ? render_target->GetRenderTargetTexture()
148 std::shared_ptr<Texture> destination_texture;
149 if (partial_repaint_blit_required) {
153 auto destination_descriptor =
154 render_target->GetRenderTargetTexture()->GetTextureDescriptor();
155 destination_descriptor.size = {
static_cast<ISize::Type>(texture.width),
161 destination_texture = render_target->GetRenderTargetTexture();
164 return std::unique_ptr<SurfaceMTL>(
new SurfaceMTL(
167 render_target->GetRenderTargetTexture(),
171 partial_repaint_blit_required,
176 SurfaceMTL::SurfaceMTL(
const std::weak_ptr<Context>& context,
178 std::shared_ptr<Texture> resolve_texture,
179 id<CAMetalDrawable> drawable,
180 std::shared_ptr<Texture> source_texture,
181 std::shared_ptr<Texture> destination_texture,
183 std::optional<IRect> clip_rect)
186 resolve_texture_(
std::move(resolve_texture)),
188 source_texture_(
std::move(source_texture)),
189 destination_texture_(
std::move(destination_texture)),
190 requires_blit_(requires_blit),
191 clip_rect_(clip_rect) {}
196 bool SurfaceMTL::ShouldPerformPartialRepaint(std::optional<IRect> damage_rect) {
200 if (!damage_rect.has_value()) {
205 if (damage_rect->IsEmpty()) {
217 auto context = context_.lock();
222 #ifdef IMPELLER_DEBUG
223 context->GetResourceAllocator()->DebugTraceMemoryStatistics();
224 if (frame_boundary_) {
229 if (requires_blit_) {
230 if (!(source_texture_ && destination_texture_)) {
235 if (!blit_command_buffer) {
238 auto blit_pass = blit_command_buffer->CreateBlitPass();
239 if (!clip_rect_.has_value()) {
243 blit_pass->AddCopy(source_texture_, destination_texture_, clip_rect_,
244 clip_rect_->GetOrigin());
245 blit_pass->EncodeCommands();
246 if (!context->GetCommandQueue()->Submit({blit_command_buffer}).ok()) {
250 #ifdef IMPELLER_DEBUG
262 auto context = context_.lock();
268 id<MTLCommandBuffer> command_buffer =
272 id<CAMetalDrawable> metal_drawable =
273 reinterpret_cast<id<CAMetalDrawable>
>(drawable_);
276 flutterPrepareForPresent:command_buffer];
283 #if defined(FML_OS_IOS_SIMULATOR) && defined(FML_ARCH_CPU_X86_64)
284 constexpr
bool alwaysWaitForScheduling =
true;
286 constexpr
bool alwaysWaitForScheduling =
false;
292 if (present_with_transaction_ || [[NSThread currentThread] isMainThread] ||
293 [[MTLCaptureManager sharedCaptureManager] isCapturing] ||
294 alwaysWaitForScheduling) {
295 TRACE_EVENT0(
"flutter",
"waitUntilScheduled");
296 [command_buffer commit];
297 #if defined(FML_OS_IOS_SIMULATOR) && defined(FML_ARCH_CPU_X86_64)
298 [command_buffer waitUntilCompleted];
300 [command_buffer waitUntilScheduled];
306 id<CAMetalDrawable>
drawable = drawable_;
307 [command_buffer addScheduledHandler:^(id<MTLCommandBuffer> buffer) {
310 [command_buffer commit];
316 #pragma GCC diagnostic pop
static ContextMTL & Cast(Context &base)
std::shared_ptr< CommandBuffer > CreateCommandBuffer() const override
Create a new command buffer. Command buffers can be used to encode graphics, blit,...
id< MTLCommandBuffer > CreateMTLCommandBuffer(const std::string &label) const
RenderTarget & SetColorAttachment(const ColorAttachment &attachment, size_t index)
static constexpr AttachmentConfig kDefaultStencilAttachmentConfig
RenderTarget & SetDepthAttachment(std::optional< DepthAttachment > attachment)
RenderTarget & SetStencilAttachment(std::optional< StencilAttachment > attachment)
bool Present() const override
static std::unique_ptr< SurfaceMTL > MakeFromMetalLayerDrawable(const std::shared_ptr< Context > &context, id< CAMetalDrawable > drawable, const std::shared_ptr< SwapchainTransientsMTL > &transients, std::optional< IRect > clip_rect=std::nullopt)
static id< CAMetalDrawable > GetMetalDrawableAndValidate(const std::shared_ptr< Context > &context, CAMetalLayer *layer)
Wraps the current drawable of the given Metal layer to create a surface Impeller can render to....
bool PreparePresent() const
Perform the final blit and trigger end of frame workloads.
static std::unique_ptr< SurfaceMTL > MakeFromTexture(const std::shared_ptr< Context > &context, id< MTLTexture > texture, const std::shared_ptr< SwapchainTransientsMTL > &transients, std::optional< IRect > clip_rect, id< CAMetalDrawable > drawable=nil)
id< MTLDrawable > drawable() const
static std::shared_ptr< TextureMTL > Wrapper(TextureDescriptor desc, id< MTLTexture > texture, std::function< void()> deletion_proc=nullptr)
static std::shared_ptr< TextureMTL > Create(TextureDescriptor desc, id< MTLTexture > texture)
constexpr PixelFormat FromMTLPixelFormat(MTLPixelFormat format)
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
static std::optional< RenderTarget > WrapTextureWithRenderTarget(const std::shared_ptr< SwapchainTransientsMTL > &transients, id< MTLTexture > texture, bool requires_blit, std::optional< IRect > clip_rect)
std::shared_ptr< Texture > resolve_texture
std::shared_ptr< Texture > texture
static constexpr Color DarkSlateGray()
constexpr static TRect MakeSize(const TSize< U > &size)
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...