diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index ec44e2af421b5..07d2885c04410 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -1856,6 +1856,102 @@ - (void)testClipRect { } } +- (void)testClipRect_multipleClips { + flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate; + + flutter::TaskRunners runners(/*label=*/self.name.UTF8String, + /*platform=*/GetDefaultTaskRunner(), + /*raster=*/GetDefaultTaskRunner(), + /*ui=*/GetDefaultTaskRunner(), + /*io=*/GetDefaultTaskRunner()); + auto flutterPlatformViewsController = std::make_shared(); + flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + auto platform_view = std::make_unique( + /*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()); + + FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = + [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; + flutterPlatformViewsController->RegisterViewFactory( + factory, @"MockFlutterPlatformView", + FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + FlutterResult result = ^(id result) { + }; + flutterPlatformViewsController->OnMethodCall( + [FlutterMethodCall + methodCallWithMethodName:@"create" + arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], + result); + + XCTAssertNotNil(gMockPlatformView); + + UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; + flutterPlatformViewsController->SetFlutterView(flutterView); + // Create embedded view params + flutter::MutatorsStack stack; + // Layer tree always pushes a screen scale factor to the stack + SkMatrix screenScaleMatrix = + SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale); + stack.PushTransform(screenScaleMatrix); + // Push a clip rect + SkRect rect1 = SkRect::MakeXYWH(2, 2, 3, 3); + stack.PushClipRect(rect1); + // Push another clip rect + SkRect rect2 = SkRect::MakeXYWH(3, 3, 3, 3); + stack.PushClipRect(rect2); + + auto embeddedViewParams = + std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); + + flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); + flutterPlatformViewsController->CompositeWithParams( + 2, flutterPlatformViewsController->GetCompositionParams(2)); + + gMockPlatformView.backgroundColor = UIColor.redColor; + XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); + ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview; + [flutterView addSubview:childClippingView]; + + [flutterView setNeedsLayout]; + [flutterView layoutIfNeeded]; + + /* + clip 1 clip 2 + 2 3 4 5 6 2 3 4 5 6 + 2 + - - + 2 + 3 | | 3 + - - + + 4 | | 4 | | + 5 + - - + 5 | | + 6 6 + - - + + + Result should be the intersection of 2 clips + 2 3 4 5 6 + 2 + 3 + - + + 4 | | + 5 + - + + 6 + */ + CGRect insideClipping = CGRectMake(3, 3, 2, 2); + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + CGPoint point = CGPointMake(i, j); + int alpha = [self alphaOfPoint:CGPointMake(i, j) onView:flutterView]; + if (CGRectContainsPoint(insideClipping, point)) { + XCTAssertEqual(alpha, 255); + } else { + XCTAssertEqual(alpha, 0); + } + } + } +} + - (void)testClipRRect { flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate; @@ -1959,6 +2055,126 @@ - (void)testClipRRect { } } +- (void)testClipRRect_multipleClips { + flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate; + + flutter::TaskRunners runners(/*label=*/self.name.UTF8String, + /*platform=*/GetDefaultTaskRunner(), + /*raster=*/GetDefaultTaskRunner(), + /*ui=*/GetDefaultTaskRunner(), + /*io=*/GetDefaultTaskRunner()); + auto flutterPlatformViewsController = std::make_shared(); + flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + auto platform_view = std::make_unique( + /*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()); + + FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = + [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; + flutterPlatformViewsController->RegisterViewFactory( + factory, @"MockFlutterPlatformView", + FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + FlutterResult result = ^(id result) { + }; + flutterPlatformViewsController->OnMethodCall( + [FlutterMethodCall + methodCallWithMethodName:@"create" + arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], + result); + + XCTAssertNotNil(gMockPlatformView); + + UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; + flutterPlatformViewsController->SetFlutterView(flutterView); + // Create embedded view params + flutter::MutatorsStack stack; + // Layer tree always pushes a screen scale factor to the stack + SkMatrix screenScaleMatrix = + SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale); + stack.PushTransform(screenScaleMatrix); + // Push a clip rrect + SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(2, 2, 6, 6), 1, 1); + stack.PushClipRRect(rrect); + // Push a clip rect + SkRect rect = SkRect::MakeXYWH(4, 2, 6, 6); + stack.PushClipRect(rect); + + auto embeddedViewParams = + std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); + + flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); + flutterPlatformViewsController->CompositeWithParams( + 2, flutterPlatformViewsController->GetCompositionParams(2)); + + gMockPlatformView.backgroundColor = UIColor.redColor; + XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); + ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview; + [flutterView addSubview:childClippingView]; + + [flutterView setNeedsLayout]; + [flutterView layoutIfNeeded]; + + /* + clip 1 clip 2 + 2 3 4 5 6 7 8 9 2 3 4 5 6 7 8 9 + 2 / - - - - \ 2 + - - - - + + 3 | | 3 | | + 4 | | 4 | | + 5 | | 5 | | + 6 | | 6 | | + 7 \ - - - - / 7 + - - - - + + + Result should be the intersection of 2 clips + 2 3 4 5 6 7 8 9 + 2 + - - \ + 3 | | + 4 | | + 5 | | + 6 | | + 7 + - - / + */ + CGRect clipping = CGRectMake(4, 2, 4, 6); + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + CGPoint point = CGPointMake(i, j); + int alpha = [self alphaOfPoint:CGPointMake(i, j) onView:flutterView]; + if (i == 7 && (j == 2 || j == 7)) { + // Upper and lower right corners should be partially transparent. + XCTAssert(0 < alpha && alpha < 255); + } else if ( + // left + (i == 4 && j >= 2 && j <= 7) || + // right + (i == 7 && j >= 2 && j <= 7) || + // top + (j == 2 && i >= 4 && i <= 7) || + // bottom + (j == 7 && i >= 4 && i <= 7)) { + // Since we are falling back to software rendering for this case + // The edge pixels can be anti-aliased, so it may not be fully opaque. + XCTAssert(alpha > 127); + } else if ((i == 3 && j >= 1 && j <= 8) || (i == 8 && j >= 1 && j <= 8) || + (j == 1 && i >= 3 && i <= 8) || (j == 8 && i >= 3 && i <= 8)) { + // Since we are falling back to software rendering for this case + // The edge pixels can be anti-aliased, so it may not be fully transparent. + XCTAssert(alpha < 127); + } else if (CGRectContainsPoint(clipping, point)) { + // Other pixels inside clipping should be fully opaque. + XCTAssertEqual(alpha, 255); + } else { + // Pixels outside clipping should be fully transparent. + XCTAssertEqual(alpha, 0); + } + } + } +} + - (void)testClipPath { flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate; @@ -2063,6 +2279,127 @@ - (void)testClipPath { } } +- (void)testClipPath_multipleClips { + flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate; + + flutter::TaskRunners runners(/*label=*/self.name.UTF8String, + /*platform=*/GetDefaultTaskRunner(), + /*raster=*/GetDefaultTaskRunner(), + /*ui=*/GetDefaultTaskRunner(), + /*io=*/GetDefaultTaskRunner()); + auto flutterPlatformViewsController = std::make_shared(); + flutterPlatformViewsController->SetTaskRunner(GetDefaultTaskRunner()); + auto platform_view = std::make_unique( + /*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()); + + FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = + [[FlutterPlatformViewsTestMockFlutterPlatformFactory alloc] init]; + flutterPlatformViewsController->RegisterViewFactory( + factory, @"MockFlutterPlatformView", + FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + FlutterResult result = ^(id result) { + }; + flutterPlatformViewsController->OnMethodCall( + [FlutterMethodCall + methodCallWithMethodName:@"create" + arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], + result); + + XCTAssertNotNil(gMockPlatformView); + + UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; + flutterPlatformViewsController->SetFlutterView(flutterView); + // Create embedded view params + flutter::MutatorsStack stack; + // Layer tree always pushes a screen scale factor to the stack + SkMatrix screenScaleMatrix = + SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale); + stack.PushTransform(screenScaleMatrix); + // Push a clip path + SkPath path; + path.addRoundRect(SkRect::MakeXYWH(2, 2, 6, 6), 1, 1); + stack.PushClipPath(path); + // Push a clip rect + SkRect rect = SkRect::MakeXYWH(4, 2, 6, 6); + stack.PushClipRect(rect); + + auto embeddedViewParams = + std::make_unique(screenScaleMatrix, SkSize::Make(10, 10), stack); + + flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); + flutterPlatformViewsController->CompositeWithParams( + 2, flutterPlatformViewsController->GetCompositionParams(2)); + + gMockPlatformView.backgroundColor = UIColor.redColor; + XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); + ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview; + [flutterView addSubview:childClippingView]; + + [flutterView setNeedsLayout]; + [flutterView layoutIfNeeded]; + + /* + clip 1 clip 2 + 2 3 4 5 6 7 8 9 2 3 4 5 6 7 8 9 + 2 / - - - - \ 2 + - - - - + + 3 | | 3 | | + 4 | | 4 | | + 5 | | 5 | | + 6 | | 6 | | + 7 \ - - - - / 7 + - - - - + + + Result should be the intersection of 2 clips + 2 3 4 5 6 7 8 9 + 2 + - - \ + 3 | | + 4 | | + 5 | | + 6 | | + 7 + - - / + */ + CGRect clipping = CGRectMake(4, 2, 4, 6); + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + CGPoint point = CGPointMake(i, j); + int alpha = [self alphaOfPoint:CGPointMake(i, j) onView:flutterView]; + if (i == 7 && (j == 2 || j == 7)) { + // Upper and lower right corners should be partially transparent. + XCTAssert(0 < alpha && alpha < 255); + } else if ( + // left + (i == 4 && j >= 2 && j <= 7) || + // right + (i == 7 && j >= 2 && j <= 7) || + // top + (j == 2 && i >= 4 && i <= 7) || + // bottom + (j == 7 && i >= 4 && i <= 7)) { + // Since we are falling back to software rendering for this case + // The edge pixels can be anti-aliased, so it may not be fully opaque. + XCTAssert(alpha > 127); + } else if ((i == 3 && j >= 1 && j <= 8) || (i == 8 && j >= 1 && j <= 8) || + (j == 1 && i >= 3 && i <= 8) || (j == 8 && i >= 3 && i <= 8)) { + // Since we are falling back to software rendering for this case + // The edge pixels can be anti-aliased, so it may not be fully transparent. + XCTAssert(alpha < 127); + } else if (CGRectContainsPoint(clipping, point)) { + // Other pixels inside clipping should be fully opaque. + XCTAssertEqual(alpha, 255); + } else { + // Pixels outside clipping should be fully transparent. + XCTAssertEqual(alpha, 0); + } + } + } +} + - (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents { flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm index 2a90c27a6a415..5e76654bed179 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm @@ -197,12 +197,14 @@ @interface FlutterClippingMaskView () // information about screen scale. @property(nonatomic) CATransform3D reverseScreenScale; -- (void)addTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix; +- (fml::CFRef)getTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix; @end @implementation FlutterClippingMaskView { - CGMutablePathRef pathSoFar_; + std::vector> paths_; + BOOL containsNonRectPath_; + CGRect rectSoFar_; } - (instancetype)initWithFrame:(CGRect)frame { @@ -213,7 +215,8 @@ - (instancetype)initWithFrame:(CGRect)frame screenScale:(CGFloat)screenScale { if (self = [super initWithFrame:frame]) { self.backgroundColor = UIColor.clearColor; _reverseScreenScale = CATransform3DMakeScale(1 / screenScale, 1 / screenScale, 1); - pathSoFar_ = CGPathCreateMutable(); + rectSoFar_ = self.bounds; + containsNonRectPath_ = NO; } return self; } @@ -227,16 +230,13 @@ - (CAShapeLayer*)shapeLayer { } - (void)reset { - CGPathRelease(pathSoFar_); - pathSoFar_ = CGPathCreateMutable(); + paths_.clear(); + rectSoFar_ = self.bounds; + containsNonRectPath_ = NO; [self shapeLayer].path = nil; [self setNeedsDisplay]; } -- (void)dealloc { - CGPathRelease(pathSoFar_); -} - // In some scenarios, when we add this view as a maskView of the ChildClippingView, iOS added // this view as a subview of the ChildClippingView. // This results this view blocking touch events on the ChildClippingView. @@ -246,16 +246,58 @@ - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event { return NO; } +- (void)drawRect:(CGRect)rect { + // It's hard to compute intersection of arbitrary non-rect paths. + // So we fallback to software rendering. + if (containsNonRectPath_ && paths_.size() > 1) { + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextSaveGState(context); + + // For mask view, only the alpha channel is used. + CGContextSetAlpha(context, 1); + + for (size_t i = 0; i < paths_.size(); i++) { + CGContextAddPath(context, paths_.at(i)); + CGContextClip(context); + } + CGContextFillRect(context, rect); + CGContextRestoreGState(context); + } else { + // Either a single path, or multiple rect paths. + // Use hardware rendering with CAShapeLayer. + [super drawRect:rect]; + if (![self shapeLayer].path) { + if (paths_.size() == 1) { + // A single path, either rect or non-rect. + [self shapeLayer].path = paths_.at(0); + } else { + // Multiple paths, all paths must be rects. + CGPathRef pathSoFar = CGPathCreateWithRect(rectSoFar_, nil); + [self shapeLayer].path = pathSoFar; + CGPathRelease(pathSoFar); + } + } + } +} + - (void)clipRect:(const SkRect&)clipSkRect matrix:(const SkMatrix&)matrix { CGRect clipRect = GetCGRectFromSkRect(clipSkRect); CGPathRef path = CGPathCreateWithRect(clipRect, nil); // The `matrix` is based on the physical pixels, convert it to UIKit points. CATransform3D matrixInPoints = CATransform3DConcat(GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale); - [self addTransformedPath:path matrix:matrixInPoints]; + paths_.push_back([self getTransformedPath:path matrix:matrixInPoints]); + CGAffineTransform affine = [self affineWithMatrix:matrixInPoints]; + // Make sure the rect is not rotated (only translated or scaled). + if (affine.b == 0 && affine.c == 0) { + rectSoFar_ = CGRectIntersection(rectSoFar_, CGRectApplyAffineTransform(clipRect, affine)); + } else { + containsNonRectPath_ = YES; + } } - (void)clipRRect:(const SkRRect&)clipSkRRect matrix:(const SkMatrix&)matrix { + containsNonRectPath_ = YES; CGPathRef pathRef = nullptr; switch (clipSkRRect.getType()) { case SkRRect::kEmpty_Type: { @@ -321,7 +363,7 @@ - (void)clipRRect:(const SkRRect&)clipSkRRect matrix:(const SkMatrix&)matrix { // TODO(cyanglaz): iOS does not seem to support hard edge on CAShapeLayer. It clearly stated that // the CAShaperLayer will be drawn antialiased. Need to figure out a way to do the hard edge // clipping on iOS. - [self addTransformedPath:pathRef matrix:matrixInPoints]; + paths_.push_back([self getTransformedPath:pathRef matrix:matrixInPoints]); } - (void)clipPath:(const SkPath&)path matrix:(const SkMatrix&)matrix { @@ -331,6 +373,7 @@ - (void)clipPath:(const SkPath&)path matrix:(const SkMatrix&)matrix { if (path.isEmpty()) { return; } + containsNonRectPath_ = YES; CGMutablePathRef pathRef = CGPathCreateMutable(); // Loop through all verbs and translate them into CGPath @@ -386,15 +429,20 @@ - (void)clipPath:(const SkPath&)path matrix:(const SkMatrix&)matrix { // The `matrix` is based on the physical pixels, convert it to UIKit points. CATransform3D matrixInPoints = CATransform3DConcat(GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale); - [self addTransformedPath:pathRef matrix:matrixInPoints]; + paths_.push_back([self getTransformedPath:pathRef matrix:matrixInPoints]); +} + +- (CGAffineTransform)affineWithMatrix:(CATransform3D)matrix { + return CGAffineTransformMake(matrix.m11, matrix.m12, matrix.m21, matrix.m22, matrix.m41, + matrix.m42); } -- (void)addTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix { - CGAffineTransform affine = - CGAffineTransformMake(matrix.m11, matrix.m12, matrix.m21, matrix.m22, matrix.m41, matrix.m42); - CGPathAddPath(pathSoFar_, &affine, path); - [self shapeLayer].path = pathSoFar_; +- (fml::CFRef)getTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix { + CGAffineTransform affine = [self affineWithMatrix:matrix]; + CGPathRef transformedPath = CGPathCreateCopyByTransformingPath(path, &affine); + CGPathRelease(path); + return fml::CFRef(transformedPath); } @end diff --git a/testing/scenario_app/bin/run_ios_tests.dart b/testing/scenario_app/bin/run_ios_tests.dart index 5b97f971d8dfb..32a9d5b1db1c4 100644 --- a/testing/scenario_app/bin/run_ios_tests.dart +++ b/testing/scenario_app/bin/run_ios_tests.dart @@ -358,14 +358,23 @@ final _skipTestsForImpeller = [ 'ScenariosUITests/MultiplePlatformViewsTest/testPlatformView', 'ScenariosUITests/NonFullScreenFlutterViewPlatformViewUITests/testPlatformView', 'ScenariosUITests/PlatformViewMutationClipPathTests/testPlatformView', + 'ScenariosUITests/PlatformViewMutationClipPathMultipleClipsTests/testPlatformView', 'ScenariosUITests/PlatformViewMutationClipPathWithTransformTests/testPlatformView', + 'ScenariosUITests/PlatformViewMutationClipPathWithTransformMultipleClipsTests/testPlatformView', 'ScenariosUITests/PlatformViewMutationClipRectAfterMovedTests/testPlatformView', + 'ScenariosUITests/PlatformViewMutationClipRectAfterMovedMultipleClipsTests/testPlatformView', 'ScenariosUITests/PlatformViewMutationClipRectTests/testPlatformView', + 'ScenariosUITests/PlatformViewMutationClipRectMultipleClipsTests/testPlatformView', 'ScenariosUITests/PlatformViewMutationClipRectWithTransformTests/testPlatformView', + 'ScenariosUITests/PlatformViewMutationClipRectWithTransformMultipleClipsTests/testPlatformView', 'ScenariosUITests/PlatformViewMutationClipRRectTests/testPlatformView', + 'ScenariosUITests/PlatformViewMutationClipRRectMultipleClipsTests/testPlatformView', 'ScenariosUITests/PlatformViewMutationClipRRectWithTransformTests/testPlatformView', + 'ScenariosUITests/PlatformViewMutationClipRRectWithTransformMultipleClipsTests/testPlatformView', 'ScenariosUITests/PlatformViewMutationLargeClipRRectTests/testPlatformView', + 'ScenariosUITests/PlatformViewMutationLargeClipRRectMultipleClipsTests/testPlatformView', 'ScenariosUITests/PlatformViewMutationLargeClipRRectWithTransformTests/testPlatformView', + 'ScenariosUITests/PlatformViewMutationLargeClipRRectWithTransformMultipleClipsTests/testPlatformView', 'ScenariosUITests/PlatformViewMutationOpacityTests/testPlatformView', 'ScenariosUITests/PlatformViewMutationTransformTests/testPlatformView', 'ScenariosUITests/PlatformViewRotation/testPlatformView', @@ -374,8 +383,11 @@ final _skipTestsForImpeller = [ 'ScenariosUITests/PlatformViewWithOtherBackdropFilterTests/testPlatformView', 'ScenariosUITests/RenderingSelectionTest/testSoftwareRendering', 'ScenariosUITests/TwoPlatformViewClipPathTests/testPlatformView', + 'ScenariosUITests/TwoPlatformViewClipPathMultipleClipsTests/testPlatformView', 'ScenariosUITests/TwoPlatformViewClipRectTests/testPlatformView', + 'ScenariosUITests/TwoPlatformViewClipRectMultipleClipsTests/testPlatformView', 'ScenariosUITests/TwoPlatformViewClipRRectTests/testPlatformView', + 'ScenariosUITests/TwoPlatformViewClipRRectMultipleClipsTests/testPlatformView', 'ScenariosUITests/TwoPlatformViewsWithOtherBackDropFilterTests/testPlatformView', 'ScenariosUITests/UnobstructedPlatformViewTests/testMultiplePlatformViewsWithOverlays', ].map((name) => '-skip-testing:$name').toList(); diff --git a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj index 29355ef4a5872..7f8c0bac1756a 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj +++ b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj @@ -73,6 +73,18 @@ 68C9D8092AD9B6C800DF9D79 /* golden_darwin_system_font_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 68C9D8082AD9B6C800DF9D79 /* golden_darwin_system_font_iPhone SE (3rd generation)_17.0_simulator.png */; }; 68D4017D2564859300ECD91A /* ContinuousTexture.m in Sources */ = {isa = PBXBuildFile; fileRef = 68D4017C2564859300ECD91A /* ContinuousTexture.m */; }; 68D93AEE2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 68D93AED2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png */; }; + E0D5A1DE2C8115F7003BB890 /* golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D52C8115F7003BB890 /* golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; }; + E0D5A1DF2C8115F7003BB890 /* golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D22C8115F7003BB890 /* golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; }; + E0D5A1E02C8115F7003BB890 /* golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D62C8115F7003BB890 /* golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; }; + E0D5A1E12C8115F7003BB890 /* golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D82C8115F7003BB890 /* golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; }; + E0D5A1E22C8115F7003BB890 /* golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1DA2C8115F7003BB890 /* golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; }; + E0D5A1E32C8115F7003BB890 /* golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1DB2C8115F7003BB890 /* golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; }; + E0D5A1E42C8115F7003BB890 /* golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1DD2C8115F7003BB890 /* golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; }; + E0D5A1E52C8115F7003BB890 /* golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1DC2C8115F7003BB890 /* golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; }; + E0D5A1E62C8115F7003BB890 /* golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D72C8115F7003BB890 /* golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; }; + E0D5A1E72C8115F7003BB890 /* golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D32C8115F7003BB890 /* golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; }; + E0D5A1E82C8115F7003BB890 /* golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D92C8115F7003BB890 /* golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; }; + E0D5A1E92C8115F7003BB890 /* golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = E0D5A1D42C8115F7003BB890 /* golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */; }; F26F15B8268B6B5600EC54D3 /* iPadGestureTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F26F15B7268B6B5500EC54D3 /* iPadGestureTests.m */; }; /* End PBXBuildFile section */ @@ -249,6 +261,18 @@ 68D4017B2564859300ECD91A /* ContinuousTexture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContinuousTexture.h; sourceTree = ""; }; 68D4017C2564859300ECD91A /* ContinuousTexture.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ContinuousTexture.m; sourceTree = ""; }; 68D93AED2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = ""; }; + E0D5A1D22C8115F7003BB890 /* golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = ""; }; + E0D5A1D32C8115F7003BB890 /* golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = ""; }; + E0D5A1D42C8115F7003BB890 /* golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = ""; }; + E0D5A1D52C8115F7003BB890 /* golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = ""; }; + E0D5A1D62C8115F7003BB890 /* golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = ""; }; + E0D5A1D72C8115F7003BB890 /* golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = ""; }; + E0D5A1D82C8115F7003BB890 /* golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = ""; }; + E0D5A1D92C8115F7003BB890 /* golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = ""; }; + E0D5A1DA2C8115F7003BB890 /* golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = ""; }; + E0D5A1DB2C8115F7003BB890 /* golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = ""; }; + E0D5A1DC2C8115F7003BB890 /* golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = ""; }; + E0D5A1DD2C8115F7003BB890 /* golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png"; sourceTree = ""; }; F26F15B7268B6B5500EC54D3 /* iPadGestureTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iPadGestureTests.m; sourceTree = ""; }; F72114B628EF99F500184A2D /* Info_Impeller.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info_Impeller.plist; sourceTree = ""; }; /* End PBXFileReference section */ @@ -433,6 +457,18 @@ 684FFF7B29F9C10700281002 /* golden_platform_view_with_other_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png */, 684FFF7A29F9C10700281002 /* golden_spawn_engine_works_iPhone SE (3rd generation)_17.0_simulator.png */, 684FFF6E29F9C10400281002 /* golden_two_platform_views_with_other_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png */, + E0D5A1D22C8115F7003BB890 /* golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */, + E0D5A1D32C8115F7003BB890 /* golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */, + E0D5A1D42C8115F7003BB890 /* golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */, + E0D5A1D52C8115F7003BB890 /* golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */, + E0D5A1D62C8115F7003BB890 /* golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */, + E0D5A1D72C8115F7003BB890 /* golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */, + E0D5A1D82C8115F7003BB890 /* golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */, + E0D5A1D92C8115F7003BB890 /* golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */, + E0D5A1DA2C8115F7003BB890 /* golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */, + E0D5A1DB2C8115F7003BB890 /* golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */, + E0D5A1DC2C8115F7003BB890 /* golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */, + E0D5A1DD2C8115F7003BB890 /* golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png */, ); name = Goldens; sourceTree = ""; @@ -623,6 +659,18 @@ 684FFF8729F9C10700281002 /* golden_platform_view_multiple_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, 68D93AEE2A46097E0054AB6D /* golden_platform_view_with_negative_backdrop_filter_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, 3BFD97202A990CF50094F51B /* golden_bogus_font_text_impeller_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, + E0D5A1DE2C8115F7003BB890 /* golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, + E0D5A1DF2C8115F7003BB890 /* golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, + E0D5A1E02C8115F7003BB890 /* golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, + E0D5A1E12C8115F7003BB890 /* golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, + E0D5A1E22C8115F7003BB890 /* golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, + E0D5A1E32C8115F7003BB890 /* golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, + E0D5A1E42C8115F7003BB890 /* golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, + E0D5A1E52C8115F7003BB890 /* golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, + E0D5A1E62C8115F7003BB890 /* golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, + E0D5A1E72C8115F7003BB890 /* golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, + E0D5A1E82C8115F7003BB890 /* golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, + E0D5A1E92C8115F7003BB890 /* golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, 68C9D8092AD9B6C800DF9D79 /* golden_darwin_system_font_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, 684FFF8D29F9C10700281002 /* golden_platform_view_large_cliprrect_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, 684FFF8329F9C10700281002 /* golden_platform_view_transform_iPhone SE (3rd generation)_17.0_simulator.png in Resources */, diff --git a/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m b/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m index 47188144fcca7..c7f86cf200c2b 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m +++ b/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m @@ -60,14 +60,27 @@ - (BOOL)application:(UIApplication*)application @"--platform-view-multiple-background-foreground" : @"platform_view_multiple_background_foreground", @"--platform-view-cliprect" : @"platform_view_cliprect", + @"--platform-view-cliprect-multiple-clips" : @"platform_view_cliprect_multiple_clips", @"--platform-view-cliprrect" : @"platform_view_cliprrect", + @"--platform-view-cliprrect-multiple-clips" : @"platform_view_cliprrect_multiple_clips", @"--platform-view-large-cliprrect" : @"platform_view_large_cliprrect", + @"--platform-view-large-cliprrect-multiple-clips" : + @"platform_view_large_cliprrect_multiple_clips", @"--platform-view-clippath" : @"platform_view_clippath", + @"--platform-view-clippath-multiple-clips" : @"platform_view_clippath_multiple_clips", @"--platform-view-cliprrect-with-transform" : @"platform_view_cliprrect_with_transform", + @"--platform-view-cliprrect-with-transform-multiple-clips" : + @"platform_view_cliprrect_with_transform_multiple_clips", @"--platform-view-large-cliprrect-with-transform" : @"platform_view_large_cliprrect_with_transform", + @"--platform-view-large-cliprrect-with-transform-multiple-clips" : + @"platform_view_large_cliprrect_with_transform_multiple_clips", @"--platform-view-cliprect-with-transform" : @"platform_view_cliprect_with_transform", + @"--platform-view-cliprect-with-transform-multiple-clips" : + @"platform_view_cliprect_with_transform_multiple_clips", @"--platform-view-clippath-with-transform" : @"platform_view_clippath_with_transform", + @"--platform-view-clippath-with-transform-multiple-clips" : + @"platform_view_clippath_with_transform_multiple_clips", @"--platform-view-transform" : @"platform_view_transform", @"--platform-view-opacity" : @"platform_view_opacity", @"--platform-view-with-other-backdrop-filter" : @"platform_view_with_other_backdrop_filter", @@ -91,10 +104,18 @@ - (BOOL)application:(UIApplication*)application @"--pointer-events" : @"pointer_events", @"--platform-view-scrolling-under-widget" : @"platform_view_scrolling_under_widget", @"--platform-views-with-clips-scrolling" : @"platform_views_with_clips_scrolling", + @"--platform-views-with-clips-scrolling-multiple-clips" : + @"platform_views_with_clips_scrolling_multiple_clips", @"--platform-view-cliprect-after-moved" : @"platform_view_cliprect_after_moved", + @"--platform-view-cliprect-after-moved-multiple-clips" : + @"platform_view_cliprect_after_moved_multiple_clips", @"--two-platform-view-clip-rect" : @"two_platform_view_clip_rect", + @"--two-platform-view-clip-rect-multiple-clips" : @"two_platform_view_clip_rect_multiple_clips", @"--two-platform-view-clip-rrect" : @"two_platform_view_clip_rrect", + @"--two-platform-view-clip-rrect-multiple-clips" : + @"two_platform_view_clip_rrect_multiple_clips", @"--two-platform-view-clip-path" : @"two_platform_view_clip_path", + @"--two-platform-view-clip-path-multiple-clips" : @"two_platform_view_clip_path_multiple_clips", @"--darwin-system-font" : @"darwin_system_font", }; __block NSString* flutterViewControllerTestName = nil; diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenTestManager.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenTestManager.m index ac55da74642bb..a4650a5d3616c 100644 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenTestManager.m +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenTestManager.m @@ -29,14 +29,27 @@ - (instancetype)initWithLaunchArg:(NSString*)launchArg { @"--platform-view-multiple-background-foreground" : @"platform_view_multiple_background_foreground", @"--platform-view-cliprect" : @"platform_view_cliprect", + @"--platform-view-cliprect-multiple-clips" : @"platform_view_cliprect_multiple_clips", @"--platform-view-cliprrect" : @"platform_view_cliprrect", + @"--platform-view-cliprrect-multiple-clips" : @"platform_view_cliprrect_multiple_clips", @"--platform-view-large-cliprrect" : @"platform_view_large_cliprrect", + @"--platform-view-large-cliprrect-multiple-clips" : + @"platform_view_large_cliprrect_multiple_clips", @"--platform-view-clippath" : @"platform_view_clippath", + @"--platform-view-clippath-multiple-clips" : @"platform_view_clippath_multiple_clips", @"--platform-view-cliprrect-with-transform" : @"platform_view_cliprrect_with_transform", + @"--platform-view-cliprrect-with-transform-multiple-clips" : + @"platform_view_cliprrect_with_transform_multiple_clips", @"--platform-view-large-cliprrect-with-transform" : @"platform_view_large_cliprrect_with_transform", + @"--platform-view-large-cliprrect-with-transform-multiple-clips" : + @"platform_view_large_cliprrect_with_transform_multiple_clips", @"--platform-view-cliprect-with-transform" : @"platform_view_cliprect_with_transform", + @"--platform-view-cliprect-with-transform-multiple-clips" : + @"platform_view_cliprect_with_transform_multiple_clips", @"--platform-view-clippath-with-transform" : @"platform_view_clippath_with_transform", + @"--platform-view-clippath-with-transform-multiple-clips" : + @"platform_view_clippath_with_transform_multiple_clips", @"--platform-view-transform" : @"platform_view_transform", @"--platform-view-opacity" : @"platform_view_opacity", @"--platform-view-with-other-backdrop-filter" : @"platform_view_with_other_backdrop_filter", @@ -50,9 +63,17 @@ - (instancetype)initWithLaunchArg:(NSString*)launchArg { @"--bogus-font-text" : @"bogus_font_text", @"--spawn-engine-works" : @"spawn_engine_works", @"--platform-view-cliprect-after-moved" : @"platform_view_cliprect_after_moved", + @"--platform-view-cliprect-after-moved-multiple-clips" : + @"platform_view_cliprect_after_moved_multiple_clips", @"--two-platform-view-clip-rect" : @"two_platform_view_clip_rect", + @"--two-platform-view-clip-rect-multiple-clips" : + @"two_platform_view_clip_rect_multiple_clips", @"--two-platform-view-clip-rrect" : @"two_platform_view_clip_rrect", + @"--two-platform-view-clip-rrect-multiple-clips" : + @"two_platform_view_clip_rrect_multiple_clips", @"--two-platform-view-clip-path" : @"two_platform_view_clip_path", + @"--two-platform-view-clip-path-multiple-clips" : + @"two_platform_view_clip_path_multiple_clips", @"--app-extension" : @"app_extension", @"--darwin-system-font" : @"darwin_system_font", }; diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewUITests.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewUITests.m index 7415a51717ddb..156a2dbe76c24 100644 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewUITests.m +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewUITests.m @@ -98,6 +98,25 @@ - (void)testPlatformView { @end +// Clip Rect Tests +@interface PlatformViewMutationClipRectWithMultiupleClipsTests : GoldenPlatformViewTests + +@end + +@implementation PlatformViewMutationClipRectWithMultiupleClipsTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = + [[GoldenTestManager alloc] initWithLaunchArg:@"--platform-view-cliprect-multiple-clips"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + @interface PlatformViewMutationClipRectAfterMovedTests : GoldenPlatformViewTests @end @@ -128,6 +147,36 @@ - (void)testPlatformView { @end +@interface PlatformViewMutationClipRectAfterMovedMultipleClipsTests : GoldenPlatformViewTests + +@end + +@implementation PlatformViewMutationClipRectAfterMovedMultipleClipsTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = [[GoldenTestManager alloc] + initWithLaunchArg:@"--platform-view-cliprect-after-moved-multiple-clips"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + // This test needs to wait for several frames for the PlatformView to settle to + // the correct position. The PlatformView accessiblity is set to platform_view[10000] when it is + // ready. + XCUIElement* element = self.application.otherElements[@"platform_view[10000]"]; + BOOL exists = [element waitForExistenceWithTimeout:kSecondsToWaitForPlatformView]; + if (!exists) { + XCTFail(@"It took longer than %@ second to find the platform view." + @"There might be issues with the platform view's construction," + @"or with how the scenario is built.", + @(kSecondsToWaitForPlatformView)); + } + + [self checkPlatformViewGolden]; +} + +@end + @interface PlatformViewMutationClipRRectTests : GoldenPlatformViewTests @end @@ -146,6 +195,24 @@ - (void)testPlatformView { @end +@interface PlatformViewMutationClipRRectMultipleClipsTests : GoldenPlatformViewTests + +@end + +@implementation PlatformViewMutationClipRRectMultipleClipsTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = + [[GoldenTestManager alloc] initWithLaunchArg:@"--platform-view-cliprrect-multiple-clips"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + @interface PlatformViewMutationLargeClipRRectTests : GoldenPlatformViewTests @end @@ -164,6 +231,24 @@ - (void)testPlatformView { @end +@interface PlatformViewMutationLargeClipRRectMultipleClipsTests : GoldenPlatformViewTests + +@end + +@implementation PlatformViewMutationLargeClipRRectMultipleClipsTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = [[GoldenTestManager alloc] + initWithLaunchArg:@"--platform-view-large-cliprrect-multiple-clips"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + @interface PlatformViewMutationClipPathTests : GoldenPlatformViewTests @end @@ -182,6 +267,24 @@ - (void)testPlatformView { @end +@interface PlatformViewMutationClipPathMultipleClipsTests : GoldenPlatformViewTests + +@end + +@implementation PlatformViewMutationClipPathMultipleClipsTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = + [[GoldenTestManager alloc] initWithLaunchArg:@"--platform-view-clippath-multiple-clips"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + @interface PlatformViewMutationClipRectWithTransformTests : GoldenPlatformViewTests @end @@ -200,6 +303,24 @@ - (void)testPlatformView { @end +@interface PlatformViewMutationClipRectWithTransformMultipleClipsTests : GoldenPlatformViewTests + +@end + +@implementation PlatformViewMutationClipRectWithTransformMultipleClipsTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = [[GoldenTestManager alloc] + initWithLaunchArg:@"--platform-view-cliprect-with-transform-multiple-clips"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + @interface PlatformViewMutationClipRRectWithTransformTests : GoldenPlatformViewTests @end @@ -218,6 +339,24 @@ - (void)testPlatformView { @end +@interface PlatformViewMutationClipRRectWithTransformMultipleClipsTests : GoldenPlatformViewTests + +@end + +@implementation PlatformViewMutationClipRRectWithTransformMultipleClipsTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = [[GoldenTestManager alloc] + initWithLaunchArg:@"--platform-view-cliprrect-with-transform-multiple-clips"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + @interface PlatformViewMutationLargeClipRRectWithTransformTests : GoldenPlatformViewTests @end @@ -236,6 +375,25 @@ - (void)testPlatformView { @end +@interface PlatformViewMutationLargeClipRRectWithTransformMultipleClipsTests + : GoldenPlatformViewTests + +@end + +@implementation PlatformViewMutationLargeClipRRectWithTransformMultipleClipsTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = [[GoldenTestManager alloc] + initWithLaunchArg:@"--platform-view-large-cliprrect-with-transform-multiple-clips"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + @interface PlatformViewMutationClipPathWithTransformTests : GoldenPlatformViewTests @end @@ -254,6 +412,24 @@ - (void)testPlatformView { @end +@interface PlatformViewMutationClipPathWithTransformMultipleClipsTests : GoldenPlatformViewTests + +@end + +@implementation PlatformViewMutationClipPathWithTransformMultipleClipsTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = [[GoldenTestManager alloc] + initWithLaunchArg:@"--platform-view-clippath-with-transform-multiple-clips"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + @interface TwoPlatformViewClipRectTests : GoldenPlatformViewTests @end @@ -272,6 +448,24 @@ - (void)testPlatformView { @end +@interface TwoPlatformViewClipRectMultipleClipsTests : GoldenPlatformViewTests + +@end + +@implementation TwoPlatformViewClipRectMultipleClipsTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = + [[GoldenTestManager alloc] initWithLaunchArg:@"--two-platform-view-clip-rect-multiple-clips"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + @interface TwoPlatformViewClipRRectTests : GoldenPlatformViewTests @end @@ -290,6 +484,24 @@ - (void)testPlatformView { @end +@interface TwoPlatformViewClipRRectMultipleClipsTests : GoldenPlatformViewTests + +@end + +@implementation TwoPlatformViewClipRRectMultipleClipsTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = [[GoldenTestManager alloc] + initWithLaunchArg:@"--two-platform-view-clip-rrect-multiple-clips"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + @interface TwoPlatformViewClipPathTests : GoldenPlatformViewTests @end @@ -308,6 +520,24 @@ - (void)testPlatformView { @end +@interface TwoPlatformViewClipPathMultipleClipsTests : GoldenPlatformViewTests + +@end + +@implementation TwoPlatformViewClipPathMultipleClipsTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = + [[GoldenTestManager alloc] initWithLaunchArg:@"--two-platform-view-clip-path-multiple-clips"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + @interface PlatformViewMutationTransformTests : GoldenPlatformViewTests @end @@ -528,3 +758,41 @@ - (void)testPlatformViewsWithClipsScrolling { } @end + +@interface PlatformViewWithClipsScrollingMultipleClips : XCTestCase + +@end + +@implementation PlatformViewWithClipsScrollingMultipleClips + +- (void)setUp { + [super setUp]; + self.continueAfterFailure = NO; +} + +- (void)testPlatformViewsWithClipsScrolling { + XCUIApplication* app = [[XCUIApplication alloc] init]; + app.launchArguments = @[ + @"--platform-views-with-clips-scrolling", @"platform_views_with_clips_scrolling-multiple-clips" + ]; + [app launch]; + + XCUIElement* platformView = app.textViews.firstMatch; + BOOL exists = [platformView waitForExistenceWithTimeout:kSecondsToWaitForPlatformView]; + if (!exists) { + XCTFail(@"It took longer than %@ second to find the platform view." + @"There might be issues with the platform view's construction," + @"or with how the scenario is built.", + @(kSecondsToWaitForPlatformView)); + } + + // Wait and let the scenario app scroll a bit. + XCTWaiterResult waitResult = [XCTWaiter + waitForExpectations:@[ [[XCTestExpectation alloc] initWithDescription:@"Wait for 5 seconds"] ] + timeout:5]; + // If the waiter is not interrupted, we know the app is in a valid state after timeout, thus the + // test passes. + XCTAssert(waitResult != XCTWaiterResultInterrupted); +} + +@end diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png new file mode 100644 index 0000000000000..0215aa6f0aa76 Binary files /dev/null and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png new file mode 100644 index 0000000000000..0992ec0ea909f Binary files /dev/null and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png new file mode 100644 index 0000000000000..a2e9b069eb020 Binary files /dev/null and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_after_moved_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png new file mode 100644 index 0000000000000..2b66feb9eed21 Binary files /dev/null and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png new file mode 100644 index 0000000000000..7504b1f0257c2 Binary files /dev/null and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png new file mode 100644 index 0000000000000..11cbf55d18f92 Binary files /dev/null and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png new file mode 100644 index 0000000000000..c5411cd124336 Binary files /dev/null and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png new file mode 100644 index 0000000000000..23427f2057b42 Binary files /dev/null and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_large_cliprrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png new file mode 100644 index 0000000000000..1349b56cbd511 Binary files /dev/null and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_large_cliprrect_with_transform_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png new file mode 100644 index 0000000000000..27dbbccbea8c4 Binary files /dev/null and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_two_platform_view_clip_path_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png new file mode 100644 index 0000000000000..e3a9337e9b9f5 Binary files /dev/null and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_two_platform_view_clip_rect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png new file mode 100644 index 0000000000000..cb51fc70f4777 Binary files /dev/null and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_two_platform_view_clip_rrect_multiple_clips_iPhone SE (3rd generation)_17.0_simulator.png differ diff --git a/testing/scenario_app/lib/src/platform_view.dart b/testing/scenario_app/lib/src/platform_view.dart index 5d1099a522350..241317f3213af 100644 --- a/testing/scenario_app/lib/src/platform_view.dart +++ b/testing/scenario_app/lib/src/platform_view.dart @@ -680,6 +680,33 @@ class PlatformViewClipRectScenario extends Scenario with _BasePlatformViewScenar } } +/// Platform view with clip rect, with multiple clips. +class PlatformViewClipRectMultipleClipsScenario extends Scenario with _BasePlatformViewScenarioMixin { + /// Constructs a platform view with clip rect scenario. + PlatformViewClipRectMultipleClipsScenario( + super.view, { + required this.id, + }); + + /// The platform view identifier. + final int id; + + @override + void onBeginFrame(Duration duration) { + final SceneBuilder builder = SceneBuilder() + ..pushClipRect(const Rect.fromLTRB(100, 100, 400, 400)) + ..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600)); + + addPlatformView( + id, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + ); + + finishBuilder(builder); + } +} + /// Platform view with clip rect then the PlatformView is moved for 10 frames. /// /// The clip rect moves with the same transform matrix with the PlatformView. @@ -735,6 +762,64 @@ class PlatformViewClipRectAfterMovedScenario extends Scenario with _BasePlatform } } + +/// Platform view with clip rect with multiple clips then the PlatformView is moved for 10 frames. +/// +/// The clip rect moves with the same transform matrix with the PlatformView. +class PlatformViewClipRectAfterMovedMultipleClipsScenario extends Scenario with _BasePlatformViewScenarioMixin { + /// Constructs a platform view with clip rect scenario. + PlatformViewClipRectAfterMovedMultipleClipsScenario( + super.view, { + required this.id, + }); + + /// The platform view identifier. + final int id; + + int _numberOfFrames = 0; + + double _y = 100.0; + + @override + void onBeginFrame(Duration duration) { + final Matrix4 translateMatrix = Matrix4.identity()..translate(0.0, _y); + final SceneBuilder builder = SceneBuilder() + ..pushTransform(translateMatrix.storage) + ..pushClipRect(const Rect.fromLTRB(100, 100, 400, 400)) + ..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600)); + + addPlatformView( + _numberOfFrames == 10? 10000: id, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + ); + + // Add a translucent rect that has the same size of PlatformView. + final PictureRecorder recorder = PictureRecorder(); + final Canvas canvas = Canvas(recorder); + canvas.drawRect( + const Rect.fromLTWH(0, 0, 500, 500), + Paint()..color = const Color(0x22FF0000), + ); + final Picture picture = recorder.endRecording(); + builder.addPicture(Offset.zero, picture); + + finishBuilder(builder); + super.onBeginFrame(duration); + } + + @override + void onDrawFrame() { + if (_numberOfFrames < 10) { + _numberOfFrames ++; + _y -= 10; + view.platformDispatcher.scheduleFrame(); + } + super.onDrawFrame(); + } +} + + /// Platform view with clip rrect. class PlatformViewClipRRectScenario extends PlatformViewScenario { /// Constructs a platform view with clip rrect scenario. @@ -768,6 +853,40 @@ class PlatformViewClipRRectScenario extends PlatformViewScenario { } } +/// Platform view with clip rrect, with multiple clips. +class PlatformViewClipRRectMultipleClipsScenario extends PlatformViewScenario { + /// Constructs a platform view with clip rrect scenario. + PlatformViewClipRRectMultipleClipsScenario( + super.view, { + super.id = 0, + }); + + @override + void onBeginFrame(Duration duration) { + final SceneBuilder builder = SceneBuilder(); + builder..pushClipRRect( + RRect.fromLTRBAndCorners( + 100, + 100, + 400, + 400, + topLeft: const Radius.circular(15), + topRight: const Radius.circular(50), + bottomLeft: const Radius.circular(50), + ), + ) + ..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600)); + + addPlatformView( + id, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + ); + + finishBuilder(builder); + } +} + /// Platform view with clip rrect. /// The bounding rect of the rrect is the same as PlatformView and only the corner radii clips the PlatformView. class PlatformViewLargeClipRRectScenario extends PlatformViewScenario { @@ -802,6 +921,41 @@ class PlatformViewLargeClipRRectScenario extends PlatformViewScenario { } } +/// Platform view with clip rrect, with multiple clips. +/// The bounding rect of the rrect is the same as PlatformView and only the corner radii clips the PlatformView. +class PlatformViewLargeClipRRectMultipleClipsScenario extends PlatformViewScenario { + /// Constructs a platform view with large clip rrect scenario. + PlatformViewLargeClipRRectMultipleClipsScenario( + super.view, { + super.id = 0, + }); + + @override + void onBeginFrame(Duration duration) { + final SceneBuilder builder = SceneBuilder(); + builder..pushClipRRect( + RRect.fromLTRBAndCorners( + 0, + 0, + 500, + 500, + topLeft: const Radius.circular(15), + topRight: const Radius.circular(50), + bottomLeft: const Radius.circular(50), + ), + ) + ..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600)); + + addPlatformView( + id, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + ); + + finishBuilder(builder); + } +} + /// Platform view with clip path. class PlatformViewClipPathScenario extends PlatformViewScenario { /// Constructs a platform view with clip path scenario. @@ -829,6 +983,35 @@ class PlatformViewClipPathScenario extends PlatformViewScenario { } } +/// Platform view with clip path, with multiple clips. +class PlatformViewClipPathMultipleClipsScenario extends PlatformViewScenario { + /// Constructs a platform view with clip path scenario. + PlatformViewClipPathMultipleClipsScenario( + super.view, { + super.id = 0, + }); + + @override + void onBeginFrame(Duration duration) { + final Path path = Path() + ..moveTo(100, 100) + ..quadraticBezierTo(50, 250, 100, 400) + ..lineTo(350, 400) + ..cubicTo(400, 300, 300, 200, 350, 100) + ..close(); + + final SceneBuilder builder = SceneBuilder()..pushClipPath(path) + ..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600)); + + addPlatformView( + id, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + ); + finishBuilder(builder); + } +} + /// Platform view with clip rect after transformed. class PlatformViewClipRectWithTransformScenario extends PlatformViewScenario { /// Constructs a platform view with clip rect with transform scenario. @@ -867,6 +1050,45 @@ class PlatformViewClipRectWithTransformScenario extends PlatformViewScenario { } } +/// Platform view with clip rect after transformed, with multiple clips. +class PlatformViewClipRectWithTransformMultipleClipsScenario extends PlatformViewScenario { + /// Constructs a platform view with clip rect with transform scenario. + PlatformViewClipRectWithTransformMultipleClipsScenario( + super.view, { + super.id = 0, + }); + + @override + void onBeginFrame(Duration duration) { + final Matrix4 matrix4 = Matrix4.identity() + ..rotateZ(1) + ..scale(0.5, 0.5, 1.0) + ..translate(1000.0, 100.0); + + final SceneBuilder builder = SceneBuilder()..pushTransform(matrix4.storage); + builder..pushClipRect(const Rect.fromLTRB(100, 100, 400, 400)) + ..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600)); + + addPlatformView( + id, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + ); + + // Add a translucent rect that has the same size of PlatformView. + final PictureRecorder recorder = PictureRecorder(); + final Canvas canvas = Canvas(recorder); + canvas.drawRect( + const Rect.fromLTWH(0, 0, 500, 500), + Paint()..color = const Color(0x22FF0000), + ); + final Picture picture = recorder.endRecording(); + builder.addPicture(Offset.zero, picture); + + finishBuilder(builder); + } +} + /// Platform view with clip rrect after transformed. class PlatformViewClipRRectWithTransformScenario extends PlatformViewScenario { /// Constructs a platform view with clip rrect with transform scenario. @@ -914,6 +1136,55 @@ class PlatformViewClipRRectWithTransformScenario extends PlatformViewScenario { } } +/// Platform view with clip rrect after transformed, with multiple clips. +class PlatformViewClipRRectWithTransformMultipleClipsScenario extends PlatformViewScenario { + /// Constructs a platform view with clip rrect with transform scenario. + PlatformViewClipRRectWithTransformMultipleClipsScenario( + super.view, { + super.id = 0, + }); + + @override + void onBeginFrame(Duration duration) { + final Matrix4 matrix4 = Matrix4.identity() + ..rotateZ(1) + ..scale(0.5, 0.5, 1.0) + ..translate(1000.0, 100.0); + + final SceneBuilder builder = SceneBuilder()..pushTransform(matrix4.storage); + builder..pushClipRRect( + RRect.fromLTRBAndCorners( + 100, + 100, + 400, + 400, + topLeft: const Radius.circular(15), + topRight: const Radius.circular(50), + bottomLeft: const Radius.circular(50), + ), + ) + ..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600)); + + addPlatformView( + id, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + ); + + // Add a translucent rect that has the same size of PlatformView. + final PictureRecorder recorder = PictureRecorder(); + final Canvas canvas = Canvas(recorder); + canvas.drawRect( + const Rect.fromLTWH(0, 0, 500, 500), + Paint()..color = const Color(0x22FF0000), + ); + final Picture picture = recorder.endRecording(); + builder.addPicture(Offset.zero, picture); + + finishBuilder(builder); + } +} + /// Platform view with clip rrect after transformed. /// The bounding rect of the rrect is the same as PlatformView and only the corner radii clips the PlatformView. class PlatformViewLargeClipRRectWithTransformScenario extends PlatformViewScenario { @@ -955,62 +1226,260 @@ class PlatformViewLargeClipRRectWithTransformScenario extends PlatformViewScenar const Rect.fromLTWH(0, 0, 500, 500), Paint()..color = const Color(0x22FF0000), ); - final Picture picture = recorder.endRecording(); - builder.addPicture(Offset.zero, picture); + final Picture picture = recorder.endRecording(); + builder.addPicture(Offset.zero, picture); + + finishBuilder(builder); + } +} + +/// Platform view with clip rrect after transformed, with multiple clips. +/// The bounding rect of the rrect is the same as PlatformView and only the corner radii clips the PlatformView. +class PlatformViewLargeClipRRectWithTransformMultipleClipsScenario extends PlatformViewScenario { + /// Constructs a platform view with large clip rrect with transform scenario. + PlatformViewLargeClipRRectWithTransformMultipleClipsScenario( + super.view, { + super.id = 0, + }); + + @override + void onBeginFrame(Duration duration) { + final Matrix4 matrix4 = Matrix4.identity() + ..rotateZ(1) + ..scale(0.5, 0.5, 1.0) + ..translate(1000.0, 100.0); + + final SceneBuilder builder = SceneBuilder()..pushTransform(matrix4.storage); + builder..pushClipRRect( + RRect.fromLTRBAndCorners( + 0, + 0, + 500, + 500, + topLeft: const Radius.circular(15), + topRight: const Radius.circular(50), + bottomLeft: const Radius.circular(50), + ), + ) + ..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600)); + + addPlatformView( + id, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + ); + + // Add a translucent rect that has the same size of PlatformView. + final PictureRecorder recorder = PictureRecorder(); + final Canvas canvas = Canvas(recorder); + canvas.drawRect( + const Rect.fromLTWH(0, 0, 500, 500), + Paint()..color = const Color(0x22FF0000), + ); + final Picture picture = recorder.endRecording(); + builder.addPicture(Offset.zero, picture); + + finishBuilder(builder); + } +} + +/// Platform view with clip path after transformed. +class PlatformViewClipPathWithTransformScenario extends PlatformViewScenario { + /// Constructs a platform view with clip path with transform scenario. + PlatformViewClipPathWithTransformScenario( + super.view, { + super.id = 0, + }); + + @override + void onBeginFrame(Duration duration) { + final Matrix4 matrix4 = Matrix4.identity() + ..rotateZ(1) + ..scale(0.5, 0.5, 1.0) + ..translate(1000.0, 100.0); + + final SceneBuilder builder = SceneBuilder()..pushTransform(matrix4.storage); + final Path path = Path() + ..moveTo(100, 100) + ..quadraticBezierTo(50, 250, 100, 400) + ..lineTo(350, 400) + ..cubicTo(400, 300, 300, 200, 350, 100) + ..close(); + + builder.pushClipPath(path); + addPlatformView( + id, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + ); + + // Add a translucent rect that has the same size of PlatformView. + final PictureRecorder recorder = PictureRecorder(); + final Canvas canvas = Canvas(recorder); + canvas.drawRect( + const Rect.fromLTWH(0, 0, 500, 500), + Paint()..color = const Color(0x22FF0000), + ); + final Picture picture = recorder.endRecording(); + builder.addPicture(Offset.zero, picture); + + finishBuilder(builder); + } +} + +/// Platform view with clip path after transformed, with multiple clips. +class PlatformViewClipPathWithTransformMultipleClipsScenario extends PlatformViewScenario { + /// Constructs a platform view with clip path with transform scenario. + PlatformViewClipPathWithTransformMultipleClipsScenario( + super.view, { + super.id = 0, + }); + + @override + void onBeginFrame(Duration duration) { + final Matrix4 matrix4 = Matrix4.identity() + ..rotateZ(1) + ..scale(0.5, 0.5, 1.0) + ..translate(1000.0, 100.0); + + final SceneBuilder builder = SceneBuilder()..pushTransform(matrix4.storage); + final Path path = Path() + ..moveTo(100, 100) + ..quadraticBezierTo(50, 250, 100, 400) + ..lineTo(350, 400) + ..cubicTo(400, 300, 300, 200, 350, 100) + ..close(); + + builder..pushClipPath(path) + ..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600)); + + addPlatformView( + id, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + ); + + // Add a translucent rect that has the same size of PlatformView. + final PictureRecorder recorder = PictureRecorder(); + final Canvas canvas = Canvas(recorder); + canvas.drawRect( + const Rect.fromLTWH(0, 0, 500, 500), + Paint()..color = const Color(0x22FF0000), + ); + final Picture picture = recorder.endRecording(); + builder.addPicture(Offset.zero, picture); + + finishBuilder(builder); + } +} + +/// Two platform views, both have clip rects +class TwoPlatformViewClipRect extends Scenario + with _BasePlatformViewScenarioMixin { + /// Creates the PlatformView scenario. + TwoPlatformViewClipRect( + super.view, { + required this.firstId, + required this.secondId, + }); + + /// The platform view identifier to use for the first platform view. + final int firstId; + + /// The platform view identifier to use for the second platform view. + final int secondId; + + @override + void onBeginFrame(Duration duration) { + final SceneBuilder builder = SceneBuilder(); + builder.pushOffset(0, 600); + builder.pushClipRect(const Rect.fromLTRB(100, 100, 400, 400)); + + addPlatformView( + firstId, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + text: 'platform view 1', + ); + + builder.pop(); + builder.pop(); + + // Use a different rect to differentiate from the 1st clip rect. + builder.pushClipRect(const Rect.fromLTRB(100, 100, 300, 300)); + + addPlatformView( + secondId, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + text: 'platform view 2', + ); - finishBuilder(builder); + builder.pop(); + final Scene scene = builder.build(); + view.render(scene); + scene.dispose(); } } -/// Platform view with clip path after transformed. -class PlatformViewClipPathWithTransformScenario extends PlatformViewScenario { - /// Constructs a platform view with clip path with transform scenario. - PlatformViewClipPathWithTransformScenario( +/// Two platform views, both have clip rects, with multiple clips. +class TwoPlatformViewClipRectMultipleClips extends Scenario + with _BasePlatformViewScenarioMixin { + /// Creates the PlatformView scenario. + TwoPlatformViewClipRectMultipleClips( super.view, { - super.id = 0, + required this.firstId, + required this.secondId, }); + /// The platform view identifier to use for the first platform view. + final int firstId; + + /// The platform view identifier to use for the second platform view. + final int secondId; + @override void onBeginFrame(Duration duration) { - final Matrix4 matrix4 = Matrix4.identity() - ..rotateZ(1) - ..scale(0.5, 0.5, 1.0) - ..translate(1000.0, 100.0); - - final SceneBuilder builder = SceneBuilder()..pushTransform(matrix4.storage); - final Path path = Path() - ..moveTo(100, 100) - ..quadraticBezierTo(50, 250, 100, 400) - ..lineTo(350, 400) - ..cubicTo(400, 300, 300, 200, 350, 100) - ..close(); + final SceneBuilder builder = SceneBuilder(); + builder.pushOffset(0, 600); + builder..pushClipRect(const Rect.fromLTRB(100, 100, 400, 400)) + ..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600)); - builder.pushClipPath(path); addPlatformView( - id, + firstId, dispatcher: view.platformDispatcher, sceneBuilder: builder, + text: 'platform view 1', ); - // Add a translucent rect that has the same size of PlatformView. - final PictureRecorder recorder = PictureRecorder(); - final Canvas canvas = Canvas(recorder); - canvas.drawRect( - const Rect.fromLTWH(0, 0, 500, 500), - Paint()..color = const Color(0x22FF0000), + builder.pop(); + builder.pop(); + builder.pop(); + + // Use a different rect to differentiate from the 1st clip rect. + builder..pushClipRect(const Rect.fromLTRB(100, 100, 300, 300)) + ..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600)); + + addPlatformView( + secondId, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + text: 'platform view 2', ); - final Picture picture = recorder.endRecording(); - builder.addPicture(Offset.zero, picture); - finishBuilder(builder); + builder.pop(); + builder.pop(); + final Scene scene = builder.build(); + view.render(scene); + scene.dispose(); } } -/// Two platform views, both have clip rects -class TwoPlatformViewClipRect extends Scenario +/// Two platform views, both have clip rrects +class TwoPlatformViewClipRRect extends Scenario with _BasePlatformViewScenarioMixin { /// Creates the PlatformView scenario. - TwoPlatformViewClipRect( + TwoPlatformViewClipRRect( super.view, { required this.firstId, required this.secondId, @@ -1026,7 +1495,17 @@ class TwoPlatformViewClipRect extends Scenario void onBeginFrame(Duration duration) { final SceneBuilder builder = SceneBuilder(); builder.pushOffset(0, 600); - builder.pushClipRect(const Rect.fromLTRB(100, 100, 400, 400)); + builder.pushClipRRect( + RRect.fromLTRBAndCorners( + 0, + 0, + 500, + 500, + topLeft: const Radius.circular(15), + topRight: const Radius.circular(50), + bottomLeft: const Radius.circular(50), + ), + ); addPlatformView( firstId, @@ -1038,8 +1517,18 @@ class TwoPlatformViewClipRect extends Scenario builder.pop(); builder.pop(); - // Use a different rect to differentiate from the 1st clip rect. - builder.pushClipRect(const Rect.fromLTRB(100, 100, 300, 300)); + // Use a different rrect to differentiate from the 1st clip rrect. + builder.pushClipRRect( + RRect.fromLTRBAndCorners( + 0, + 0, + 500, + 500, + topLeft: const Radius.circular(100), + topRight: const Radius.circular(50), + bottomLeft: const Radius.circular(50), + ), + ); addPlatformView( secondId, @@ -1055,11 +1544,11 @@ class TwoPlatformViewClipRect extends Scenario } } -/// Two platform views, both have clip rrects -class TwoPlatformViewClipRRect extends Scenario +/// Two platform views, both have clip rrects, with multiple clips. +class TwoPlatformViewClipRRectMultipleClips extends Scenario with _BasePlatformViewScenarioMixin { /// Creates the PlatformView scenario. - TwoPlatformViewClipRRect( + TwoPlatformViewClipRRectMultipleClips( super.view, { required this.firstId, required this.secondId, @@ -1075,7 +1564,7 @@ class TwoPlatformViewClipRRect extends Scenario void onBeginFrame(Duration duration) { final SceneBuilder builder = SceneBuilder(); builder.pushOffset(0, 600); - builder.pushClipRRect( + builder..pushClipRRect( RRect.fromLTRBAndCorners( 0, 0, @@ -1085,7 +1574,9 @@ class TwoPlatformViewClipRRect extends Scenario topRight: const Radius.circular(50), bottomLeft: const Radius.circular(50), ), - ); + ) + ..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600)); + addPlatformView( firstId, @@ -1094,11 +1585,12 @@ class TwoPlatformViewClipRRect extends Scenario text: 'platform view 1', ); + builder.pop(); builder.pop(); builder.pop(); // Use a different rrect to differentiate from the 1st clip rrect. - builder.pushClipRRect( + builder..pushClipRRect( RRect.fromLTRBAndCorners( 0, 0, @@ -1108,7 +1600,9 @@ class TwoPlatformViewClipRRect extends Scenario topRight: const Radius.circular(50), bottomLeft: const Radius.circular(50), ), - ); + ) + ..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600)); + addPlatformView( secondId, @@ -1117,6 +1611,7 @@ class TwoPlatformViewClipRRect extends Scenario text: 'platform view 2', ); + builder.pop(); builder.pop(); final Scene scene = builder.build(); view.render(scene); @@ -1187,6 +1682,76 @@ class TwoPlatformViewClipPath extends Scenario } } + +/// Two platform views, both have clip path, with multiple clips. +class TwoPlatformViewClipPathMultipleClips extends Scenario + with _BasePlatformViewScenarioMixin { + /// Creates the PlatformView scenario. + TwoPlatformViewClipPathMultipleClips( + super.view, { + required this.firstId, + required this.secondId, + }); + + /// The platform view identifier to use for the first platform view. + final int firstId; + + /// The platform view identifier to use for the second platform view. + final int secondId; + + @override + void onBeginFrame(Duration duration) { + final SceneBuilder builder = SceneBuilder(); + builder.pushOffset(0, 600); + final Path path = Path() + ..moveTo(100, 100) + ..quadraticBezierTo(50, 250, 100, 400) + ..lineTo(350, 400) + ..cubicTo(400, 300, 300, 200, 350, 100) + ..close(); + + builder..pushClipPath(path) + ..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600)); + + + addPlatformView( + firstId, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + text: 'platform view 1', + ); + + builder.pop(); + builder.pop(); + builder.pop(); + + // Use a different path to differentiate from the 1st clip path. + final Path path2 = Path() + ..moveTo(100, 100) + ..quadraticBezierTo(100, 150, 100, 400) + ..lineTo(350, 350) + ..cubicTo(400, 300, 300, 200, 350, 200) + ..close(); + + builder..pushClipPath(path2) + ..pushClipRect(const Rect.fromLTRB(200, 200, 600, 600)); + + + addPlatformView( + secondId, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + text: 'platform view 2', + ); + + builder.pop(); + builder.pop(); + final Scene scene = builder.build(); + view.render(scene); + scene.dispose(); + } +} + /// Platform view with transform. class PlatformViewTransformScenario extends PlatformViewScenario { /// Constructs a platform view with transform scenario. @@ -1885,6 +2450,94 @@ class PlatformViewsWithClipsScrolling extends Scenario } } +/// Builds a scenario where many platform views with clips scrolling, with multiple clips. +class PlatformViewsWithClipsScrollingMultipleClips extends Scenario + with _BasePlatformViewScenarioMixin { + /// Creates the PlatformView scenario. + PlatformViewsWithClipsScrollingMultipleClips( + super.view, { + required int firstPlatformViewId, + required int lastPlatformViewId, + }) : _firstPlatformViewId = firstPlatformViewId, + _lastPlatformViewId = lastPlatformViewId; + + final int _firstPlatformViewId; + + final int _lastPlatformViewId; + + double _offset = 0; + + bool _movingUp = true; + + @override + void onBeginFrame(Duration duration) { + _buildOneFrame(_offset); + } + + @override + void onDrawFrame() { + // Scroll up until -1000, then scroll down until -1. + if (_offset < -500) { + _movingUp = false; + } else if (_offset > -1) { + _movingUp = true; + } + + if (_movingUp) { + _offset -= 100; + } else { + _offset += 100; + } + view.platformDispatcher.scheduleFrame(); + super.onDrawFrame(); + } + + Future _buildOneFrame(double offset) async { + const double cellWidth = 1000; + double localOffset = offset; + final SceneBuilder builder = SceneBuilder(); + const double cellHeight = 300; + for (int i = _firstPlatformViewId; i <= _lastPlatformViewId; i++) { + // Build a list view with platform views. + builder.pushOffset(0, localOffset); + bool addedClipRRect = false; + if (localOffset > -1) { + addedClipRRect = true; + builder..pushClipRRect( + RRect.fromLTRBAndCorners( + 100, + 100, + 400, + 400, + topLeft: const Radius.circular(15), + topRight: const Radius.circular(50), + bottomLeft: const Radius.circular(50), + ), + ) + ..pushClipRect(const Rect.fromLTRB(200, 0, 600, 600)); + + } + addPlatformView( + i, + dispatcher: view.platformDispatcher, + sceneBuilder: builder, + text: 'platform view $i', + width: cellWidth, + height: cellHeight, + ); + if (addedClipRRect) { + builder.pop(); + } + builder.pop(); + localOffset += cellHeight; + } + + final Scene scene = builder.build(); + view.render(scene); + scene.dispose(); + } +} + final Map _createdPlatformViews = {}; final Map _calledToBeCreatedPlatformViews = {}; diff --git a/testing/scenario_app/lib/src/scenarios.dart b/testing/scenario_app/lib/src/scenarios.dart index bcd2c0cd908b6..db50779fb2292 100644 --- a/testing/scenario_app/lib/src/scenarios.dart +++ b/testing/scenario_app/lib/src/scenarios.dart @@ -37,14 +37,23 @@ Map _scenarios = { 'platform_view_surrounding_layers_fractional_coordinate': (FlutterView view) => PlatformViewSurroundingLayersFractionalCoordinateScenario(view, id: _viewId++), 'platform_view_partial_intersection_fractional_coordinate': (FlutterView view) => PlatformViewPartialIntersectionFractionalCoordinateScenario(view, id: _viewId++), 'platform_view_cliprect': (FlutterView view) => PlatformViewClipRectScenario(view, id: _viewId++), + 'platform_view_cliprect_multiple_clips': (FlutterView view) => PlatformViewClipRectMultipleClipsScenario(view, id: _viewId++), 'platform_view_cliprect_with_transform': (FlutterView view) => PlatformViewClipRectWithTransformScenario(view, id: _viewId++), + 'platform_view_cliprect_with_transform_multiple_clips': (FlutterView view) => PlatformViewClipRectWithTransformMultipleClipsScenario(view, id: _viewId++), 'platform_view_cliprect_after_moved': (FlutterView view) => PlatformViewClipRectAfterMovedScenario(view, id: _viewId++), + 'platform_view_cliprect_after_moved_multiple_clips': (FlutterView view) => PlatformViewClipRectAfterMovedMultipleClipsScenario(view, id: _viewId++), 'platform_view_cliprrect': (FlutterView view) => PlatformViewClipRRectScenario(view, id: _viewId++), + 'platform_view_cliprrect_multiple_clips': (FlutterView view) => PlatformViewClipRRectMultipleClipsScenario(view, id: _viewId++), 'platform_view_large_cliprrect': (FlutterView view) => PlatformViewLargeClipRRectScenario(view, id: _viewId++), + 'platform_view_large_cliprrect_multiple_clips': (FlutterView view) => PlatformViewLargeClipRRectMultipleClipsScenario(view, id: _viewId++), 'platform_view_cliprrect_with_transform': (FlutterView view) => PlatformViewClipRRectWithTransformScenario(view, id: _viewId++), + 'platform_view_cliprrect_with_transform_multiple_clips': (FlutterView view) => PlatformViewClipRRectWithTransformMultipleClipsScenario(view, id: _viewId++), 'platform_view_large_cliprrect_with_transform': (FlutterView view) => PlatformViewLargeClipRRectWithTransformScenario(view, id: _viewId++), + 'platform_view_large_cliprrect_with_transform_multiple_clips': (FlutterView view) => PlatformViewLargeClipRRectWithTransformMultipleClipsScenario(view, id: _viewId++), 'platform_view_clippath': (FlutterView view) => PlatformViewClipPathScenario(view, id: _viewId++), + 'platform_view_clippath_multiple_clips': (FlutterView view) => PlatformViewClipPathMultipleClipsScenario(view, id: _viewId++), 'platform_view_clippath_with_transform': (FlutterView view) => PlatformViewClipPathWithTransformScenario(view, id: _viewId++), + 'platform_view_clippath_with_transform_multiple_clips': (FlutterView view) => PlatformViewClipPathWithTransformMultipleClipsScenario(view, id: _viewId++), 'platform_view_transform': (FlutterView view) => PlatformViewTransformScenario(view, id: _viewId++), 'platform_view_opacity': (FlutterView view) => PlatformViewOpacityScenario(view, id: _viewId++), 'platform_view_with_other_backdrop_filter': (FlutterView view) => PlatformViewWithOtherBackDropFilter(view, id: _viewId++), @@ -61,9 +70,13 @@ Map _scenarios = { 'platform_view_gesture_accept_with_overlapping_platform_views': (FlutterView view) => PlatformViewForOverlappingPlatformViewsScenario(view, foregroundId: _viewId++, backgroundId: _viewId++), 'platform_view_scrolling_under_widget':(FlutterView view) => PlatformViewScrollingUnderWidget(view, firstPlatformViewId: _viewId++, lastPlatformViewId: _viewId+=16), 'platform_views_with_clips_scrolling':(FlutterView view) => PlatformViewsWithClipsScrolling(view, firstPlatformViewId: _viewId++, lastPlatformViewId: _viewId+=16), + 'platform_views_with_clips_scrolling_multiple_clips':(FlutterView view) => PlatformViewsWithClipsScrollingMultipleClips(view, firstPlatformViewId: _viewId++, lastPlatformViewId: _viewId+=16), 'two_platform_view_clip_rect': (FlutterView view) => TwoPlatformViewClipRect(view, firstId: _viewId++, secondId: _viewId++), + 'two_platform_view_clip_rect_multiple_clips': (FlutterView view) => TwoPlatformViewClipRectMultipleClips(view, firstId: _viewId++, secondId: _viewId++), 'two_platform_view_clip_rrect': (FlutterView view) => TwoPlatformViewClipRRect(view, firstId: _viewId++, secondId: _viewId++), + 'two_platform_view_clip_rrect_multiple_clips': (FlutterView view) => TwoPlatformViewClipRRectMultipleClips(view, firstId: _viewId++, secondId: _viewId++), 'two_platform_view_clip_path': (FlutterView view) => TwoPlatformViewClipPath(view, firstId: _viewId++, secondId: _viewId++), + 'two_platform_view_clip_path_multiple_clips': (FlutterView view) => TwoPlatformViewClipPathMultipleClips(view, firstId: _viewId++, secondId: _viewId++), 'tap_status_bar': (FlutterView view) => TouchesScenario(view), 'initial_route_reply': (FlutterView view) => InitialRouteReply(view), 'platform_view_with_continuous_texture': (FlutterView view) => PlatformViewWithContinuousTexture(view, id: _viewId++), diff --git a/testing/scenario_app/run_ios_tests.sh b/testing/scenario_app/run_ios_tests.sh index ed040b16d1b47..66b13fddb0c52 100755 --- a/testing/scenario_app/run_ios_tests.sh +++ b/testing/scenario_app/run_ios_tests.sh @@ -110,14 +110,23 @@ if set -o pipefail && xcodebuild -sdk iphonesimulator \ -skip-testing ScenariosUITests/MultiplePlatformViewsTest/testPlatformView \ -skip-testing ScenariosUITests/NonFullScreenFlutterViewPlatformViewUITests/testPlatformView \ -skip-testing ScenariosUITests/PlatformViewMutationClipPathTests/testPlatformView \ + -skip-testing ScenariosUITests/PlatformViewMutationClipPathMultipleClipsTests/testPlatformView \ -skip-testing ScenariosUITests/PlatformViewMutationClipPathWithTransformTests/testPlatformView \ + -skip-testing ScenariosUITests/PlatformViewMutationClipPathWithTransformMultipleClipsTests/testPlatformView \ -skip-testing ScenariosUITests/PlatformViewMutationClipRectAfterMovedTests/testPlatformView \ + -skip-testing ScenariosUITests/PlatformViewMutationClipRectAfterMovedMultipleClipsTests/testPlatformView \ -skip-testing ScenariosUITests/PlatformViewMutationClipRectTests/testPlatformView \ + -skip-testing ScenariosUITests/PlatformViewMutationClipRectMultipleClipsTests/testPlatformView \ -skip-testing ScenariosUITests/PlatformViewMutationClipRectWithTransformTests/testPlatformView \ + -skip-testing ScenariosUITests/PlatformViewMutationClipRectWithTransformMultipleClipsTests/testPlatformView \ -skip-testing ScenariosUITests/PlatformViewMutationClipRRectTests/testPlatformView \ + -skip-testing ScenariosUITests/PlatformViewMutationClipRRectMultipleClipsTests/testPlatformView \ -skip-testing ScenariosUITests/PlatformViewMutationClipRRectWithTransformTests/testPlatformView \ + -skip-testing ScenariosUITests/PlatformViewMutationClipRRectWithTransformMultipleClipsTests/testPlatformView \ -skip-testing ScenariosUITests/PlatformViewMutationLargeClipRRectTests/testPlatformView \ + -skip-testing ScenariosUITests/PlatformViewMutationLargeClipRRectMultipleClipsTests/testPlatformView \ -skip-testing ScenariosUITests/PlatformViewMutationLargeClipRRectWithTransformTests/testPlatformView \ + -skip-testing ScenariosUITests/PlatformViewMutationLargeClipRRectWithTransformMultipleClipsTests/testPlatformView \ -skip-testing ScenariosUITests/PlatformViewMutationOpacityTests/testPlatformView \ -skip-testing ScenariosUITests/PlatformViewMutationTransformTests/testPlatformView \ -skip-testing ScenariosUITests/PlatformViewRotation/testPlatformView \ @@ -126,8 +135,11 @@ if set -o pipefail && xcodebuild -sdk iphonesimulator \ -skip-testing ScenariosUITests/PlatformViewWithOtherBackdropFilterTests/testPlatformView \ -skip-testing ScenariosUITests/RenderingSelectionTest/testSoftwareRendering \ -skip-testing ScenariosUITests/TwoPlatformViewClipPathTests/testPlatformView \ + -skip-testing ScenariosUITests/TwoPlatformViewClipPathMultipleClipsTests/testPlatformView \ -skip-testing ScenariosUITests/TwoPlatformViewClipRectTests/testPlatformView \ + -skip-testing ScenariosUITests/TwoPlatformViewClipRectMultipleClipsTests/testPlatformView \ -skip-testing ScenariosUITests/TwoPlatformViewClipRRectTests/testPlatformView \ + -skip-testing ScenariosUITests/TwoPlatformViewClipRRectMultipleClipsTests/testPlatformView \ -skip-testing ScenariosUITests/TwoPlatformViewsWithOtherBackDropFilterTests/testPlatformView \ -skip-testing ScenariosUITests/UnobstructedPlatformViewTests/testMultiplePlatformViewsWithOverlays \ # Plist with FLTEnableImpeller=YES, all projects in the workspace requires this file.