mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Preserve background frame damage (flutter/engine#54540)
Fixes https://github.com/flutter/flutter/issues/153335 When platform views are present, we always repaint entire frame. We must pass the buffer damage all the way to `GPUSurfaceMetalSkia/GPUSurfaceMetalImpeller` so that they know that the other two surfaces are lagging behind front surface and need to be repainted. This is currently not being done with platform view present, that's why we miss full frame repaint when removing platform view. With this merged in, it should be safe to reland https://github.com/flutter/engine/pull/54537 without any changes. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
parent
ed3b8da5e8
commit
7a1fd055b8
@ -3388,4 +3388,84 @@ fml::RefPtr<fml::TaskRunner> GetDefaultTaskRunner() {
|
||||
XCTAssertEqual(pool.size(), 1u);
|
||||
}
|
||||
|
||||
- (void)testFlutterPlatformViewControllerSubmitFramePreservingFrameDamage {
|
||||
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
|
||||
|
||||
flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
|
||||
/*platform=*/GetDefaultTaskRunner(),
|
||||
/*raster=*/GetDefaultTaskRunner(),
|
||||
/*ui=*/GetDefaultTaskRunner(),
|
||||
/*io=*/GetDefaultTaskRunner());
|
||||
auto flutterPlatformViewsController = std::make_shared<flutter::PlatformViewsController>();
|
||||
flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner());
|
||||
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
|
||||
/*delegate=*/mock_delegate,
|
||||
/*rendering_api=*/mock_delegate.settings_.enable_impeller
|
||||
? flutter::IOSRenderingAPI::kMetal
|
||||
: flutter::IOSRenderingAPI::kSoftware,
|
||||
/*platform_views_controller=*/flutterPlatformViewsController,
|
||||
/*task_runners=*/runners,
|
||||
/*worker_task_runner=*/nil,
|
||||
/*is_gpu_disabled_jsync_switch=*/std::make_shared<fml::SyncSwitch>());
|
||||
|
||||
UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
|
||||
flutterPlatformViewsController->SetFlutterView(flutterView);
|
||||
|
||||
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
|
||||
[[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init];
|
||||
flutterPlatformViewsController->RegisterViewFactory(
|
||||
factory, @"MockFlutterPlatformView",
|
||||
FlutterPlatformViewGestureRecognizersBlockingPolicyEager);
|
||||
FlutterResult result = ^(id result) {
|
||||
};
|
||||
flutterPlatformViewsController->OnMethodCall(
|
||||
[FlutterMethodCall
|
||||
methodCallWithMethodName:@"create"
|
||||
arguments:@{@"id" : @0, @"viewType" : @"MockFlutterPlatformView"}],
|
||||
result);
|
||||
|
||||
// This overwrites `gMockPlatformView` to another view.
|
||||
flutterPlatformViewsController->OnMethodCall(
|
||||
[FlutterMethodCall
|
||||
methodCallWithMethodName:@"create"
|
||||
arguments:@{@"id" : @1, @"viewType" : @"MockFlutterPlatformView"}],
|
||||
result);
|
||||
|
||||
flutterPlatformViewsController->BeginFrame(SkISize::Make(300, 300));
|
||||
flutter::MutatorsStack stack;
|
||||
SkMatrix finalMatrix;
|
||||
auto embeddedViewParams1 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
|
||||
flutterPlatformViewsController->PrerollCompositeEmbeddedView(0, std::move(embeddedViewParams1));
|
||||
|
||||
auto embeddedViewParams2 =
|
||||
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(500, 500), stack);
|
||||
flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams2));
|
||||
|
||||
// SKSurface is required if the root FlutterView is present.
|
||||
const SkImageInfo image_info = SkImageInfo::MakeN32Premul(1000, 1000);
|
||||
sk_sp<SkSurface> mock_sk_surface = SkSurfaces::Raster(image_info);
|
||||
flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
|
||||
std::optional<flutter::SurfaceFrame::SubmitInfo> submit_info;
|
||||
auto mock_surface = std::make_unique<flutter::SurfaceFrame>(
|
||||
std::move(mock_sk_surface), framebuffer_info,
|
||||
[](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; },
|
||||
[&](const flutter::SurfaceFrame& surface_frame) {
|
||||
submit_info = surface_frame.submit_info();
|
||||
return true;
|
||||
},
|
||||
/*frame_size=*/SkISize::Make(800, 600));
|
||||
mock_surface->set_submit_info({
|
||||
.frame_damage = SkIRect::MakeWH(800, 600),
|
||||
.buffer_damage = SkIRect::MakeWH(400, 600),
|
||||
});
|
||||
|
||||
XCTAssertTrue(
|
||||
flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface)));
|
||||
|
||||
XCTAssertTrue(submit_info.has_value());
|
||||
XCTAssertEqual(*submit_info->frame_damage, SkIRect::MakeWH(800, 600));
|
||||
XCTAssertEqual(*submit_info->buffer_damage, SkIRect::MakeWH(400, 600));
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -679,7 +679,12 @@ bool PlatformViewsController::SubmitFrame(GrDirectContext* gr_context,
|
||||
overlay_id++;
|
||||
}
|
||||
|
||||
background_frame->set_submit_info({.present_with_transaction = true});
|
||||
auto previous_submit_info = background_frame->submit_info();
|
||||
background_frame->set_submit_info({
|
||||
.frame_damage = previous_submit_info.frame_damage,
|
||||
.buffer_damage = previous_submit_info.buffer_damage,
|
||||
.present_with_transaction = true,
|
||||
});
|
||||
background_frame->Encode();
|
||||
surface_frames.push_back(std::move(background_frame));
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user