[iOS] keep threads merged when using Skia renderer on iOS (flutter/engine#54514)

Potential fix for money crasher.
This commit is contained in:
Jonah Williams 2024-08-12 14:27:54 -07:00 committed by GitHub
parent a034d42a09
commit 1fd6a547fb
3 changed files with 44 additions and 33 deletions

View File

@ -84,14 +84,16 @@ class PlatformViewsController {
///
/// Called from the raster thread.
PostPrerollResult PostPrerollAction(
const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger);
const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger,
bool impeller_enabled);
/// @brief Mark the end of a compositor frame.
///
/// May determine changes are required to the thread merging state.
/// Called from the raster thread.
void EndFrame(bool should_resubmit_frame,
const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger);
const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger,
bool impeller_enabled);
/// @brief Returns the Canvas for the overlay slice for the given platform view.
///

View File

@ -15,13 +15,11 @@
namespace {
#ifdef FML_OS_IOS_SIMULATOR
// The number of frames the rasterizer task runner will continue
// to run on the platform thread after no platform view is rendered.
//
// Note: this is an arbitrary number.
static const int kDefaultMergedLeaseDuration = 10;
#endif // FML_OS_IOS_SIMULATOR
static constexpr NSUInteger kFlutterClippingMaskViewPoolCapacity = 5;
@ -291,43 +289,52 @@ void PlatformViewsController::CancelFrame() {
}
PostPrerollResult PlatformViewsController::PostPrerollAction(
const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger) {
const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger,
bool impeller_enabled) {
// TODO(jonahwilliams): remove this once Software backend is removed for iOS Sim.
#ifdef FML_OS_IOS_SIMULATOR
if (composition_order_.empty()) {
return PostPrerollResult::kSuccess;
}
if (!raster_thread_merger->IsMerged()) {
// The raster thread merger may be disabled if the rasterizer is being
// created or teared down.
//
// In such cases, the current frame is dropped, and a new frame is attempted
// with the same layer tree.
//
// Eventually, the frame is submitted once this method returns `kSuccess`.
// At that point, the raster tasks are handled on the platform thread.
CancelFrame();
return PostPrerollResult::kSkipAndRetryFrame;
}
// If the post preroll action is successful, we will display platform views in the current frame.
// In order to sync the rendering of the platform views (quartz) with skia's rendering,
// We need to begin an explicit CATransaction. This transaction needs to be submitted
// after the current frame is submitted.
raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
return PostPrerollResult::kSuccess;
const bool merge_threads = true;
#else
return PostPrerollResult::kSuccess;
const bool merge_threads = !impeller_enabled;
#endif // FML_OS_IOS_SIMULATOR
if (merge_threads) {
if (composition_order_.empty()) {
return PostPrerollResult::kSuccess;
}
if (!raster_thread_merger->IsMerged()) {
// The raster thread merger may be disabled if the rasterizer is being
// created or teared down.
//
// In such cases, the current frame is dropped, and a new frame is attempted
// with the same layer tree.
//
// Eventually, the frame is submitted once this method returns `kSuccess`.
// At that point, the raster tasks are handled on the platform thread.
CancelFrame();
return PostPrerollResult::kSkipAndRetryFrame;
}
// If the post preroll action is successful, we will display platform views in the current
// frame. In order to sync the rendering of the platform views (quartz) with skia's rendering,
// We need to begin an explicit CATransaction. This transaction needs to be submitted
// after the current frame is submitted.
raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
}
return PostPrerollResult::kSuccess;
}
void PlatformViewsController::EndFrame(
bool should_resubmit_frame,
const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger) {
const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger,
bool impeller_enabled) {
#if FML_OS_IOS_SIMULATOR
if (should_resubmit_frame) {
bool run_check = true;
#else
bool run_check = !impeller_enabled;
#endif // FML_OS_IOS_SIMULATOR
if (run_check && should_resubmit_frame) {
raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
}
#endif // FML_OS_IOS_SIMULATOR
}
void PlatformViewsController::PushFilterToVisitedPlatformViews(

View File

@ -59,7 +59,8 @@ PostPrerollResult IOSExternalViewEmbedder::PostPrerollAction(
const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger) {
TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::PostPrerollAction");
FML_CHECK(platform_views_controller_);
PostPrerollResult result = platform_views_controller_->PostPrerollAction(raster_thread_merger);
PostPrerollResult result = platform_views_controller_->PostPrerollAction(
raster_thread_merger, ios_context_->GetBackend() != IOSRenderingBackend::kSkia);
return result;
}
@ -91,7 +92,8 @@ void IOSExternalViewEmbedder::EndFrame(
bool should_resubmit_frame,
const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger) {
TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::EndFrame");
platform_views_controller_->EndFrame(should_resubmit_frame, raster_thread_merger);
platform_views_controller_->EndFrame(should_resubmit_frame, raster_thread_merger,
ios_context_->GetBackend() != IOSRenderingBackend::kSkia);
}
// |ExternalViewEmbedder|
@ -100,7 +102,7 @@ bool IOSExternalViewEmbedder::SupportsDynamicThreadMerging() {
#if FML_OS_IOS_SIMULATOR
return true;
#else
return false;
return ios_context_->GetBackend() == IOSRenderingBackend::kSkia;
#endif // FML_OS_IOS_SIMULATOR
}