[Impeller] perform final blit and gpu end frame tracing earlier. (flutter/engine#54452)

Fixes the reported GPU time regression when rendering platform views. The problem was that we delayed the tracing of the end of the frame until the CATransaction, which artificially stretches out GPU frame time. Instead add a new method SurfaceMTL::PreparePResent which performs the final blit and tracing, call this in the encode callback.

Fixes: https://flutter-flutter-perf.skia.org/e/?queries=sub_result%3Daverage_gpu_frame_time%26test%3Dplatform_views_scroll_perf_ios__timeline_summary&selected=commit%3D41853%26name%3D%252Carch%253Dintel%252Cbranch%253Dmaster%252Cconfig%253Ddefault%252Cdevice_type%253DiPhone_11%252Cdevice_version%253Dnone%252Chost_type%253Dmac%252Csub_result%253Daverage_gpu_frame_time%252Ctest%253Dplatform_views_scroll_perf_ios__timeline_summary%252C

Test: benchmarks.
This commit is contained in:
Jonah Williams 2024-08-08 12:46:04 -07:00 committed by GitHub
parent 76e6e34bb5
commit 62a1ddeaee
3 changed files with 39 additions and 6 deletions

View File

@ -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;
@ -82,6 +85,7 @@ class SurfaceMTL final : public Surface {
std::optional<IRect> clip_rect_;
bool frame_boundary_ = false;
bool present_with_transaction_ = false;
bool prepared_ = false;
static bool ShouldPerformPartialRepaint(std::optional<IRect> damage_rect);

View File

@ -222,8 +222,7 @@ IRect SurfaceMTL::coverage() const {
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,17 @@ bool SurfaceMTL::Present() const {
#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;
}
if (drawable_) {
id<MTLCommandBuffer> command_buffer =

View File

@ -157,6 +157,9 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceMetalImpeller::AcquireFrameFromCAMetalLa
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 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceMetalImpeller::AcquireFrameFromCAMetalLa
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 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceMetalImpeller::AcquireFrameFromCAMetalLa
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 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceMetalImpeller::AcquireFrameFromMTLTextur
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 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceMetalImpeller::AcquireFrameFromMTLTextur
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 @@ std::unique_ptr<SurfaceFrame> GPUSurfaceMetalImpeller::AcquireFrameFromMTLTextur
FML_LOG(ERROR) << "Failed to render Impeller frame";
return false;
}
return true;
return surface->PreparePresent();
});
SurfaceFrame::SubmitCallback submit_callback =