forked from firka/flutter
[iOS] Avoid crash when backdrop filter is null for PlatformViews (flutter/engine#43150)
During certain partial repaint logic, the backdrop filter layer is present but the filter itself is null. We need to account for it when deciding whether to add such filter to the mutator stack. Fixes https://github.com/flutter/flutter/issues/127095 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
@@ -42,7 +42,7 @@ void BackdropFilterLayer::Diff(DiffContext* context, const Layer* old_layer) {
|
||||
void BackdropFilterLayer::Preroll(PrerollContext* context) {
|
||||
Layer::AutoPrerollSaveLayerState save =
|
||||
Layer::AutoPrerollSaveLayerState::Create(context, true, bool(filter_));
|
||||
if (context->view_embedder != nullptr) {
|
||||
if (filter_ && context->view_embedder != nullptr) {
|
||||
context->view_embedder->PushFilterToVisitedPlatformViews(
|
||||
filter_, context->state_stack.device_cull_rect());
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
6860CE272A01B2FF00B68EC5 /* golden_two_platform_view_clip_path_iPhone SE (3rd generation)_16.2_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 6860CE242A01B2FF00B68EC5 /* golden_two_platform_view_clip_path_iPhone SE (3rd generation)_16.2_simulator.png */; };
|
||||
68A5B63423EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A5B63323EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m */; };
|
||||
68D4017D2564859300ECD91A /* ContinuousTexture.m in Sources */ = {isa = PBXBuildFile; fileRef = 68D4017C2564859300ECD91A /* ContinuousTexture.m */; };
|
||||
68D93AEE2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_16.2_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 68D93AED2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_16.2_simulator.png */; };
|
||||
F26F15B8268B6B5600EC54D3 /* iPadGestureTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F26F15B7268B6B5500EC54D3 /* iPadGestureTests.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -183,6 +184,7 @@
|
||||
68A5B63323EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PlatformViewGestureRecognizerTests.m; sourceTree = "<group>"; };
|
||||
68D4017B2564859300ECD91A /* ContinuousTexture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContinuousTexture.h; sourceTree = "<group>"; };
|
||||
68D4017C2564859300ECD91A /* ContinuousTexture.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ContinuousTexture.m; sourceTree = "<group>"; };
|
||||
68D93AED2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_16.2_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_16.2_simulator.png"; sourceTree = "<group>"; };
|
||||
F26F15B7268B6B5500EC54D3 /* iPadGestureTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iPadGestureTests.m; sourceTree = "<group>"; };
|
||||
F72114B628EF99F500184A2D /* Info_Impeller.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info_Impeller.plist; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
@@ -308,6 +310,7 @@
|
||||
F7B464DC2759D02B00079189 /* Goldens */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
68D93AED2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_16.2_simulator.png */,
|
||||
6860CE242A01B2FF00B68EC5 /* golden_two_platform_view_clip_path_iPhone SE (3rd generation)_16.2_simulator.png */,
|
||||
6860CE232A01B2FF00B68EC5 /* golden_two_platform_view_clip_rect_iPhone SE (3rd generation)_16.2_simulator.png */,
|
||||
6860CE222A01B2FF00B68EC5 /* golden_two_platform_view_clip_rrect_iPhone SE (3rd generation)_16.2_simulator.png */,
|
||||
@@ -477,6 +480,7 @@
|
||||
684FFF8629F9C10700281002 /* golden_bogus_font_text_iPhone SE (3rd generation)_16.2_simulator.png in Resources */,
|
||||
684FFF7E29F9C10700281002 /* golden_platform_view_opacity_iPhone SE (3rd generation)_16.2_simulator.png in Resources */,
|
||||
684FFF8729F9C10700281002 /* golden_platform_view_multiple_iPhone SE (3rd generation)_16.2_simulator.png in Resources */,
|
||||
68D93AEE2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_16.2_simulator.png in Resources */,
|
||||
684FFF8D29F9C10700281002 /* golden_platform_view_large_cliprrect_iPhone SE (3rd generation)_16.2_simulator.png in Resources */,
|
||||
684FFF8329F9C10700281002 /* golden_platform_view_transform_iPhone SE (3rd generation)_16.2_simulator.png in Resources */,
|
||||
684FFF8B29F9C10700281002 /* golden_platform_view_clippath_iPhone SE (3rd generation)_16.2_simulator.png in Resources */,
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
@"--platform-view-with-other-backdrop-filter" : @"platform_view_with_other_backdrop_filter",
|
||||
@"--two-platform-views-with-other-backdrop-filter" :
|
||||
@"two_platform_views_with_other_backdrop_filter",
|
||||
@"--platform-view-with-negative-backdrop-filter" :
|
||||
@"platform_view_with_negative_backdrop_filter",
|
||||
@"--platform-view-rotate" : @"platform_view_rotate",
|
||||
@"--non-full-screen-flutter-view-platform-view" : @"non_full_screen_flutter_view_platform_view",
|
||||
@"--gesture-reject-after-touches-ended" : @"platform_view_gesture_reject_after_touches_ended",
|
||||
|
||||
@@ -41,6 +41,8 @@ NSDictionary* launchArgsMap;
|
||||
@"--platform-view-with-other-backdrop-filter" : @"platform_view_with_other_backdrop_filter",
|
||||
@"--two-platform-views-with-other-backdrop-filter" :
|
||||
@"two_platform_views_with_other_backdrop_filter",
|
||||
@"--platform-view-with-negative-backdrop-filter" :
|
||||
@"platform_view_with_negative_backdrop_filter",
|
||||
@"--platform-view-rotate" : @"platform_view_rotate",
|
||||
@"--non-full-screen-flutter-view-platform-view" :
|
||||
@"non_full_screen_flutter_view_platform_view",
|
||||
|
||||
@@ -380,6 +380,24 @@ static const NSInteger kSecondsToWaitForPlatformView = 30;
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewWithNegativeOtherBackDropFilterTests : GoldenPlatformViewTests
|
||||
|
||||
@end
|
||||
|
||||
@implementation PlatformViewWithNegativeOtherBackDropFilterTests
|
||||
|
||||
- (instancetype)initWithInvocation:(NSInvocation*)invocation {
|
||||
GoldenTestManager* manager = [[GoldenTestManager alloc]
|
||||
initWithLaunchArg:@"--platform-view-with-negative-backdrop-filter"];
|
||||
return [super initWithManager:manager invocation:invocation];
|
||||
}
|
||||
|
||||
- (void)testPlatformView {
|
||||
[self checkPlatformViewGolden];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface PlatformViewRotation : GoldenPlatformViewTests
|
||||
@end
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
@@ -1443,8 +1443,6 @@ class PlatformViewWithOtherBackDropFilter extends PlatformViewScenario {
|
||||
/// A simple platform view for testing backDropFilter with a platform view in the scene.
|
||||
///
|
||||
/// The stack would look like: picture 1 -> pv1 -> picture 2 -> filter -> pv2 - > picture 3.
|
||||
/// Because backdrop filter on platform views has not been implemented(see: https://github.com/flutter/flutter/issues/43902),
|
||||
/// the result will not including a filtered pv1.
|
||||
class TwoPlatformViewsWithOtherBackDropFilter extends Scenario
|
||||
with _BasePlatformViewScenarioMixin {
|
||||
/// Constructs the scenario.
|
||||
@@ -1533,6 +1531,68 @@ class TwoPlatformViewsWithOtherBackDropFilter extends Scenario
|
||||
}
|
||||
}
|
||||
|
||||
/// A simple platform view for testing backDropFilter with a platform view in the scene.
|
||||
///
|
||||
/// The backdrop filter sigma value is negative, which tries to reproduce a crash, see:
|
||||
/// https://github.com/flutter/flutter/issues/127095
|
||||
class PlatformViewWithNegativeBackDropFilter extends Scenario
|
||||
with _BasePlatformViewScenarioMixin {
|
||||
/// Constructs the scenario.
|
||||
PlatformViewWithNegativeBackDropFilter(
|
||||
super.view, {
|
||||
required int id,
|
||||
}) : _id = id;
|
||||
|
||||
final int _id;
|
||||
|
||||
@override
|
||||
void onBeginFrame(Duration duration) {
|
||||
final SceneBuilder builder = SceneBuilder();
|
||||
|
||||
final PictureRecorder recorder = PictureRecorder();
|
||||
final Canvas canvas = Canvas(recorder);
|
||||
// This is just a background picture to make the result more viewable.
|
||||
canvas.drawRect(
|
||||
const Rect.fromLTRB(0, 0, 600, 1000),
|
||||
Paint()..color = const Color(0xFFFF0000),
|
||||
);
|
||||
canvas.drawRect(
|
||||
const Rect.fromLTRB(0, 0, 300, 300),
|
||||
Paint()..color = const Color(0xFF00FF00),
|
||||
);
|
||||
final Picture picture1 = recorder.endRecording();
|
||||
builder.addPicture(Offset.zero, picture1);
|
||||
|
||||
builder.pushOffset(0, 200);
|
||||
|
||||
addPlatformView(
|
||||
_id,
|
||||
dispatcher: view.platformDispatcher,
|
||||
sceneBuilder: builder,
|
||||
width: 100,
|
||||
height: 100,
|
||||
text: 'platform view 1'
|
||||
);
|
||||
|
||||
final PictureRecorder recorder2 = PictureRecorder();
|
||||
final Canvas canvas2 = Canvas(recorder2);
|
||||
canvas2.drawCircle(
|
||||
const Offset(200, 100),
|
||||
50,
|
||||
Paint()..color = const Color(0xFF0000EF),
|
||||
);
|
||||
final Picture picture2 = recorder2.endRecording();
|
||||
builder.addPicture(const Offset(100, 100), picture2);
|
||||
|
||||
final ImageFilter filter = ImageFilter.blur(sigmaX: -8, sigmaY: 8);
|
||||
builder.pushBackdropFilter(filter);
|
||||
|
||||
final Scene scene = builder.build();
|
||||
view.render(scene);
|
||||
scene.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a scenario where many platform views are scrolling and pass under a picture.
|
||||
class PlatformViewScrollingUnderWidget extends Scenario
|
||||
with _BasePlatformViewScenarioMixin {
|
||||
|
||||
@@ -43,6 +43,7 @@ Map<String, _ScenarioFactory> _scenarios = <String, _ScenarioFactory>{
|
||||
'platform_view_opacity': (FlutterView view) => PlatformViewOpacityScenario(view, id: _viewId++),
|
||||
'platform_view_with_other_backdrop_filter': (FlutterView view) => PlatformViewWithOtherBackDropFilter(view, id: _viewId++),
|
||||
'two_platform_views_with_other_backdrop_filter': (FlutterView view) => TwoPlatformViewsWithOtherBackDropFilter(view, firstId: _viewId++, secondId: _viewId++),
|
||||
'platform_view_with_negative_backdrop_filter': (FlutterView view) => PlatformViewWithNegativeBackDropFilter(view, id: _viewId++),
|
||||
'platform_view_multiple': (FlutterView view) => MultiPlatformViewScenario(view, firstId: _viewId++, secondId: _viewId++),
|
||||
'platform_view_multiple_background_foreground': (FlutterView view) => MultiPlatformViewBackgroundForegroundScenario(view, firstId: _viewId++, secondId: _viewId++),
|
||||
'non_full_screen_flutter_view_platform_view': (FlutterView view) => NonFullScreenFlutterViewPlatformViewScenario(view, id: _viewId++),
|
||||
|
||||
Reference in New Issue
Block a user