From 21b85df3faa91f79ea6f5abdb6293d2f928b987e Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 8 Aug 2024 11:46:41 -0700 Subject: [PATCH 1/3] [Impeller] perform final blit and gpu end frame tracing earlier. --- impeller/renderer/backend/metal/surface_mtl.h | 3 +++ .../renderer/backend/metal/surface_mtl.mm | 12 +++++++-- shell/gpu/gpu_surface_metal_impeller.mm | 27 ++++++++++++++++--- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/impeller/renderer/backend/metal/surface_mtl.h b/impeller/renderer/backend/metal/surface_mtl.h index c5dd5a61eeff6..10a00bca73ab0 100644 --- a/impeller/renderer/backend/metal/surface_mtl.h +++ b/impeller/renderer/backend/metal/surface_mtl.h @@ -65,6 +65,9 @@ class SurfaceMTL final : public Surface { present_with_transaction_ = present_with_transaction; } + /// @brief Perform the final blit and trigger end of frame workloads. + bool PreparePresent(); + // |Surface| bool Present() const override; diff --git a/impeller/renderer/backend/metal/surface_mtl.mm b/impeller/renderer/backend/metal/surface_mtl.mm index c94ad6cd4c0da..335151a9b5cd7 100644 --- a/impeller/renderer/backend/metal/surface_mtl.mm +++ b/impeller/renderer/backend/metal/surface_mtl.mm @@ -222,8 +222,7 @@ - (void)flutterPrepareForPresent:(nonnull id)commandBuffer; return IRect::MakeSize(resolve_texture_->GetSize()); } -// |Surface| -bool SurfaceMTL::Present() const { +bool SurfaceMTL::PreparePresent() { auto context = context_.lock(); if (!context) { return false; @@ -260,6 +259,15 @@ - (void)flutterPrepareForPresent:(nonnull id)commandBuffer; #ifdef IMPELLER_DEBUG ContextMTL::Cast(context.get())->GetGPUTracer()->MarkFrameEnd(); #endif // IMPELLER_DEBUG + return true; +} + +// |Surface| +bool SurfaceMTL::Present() const { + auto context = context_.lock(); + if (!context) { + return false; + } if (drawable_) { id command_buffer = diff --git a/shell/gpu/gpu_surface_metal_impeller.mm b/shell/gpu/gpu_surface_metal_impeller.mm index 5041fc4092c11..f9cb5dd30b3e2 100644 --- a/shell/gpu/gpu_surface_metal_impeller.mm +++ b/shell/gpu/gpu_surface_metal_impeller.mm @@ -157,6 +157,9 @@ surface->PresentWithTransaction(surface_frame.submit_info().present_with_transaction); if (clip_rect && clip_rect->IsEmpty()) { + if (!surface->PreparePresent()) { + return false; + } surface_frame.set_user_data(std::move(surface)); return true; } @@ -167,7 +170,6 @@ const impeller::RenderTarget& render_target = surface->GetTargetRenderPassDescriptor(); surface->SetFrameBoundary(surface_frame.submit_info().frame_boundary); - surface_frame.set_user_data(std::move(surface)); #if EXPERIMENTAL_CANVAS impeller::TextFrameDispatcher collector(aiks_context->GetContentContext(), impeller::Matrix()); @@ -181,13 +183,25 @@ impeller_dispatcher.FinishRecording(); aiks_context->GetContentContext().GetTransientsBuffer().Reset(); aiks_context->GetContentContext().GetLazyGlyphAtlas()->ResetTextFrames(); + + if (!surface->PreparePresent()) { + return false; + } + surface_frame.set_user_data(std::move(surface)); return true; #else impeller::DlDispatcher impeller_dispatcher(cull_rect); display_list->Dispatch(impeller_dispatcher, sk_cull_rect); auto picture = impeller_dispatcher.EndRecordingAsPicture(); const bool reset_host_buffer = surface_frame.submit_info().frame_boundary; - return aiks_context->Render(picture, render_target, reset_host_buffer); + + auto result = aiks_context->Render(picture, render_target, reset_host_buffer); + + if (!surface->PreparePresent()) { + return false; + } + surface_frame.set_user_data(std::move(surface)); + return result; #endif }); @@ -278,6 +292,9 @@ surface->PresentWithTransaction(surface_frame.submit_info().present_with_transaction); if (clip_rect && clip_rect->IsEmpty()) { + if (!surface->PreparePresent()) { + return false; + } return surface->Present(); } @@ -296,6 +313,9 @@ impeller_dispatcher.FinishRecording(); aiks_context->GetContentContext().GetTransientsBuffer().Reset(); aiks_context->GetContentContext().GetLazyGlyphAtlas()->ResetTextFrames(); + if (!surface->PreparePresent()) { + return false; + } bool render_result = true; #else impeller::DlDispatcher impeller_dispatcher(cull_rect); @@ -310,8 +330,7 @@ FML_LOG(ERROR) << "Failed to render Impeller frame"; return false; } - - return true; + return surface->PreparePresent(); }); SurfaceFrame::SubmitCallback submit_callback = From e8342707407698b77eec7a1359d3858960c6a74e Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 8 Aug 2024 12:07:07 -0700 Subject: [PATCH 2/3] Update surface_mtl.h --- impeller/renderer/backend/metal/surface_mtl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/impeller/renderer/backend/metal/surface_mtl.h b/impeller/renderer/backend/metal/surface_mtl.h index 10a00bca73ab0..bff5072f8fb8b 100644 --- a/impeller/renderer/backend/metal/surface_mtl.h +++ b/impeller/renderer/backend/metal/surface_mtl.h @@ -85,6 +85,7 @@ class SurfaceMTL final : public Surface { std::optional clip_rect_; bool frame_boundary_ = false; bool present_with_transaction_ = false; + bool prepared_ = false; static bool ShouldPerformPartialRepaint(std::optional damage_rect); From 00f0534706216f8074f8f1a1b1e96390323c8d1f Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 8 Aug 2024 12:07:40 -0700 Subject: [PATCH 3/3] Update surface_mtl.mm --- impeller/renderer/backend/metal/surface_mtl.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/impeller/renderer/backend/metal/surface_mtl.mm b/impeller/renderer/backend/metal/surface_mtl.mm index 335151a9b5cd7..caa6804c8a42a 100644 --- a/impeller/renderer/backend/metal/surface_mtl.mm +++ b/impeller/renderer/backend/metal/surface_mtl.mm @@ -259,11 +259,13 @@ - (void)flutterPrepareForPresent:(nonnull id)commandBuffer; #ifdef IMPELLER_DEBUG ContextMTL::Cast(context.get())->GetGPUTracer()->MarkFrameEnd(); #endif // IMPELLER_DEBUG + prepared_ = true; return true; } // |Surface| bool SurfaceMTL::Present() const { + FML_CHECK(prepared_); auto context = context_.lock(); if (!context) { return false;