From bdfe5f336d1247128a133402555bdcdb5653f327 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 7 Nov 2022 15:52:36 -0800 Subject: [PATCH 1/2] only clip when necessary tests fix tests format review fix add scenario tset more scenario tests add docs and comments use offset.zero --- .../ios/framework/Source/FlutterEngine.mm | 15 +- .../framework/Source/FlutterPlatformViews.mm | 80 ++++++++--- .../Source/FlutterPlatformViewsTest.mm | 68 +++++++++ .../Source/FlutterPlatformViews_Internal.h | 16 ++- .../Source/FlutterPlatformViews_Internal.mm | 36 ++++- .../Scenarios.xcodeproj/project.pbxproj | 12 ++ .../ios/Scenarios/Scenarios/AppDelegate.m | 3 + .../ScenariosUITests/GoldenTestManager.m | 3 + .../ScenariosUITests/PlatformViewUITests.m | 54 ++++++++ ...with_transform_iPhone 8_13.0_simulator.png | Bin 0 -> 18254 bytes ...with_transform_iPhone 8_13.0_simulator.png | Bin 0 -> 18794 bytes ...with_transform_iPhone 8_13.0_simulator.png | Bin 0 -> 18730 bytes .../scenario_app/lib/src/platform_view.dart | 131 +++++++++++++++++- testing/scenario_app/lib/src/scenarios.dart | 3 + 14 files changed, 382 insertions(+), 39 deletions(-) create mode 100644 testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_with_transform_iPhone 8_13.0_simulator.png create mode 100644 testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_with_transform_iPhone 8_13.0_simulator.png create mode 100644 testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprrect_with_transform_iPhone 8_13.0_simulator.png diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 9a0352a360604..7efe80c072e89 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -527,13 +527,14 @@ - (void)setupChannels { // This will be invoked once the shell is done setting up and the isolate ID // for the UI isolate is available. fml::WeakPtr weakSelf = [self getWeakPtr]; - [_binaryMessenger setMessageHandlerOnChannel:@"flutter/isolate" - binaryMessageHandler:^(NSData* message, FlutterBinaryReply reply) { - if (weakSelf) { - weakSelf.get().isolateId = - [[FlutterStringCodec sharedInstance] decode:message]; - } - }]; + __block FlutterBinaryMessageHandler handler; + handler = ^(NSData* message, FlutterBinaryReply reply) { + if (weakSelf) { + weakSelf.get().isolateId = [[FlutterStringCodec sharedInstance] decode:message]; + } + }; + Block_release(handler); + [_binaryMessenger setMessageHandlerOnChannel:@"flutter/isolate" binaryMessageHandler:handler]; _localizationChannel.reset([[FlutterMethodChannel alloc] initWithName:@"flutter/localization" diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index 40c7ab8e12edc..12bdf28269d67 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -32,6 +32,22 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree { } @end +// Determines if the final `clipBounds` from a clipRect/clipRRect/clipPath mutator contains the +// `platformview_boundingrect`. +// +// `clip_bounds` is the bounding rect of the rect/rrect/path in the clipRect/clipRRect/clipPath +// mutator. This rect is in its own coordinate space. The rect needs to be transformed by +// `transform_matrix` to be in the coordinate space where the PlatformView is displayed. +// +// `platformview_boundingrect` is the final bounding rect of the PlatformView in the coordinate +// space where the PlatformView is displayed. +static bool ClipBoundsContainsPlatformViewBoundingRect(const SkRect& clip_bounds, + const SkRect& platformview_boundingrect, + const SkMatrix& transform_matrix) { + SkRect transforme_clip_bounds = transform_matrix.mapRect(clip_bounds); + return transforme_clip_bounds.contains(platformview_boundingrect); +} + namespace flutter { // Becomes NO if Apple's API changes and blurred backdrop filters cannot be applied. BOOL canApplyBlurBackdrop = YES; @@ -404,7 +420,8 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree { } void FlutterPlatformViewsController::ApplyMutators(const MutatorsStack& mutators_stack, - UIView* embedded_view) { + UIView* embedded_view, + const SkRect& bounding_rect) { if (flutter_view_ == nullptr) { return; } @@ -412,39 +429,53 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree { ResetAnchor(embedded_view.layer); ChildClippingView* clipView = (ChildClippingView*)embedded_view.superview; - // The UIKit frame is set based on the logical resolution instead of physical. - // (https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html). - // However, flow is based on the physical resolution. For example, 1000 pixels in flow equals - // 500 points in UIKit. And until this point, we did all the calculation based on the flow - // resolution. So we need to scale down to match UIKit's logical resolution. CGFloat screenScale = [UIScreen mainScreen].scale; - CATransform3D finalTransform = CATransform3DMakeScale(1 / screenScale, 1 / screenScale, 1); UIView* flutter_view = flutter_view_.get(); FlutterClippingMaskView* maskView = [[[FlutterClippingMaskView alloc] initWithFrame:CGRectMake(-clipView.frame.origin.x, -clipView.frame.origin.y, CGRectGetWidth(flutter_view.bounds), - CGRectGetHeight(flutter_view.bounds))] autorelease]; + CGRectGetHeight(flutter_view.bounds)) + screenScale:screenScale] autorelease]; + SkMatrix transformMatrix; NSMutableArray* blurFilters = [[[NSMutableArray alloc] init] autorelease]; + clipView.maskView = nil; auto iter = mutators_stack.Begin(); while (iter != mutators_stack.End()) { switch ((*iter)->GetType()) { case kTransform: { - CATransform3D transform = GetCATransform3DFromSkMatrix((*iter)->GetMatrix()); - finalTransform = CATransform3DConcat(transform, finalTransform); + transformMatrix.preConcat((*iter)->GetMatrix()); break; } - case kClipRect: - [maskView clipRect:(*iter)->GetRect() matrix:finalTransform]; + case kClipRect: { + if (ClipBoundsContainsPlatformViewBoundingRect((*iter)->GetRect(), bounding_rect, + transformMatrix)) { + break; + } + [maskView clipRect:(*iter)->GetRect() matrix:transformMatrix]; + clipView.maskView = maskView; break; - case kClipRRect: - [maskView clipRRect:(*iter)->GetRRect() matrix:finalTransform]; + } + case kClipRRect: { + if (ClipBoundsContainsPlatformViewBoundingRect((*iter)->GetRRect().getBounds(), + bounding_rect, transformMatrix)) { + break; + } + [maskView clipRRect:(*iter)->GetRRect() matrix:transformMatrix]; + clipView.maskView = maskView; break; - case kClipPath: - [maskView clipPath:(*iter)->GetPath() matrix:finalTransform]; + } + case kClipPath: { + if (ClipBoundsContainsPlatformViewBoundingRect((*iter)->GetPath().getBounds(), + bounding_rect, transformMatrix)) { + break; + } + [maskView clipPath:(*iter)->GetPath() matrix:transformMatrix]; + clipView.maskView = maskView; break; + } case kOpacity: embedded_view.alpha = (*iter)->GetAlphaFloat() * embedded_view.alpha; break; @@ -489,6 +520,13 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree { [clipView applyBlurBackdropFilters:blurFilters]; } + // The UIKit frame is set based on the logical resolution (points) instead of physical. + // (https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html). + // However, flow is based on the physical resolution. For example, 1000 pixels in flow equals + // 500 points in UIKit for devices that has screenScale of 2. We need to scale the transformMatrix + // down to the logical resoltion before applying it to the layer of PlatformView. + transformMatrix.postScale(1 / screenScale, 1 / screenScale); + // Reverse the offset of the clipView. // The clipView's frame includes the final translate of the final transform matrix. // Thus, this translate needs to be reversed so the platform view can layout at the correct @@ -496,10 +534,9 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree { // // Note that the transforms are not applied to the clipping paths because clipping paths happen on // the mask view, whose origin is always (0,0) to the flutter_view. - CATransform3D reverseTranslate = - CATransform3DMakeTranslation(-clipView.frame.origin.x, -clipView.frame.origin.y, 0); - embedded_view.layer.transform = CATransform3DConcat(finalTransform, reverseTranslate); - clipView.maskView = maskView; + transformMatrix.postTranslate(-clipView.frame.origin.x, -clipView.frame.origin.y); + + embedded_view.layer.transform = flutter::GetCATransform3DFromSkMatrix(transformMatrix); } void FlutterPlatformViewsController::CompositeWithParams(int view_id, @@ -538,7 +575,7 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree { CGFloat screenScale = [UIScreen mainScreen].scale; clippingView.frame = CGRectMake(rect.x() / screenScale, rect.y() / screenScale, rect.width() / screenScale, rect.height() / screenScale); - ApplyMutators(mutatorStack, touchInterceptor); + ApplyMutators(mutatorStack, touchInterceptor, rect); } EmbedderPaintContext FlutterPlatformViewsController::CompositeEmbeddedView(int view_id) { @@ -763,6 +800,7 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree { return layer; } SkCanvas* overlay_canvas = frame->SkiaCanvas(); + overlay_canvas->clipRect(rect); overlay_canvas->clear(SK_ColorTRANSPARENT); if (frame->GetDisplayListBuilder()) { slice->render_into(frame->GetDisplayListBuilder().get()); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index 56fbc541d3253..9391a4b23b1da 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -1478,6 +1478,74 @@ - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView { kFloatCompareEpsilon); } +- (void)testClipsDoNotInterceptWithPlatformViewShouldNotAddMaskView { + flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate; + auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest"); + flutter::TaskRunners runners(/*label=*/self.name.UTF8String, + /*platform=*/thread_task_runner, + /*raster=*/thread_task_runner, + /*ui=*/thread_task_runner, + /*io=*/thread_task_runner); + auto flutterPlatformViewsController = std::make_shared(); + auto platform_view = std::make_unique( + /*delegate=*/mock_delegate, + /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + /*platform_views_controller=*/flutterPlatformViewsController, + /*task_runners=*/runners); + + FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = + [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; + flutterPlatformViewsController->RegisterViewFactory( + factory, @"MockFlutterPlatformView", + FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + FlutterResult result = ^(id result) { + }; + flutterPlatformViewsController->OnMethodCall( + [FlutterMethodCall + methodCallWithMethodName:@"create" + arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], + result); + + XCTAssertNotNil(gMockPlatformView); + + UIView* mockFlutterView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)] autorelease]; + flutterPlatformViewsController->SetFlutterView(mockFlutterView); + // 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); + SkMatrix translateMatrix = SkMatrix::Translate(5, 5); + // The platform view's rect for this test will be (5, 5, 10, 10) + stack.PushTransform(translateMatrix); + // Push a clip rect, big enough to contain the entire platform view bound + SkRect rect = SkRect::MakeXYWH(0, 0, 25, 25); + stack.PushClipRect(rect); + // Push a clip rrect, big enough to contain the entire platform view bound + SkRect rect_for_rrect = SkRect::MakeXYWH(0, 0, 24, 24); + SkRRect rrect = SkRRect::MakeRectXY(rect_for_rrect, 1, 1); + stack.PushClipRRect(rrect); + // Push a clip path, big enough to contain the entire platform view bound + SkPath path = SkPath::RRect(SkRect::MakeXYWH(0, 0, 23, 23), 1, 1); + stack.PushClipPath(path); + + auto embeddedViewParams = std::make_unique( + SkMatrix::Concat(screenScaleMatrix, translateMatrix), SkSize::Make(5, 5), stack); + + flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); + flutterPlatformViewsController->CompositeEmbeddedView(2); + gMockPlatformView.backgroundColor = UIColor.redColor; + XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass:ChildClippingView.class]); + ChildClippingView* childClippingView = (ChildClippingView*)gMockPlatformView.superview.superview; + [mockFlutterView addSubview:childClippingView]; + + [mockFlutterView setNeedsLayout]; + [mockFlutterView layoutIfNeeded]; + + XCTAssertNil(childClippingView.maskView); +} + - (void)testClipRect { flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate; auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest"); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h index 9e8009e6fe077..7ec51e3b8ffcf 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h @@ -28,20 +28,22 @@ // is replaced with the alpha channel of the |FlutterClippingMaskView|. @interface FlutterClippingMaskView : UIView +- (instancetype)initWithFrame:(CGRect)frame screenScale:(CGFloat)screenScale; + // Adds a clip rect operation to the queue. // // The `clipSkRect` is transformed with the `matrix` before adding to the queue. -- (void)clipRect:(const SkRect&)clipSkRect matrix:(const CATransform3D&)matrix; +- (void)clipRect:(const SkRect&)clipSkRect matrix:(const SkMatrix&)matrix; // Adds a clip rrect operation to the queue. // // The `clipSkRRect` is transformed with the `matrix` before adding to the queue. -- (void)clipRRect:(const SkRRect&)clipSkRRect matrix:(const CATransform3D&)matrix; +- (void)clipRRect:(const SkRRect&)clipSkRRect matrix:(const SkMatrix&)matrix; // Adds a clip path operation to the queue. // // The `path` is transformed with the `matrix` before adding to the queue. -- (void)clipPath:(const SkPath&)path matrix:(const CATransform3D&)matrix; +- (void)clipPath:(const SkPath&)path matrix:(const SkMatrix&)matrix; @end @@ -280,7 +282,13 @@ class FlutterPlatformViewsController { // T_1 is applied to C_2, T_3 and T_4 are applied to C_5, and T_6 is applied to PLATFORM_VIEW. // // After each clip operation, we update the head to the super view of the current head. - void ApplyMutators(const MutatorsStack& mutators_stack, UIView* embedded_view); + // + // The `bounding_rect` is the final bounding rect of the PlatformView + // (EmbeddedViewParams::finalBoundingRect). If a clip mutator's rect contains the final bounding + // rect of the PlatformView, the clip mutator is not applied for performance optimization. + void ApplyMutators(const MutatorsStack& mutators_stack, + UIView* embedded_view, + const SkRect& bounding_rect); void CompositeWithParams(int view_id, const EmbeddedViewParams& params); // Allocates a new FlutterPlatformViewLayer if needed, draws the pixels within the rect from diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm index ff70a4b4d2b27..da7f156bafe95 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm @@ -241,6 +241,16 @@ - (NSMutableArray*)backdropFilterSubviews { @interface FlutterClippingMaskView () +// A `CATransform3D` matrix represnts a scale transform that revese UIScreen.scale. +// +// The transform matrix passed in clipRect/clipRRect/clipPath methods are in device coordinate +// space. The transfrom matrix concats `reverseScreenScale` to create a transform matrix in the iOS +// logical coordinates (points). +// +// See https://developer.apple.com/documentation/uikit/uiscreen/1617836-scale?language=objc for +// information about screen scale. +@property(nonatomic) CATransform3D reverseScreenScale; + - (fml::CFRef)getTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix; @end @@ -250,8 +260,13 @@ @implementation FlutterClippingMaskView { } - (instancetype)initWithFrame:(CGRect)frame { + return [self initWithFrame:frame screenScale:[UIScreen mainScreen].scale]; +} + +- (instancetype)initWithFrame:(CGRect)frame screenScale:(CGFloat)screenScale { if (self = [super initWithFrame:frame]) { self.backgroundColor = UIColor.clearColor; + _reverseScreenScale = CATransform3DMakeScale(1 / screenScale, 1 / screenScale, 1); } return self; } @@ -280,13 +295,16 @@ - (void)drawRect:(CGRect)rect { CGContextRestoreGState(context); } -- (void)clipRect:(const SkRect&)clipSkRect matrix:(const CATransform3D&)matrix { +- (void)clipRect:(const SkRect&)clipSkRect matrix:(const SkMatrix&)matrix { CGRect clipRect = flutter::GetCGRectFromSkRect(clipSkRect); CGPathRef path = CGPathCreateWithRect(clipRect, nil); - paths_.push_back([self getTransformedPath:path matrix:matrix]); + // The `matrix` is based on the physical pixels, convert it to UIKit points. + CATransform3D matrixInPoints = + CATransform3DConcat(flutter::GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale); + paths_.push_back([self getTransformedPath:path matrix:matrixInPoints]); } -- (void)clipRRect:(const SkRRect&)clipSkRRect matrix:(const CATransform3D&)matrix { +- (void)clipRRect:(const SkRRect&)clipSkRRect matrix:(const SkMatrix&)matrix { CGPathRef pathRef = nullptr; switch (clipSkRRect.getType()) { case SkRRect::kEmpty_Type: { @@ -346,13 +364,16 @@ - (void)clipRRect:(const SkRRect&)clipSkRRect matrix:(const CATransform3D&)matri break; } } + // The `matrix` is based on the physical pixels, convert it to UIKit points. + CATransform3D matrixInPoints = + CATransform3DConcat(flutter::GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale); // 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. - paths_.push_back([self getTransformedPath:pathRef matrix:matrix]); + paths_.push_back([self getTransformedPath:pathRef matrix:matrixInPoints]); } -- (void)clipPath:(const SkPath&)path matrix:(const CATransform3D&)matrix { +- (void)clipPath:(const SkPath&)path matrix:(const SkMatrix&)matrix { if (!path.isValid()) { return; } @@ -411,7 +432,10 @@ - (void)clipPath:(const SkPath&)path matrix:(const CATransform3D&)matrix { } verb = iter.next(pts); } - paths_.push_back([self getTransformedPath:pathRef matrix:matrix]); + // The `matrix` is based on the physical pixels, convert it to UIKit points. + CATransform3D matrixInPoints = + CATransform3DConcat(flutter::GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale); + paths_.push_back([self getTransformedPath:pathRef matrix:matrixInPoints]); } - (fml::CFRef)getTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix { diff --git a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj index feecb3b772466..5ef94a102a778 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj +++ b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj @@ -37,8 +37,11 @@ 6816DB9E231750ED00A51400 /* GoldenPlatformViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6816DB9D231750ED00A51400 /* GoldenPlatformViewTests.m */; }; 6816DBA12317573300A51400 /* GoldenImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 6816DBA02317573300A51400 /* GoldenImage.m */; }; 6816DBA42318358200A51400 /* GoldenTestManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6816DBA32318358200A51400 /* GoldenTestManager.m */; }; + 687AF8E9291EBDE0003912C7 /* golden_platform_view_clippath_with_transform_iPhone 8_13.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 687AF8E8291EBDE0003912C7 /* golden_platform_view_clippath_with_transform_iPhone 8_13.0_simulator.png */; }; 68A5B63423EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A5B63323EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m */; }; 68D4017D2564859300ECD91A /* ContinuousTexture.m in Sources */ = {isa = PBXBuildFile; fileRef = 68D4017C2564859300ECD91A /* ContinuousTexture.m */; }; + 68D5003F291ED645001ACFE1 /* golden_platform_view_cliprrect_with_transform_iPhone 8_13.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 68D5003D291ED645001ACFE1 /* golden_platform_view_cliprrect_with_transform_iPhone 8_13.0_simulator.png */; }; + 68D50042291ED8CD001ACFE1 /* golden_platform_view_cliprect_with_transform_iPhone 8_13.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 68D50041291ED8CD001ACFE1 /* golden_platform_view_cliprect_with_transform_iPhone 8_13.0_simulator.png */; }; F26F15B8268B6B5600EC54D3 /* iPadGestureTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F26F15B7268B6B5500EC54D3 /* iPadGestureTests.m */; }; F769EB53276312BB007AC10F /* golden_platform_view_cliprect_iPhone 8_13.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = F769EB52276312BB007AC10F /* golden_platform_view_cliprect_iPhone 8_13.0_simulator.png */; }; F7B464EB2759D0A900079189 /* golden_two_platform_views_with_other_backdrop_filter_iPhone 8_13.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = F7B464DE2759D0A900079189 /* golden_two_platform_views_with_other_backdrop_filter_iPhone 8_13.0_simulator.png */; }; @@ -148,9 +151,12 @@ 6816DBA02317573300A51400 /* GoldenImage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoldenImage.m; sourceTree = ""; }; 6816DBA22318358200A51400 /* GoldenTestManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GoldenTestManager.h; sourceTree = ""; }; 6816DBA32318358200A51400 /* GoldenTestManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoldenTestManager.m; sourceTree = ""; }; + 687AF8E8291EBDE0003912C7 /* golden_platform_view_clippath_with_transform_iPhone 8_13.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_clippath_with_transform_iPhone 8_13.0_simulator.png"; sourceTree = ""; }; 68A5B63323EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PlatformViewGestureRecognizerTests.m; sourceTree = ""; }; 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 = ""; }; + 68D5003D291ED645001ACFE1 /* golden_platform_view_cliprrect_with_transform_iPhone 8_13.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprrect_with_transform_iPhone 8_13.0_simulator.png"; sourceTree = ""; }; + 68D50041291ED8CD001ACFE1 /* golden_platform_view_cliprect_with_transform_iPhone 8_13.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_with_transform_iPhone 8_13.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 = ""; }; F769EB52276312BB007AC10F /* golden_platform_view_cliprect_iPhone 8_13.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_iPhone 8_13.0_simulator.png"; sourceTree = ""; }; @@ -290,6 +296,9 @@ F7B464DC2759D02B00079189 /* Goldens */ = { isa = PBXGroup; children = ( + 68D50041291ED8CD001ACFE1 /* golden_platform_view_cliprect_with_transform_iPhone 8_13.0_simulator.png */, + 68D5003D291ED645001ACFE1 /* golden_platform_view_cliprrect_with_transform_iPhone 8_13.0_simulator.png */, + 687AF8E8291EBDE0003912C7 /* golden_platform_view_clippath_with_transform_iPhone 8_13.0_simulator.png */, F7B464E32759D0A900079189 /* golden_bogus_font_text_iPhone 8_13.0_simulator.png */, F7B464E92759D0A900079189 /* golden_non_full_screen_flutter_view_platform_view_iPhone 8_13.0_simulator.png */, F7B464E52759D0A900079189 /* golden_platform_view_clippath_iPhone 8_13.0_simulator.png */, @@ -432,6 +441,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 68D50042291ED8CD001ACFE1 /* golden_platform_view_cliprect_with_transform_iPhone 8_13.0_simulator.png in Resources */, F7B464F62759D0A900079189 /* golden_non_full_screen_flutter_view_platform_view_iPhone 8_13.0_simulator.png in Resources */, F7B464F02759D0A900079189 /* golden_bogus_font_text_iPhone 8_13.0_simulator.png in Resources */, F7B464F22759D0A900079189 /* golden_platform_view_clippath_iPhone 8_13.0_simulator.png in Resources */, @@ -442,8 +452,10 @@ F7B464F32759D0A900079189 /* golden_platform_view_multiple_background_foreground_iPhone 8_13.0_simulator.png in Resources */, F7B464F72759D0A900079189 /* golden_platform_view_rotate_iPhone 8_13.0_simulator.png in Resources */, F7B464ED2759D0A900079189 /* golden_platform_view_cliprrect_iPhone 8_13.0_simulator.png in Resources */, + 68D5003F291ED645001ACFE1 /* golden_platform_view_cliprrect_with_transform_iPhone 8_13.0_simulator.png in Resources */, F7B464EB2759D0A900079189 /* golden_two_platform_views_with_other_backdrop_filter_iPhone 8_13.0_simulator.png in Resources */, F7B464F42759D0A900079189 /* golden_platform_view_with_other_backdrop_filter_iPhone 8_13.0_simulator.png in Resources */, + 687AF8E9291EBDE0003912C7 /* golden_platform_view_clippath_with_transform_iPhone 8_13.0_simulator.png in Resources */, F769EB53276312BB007AC10F /* golden_platform_view_cliprect_iPhone 8_13.0_simulator.png in Resources */, F7B464EF2759D0A900079189 /* golden_platform_view_multiple_iPhone 8_13.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 f69b402fa7131..4674126c7b47e 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m +++ b/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m @@ -44,6 +44,9 @@ - (BOOL)application:(UIApplication*)application @"--platform-view-cliprect" : @"platform_view_cliprect", @"--platform-view-cliprrect" : @"platform_view_cliprrect", @"--platform-view-clippath" : @"platform_view_clippath", + @"--platform-view-cliprrect-with-transform" : @"platform_view_cliprrect_with_transform", + @"--platform-view-cliprect-with-transform" : @"platform_view_cliprect_with_transform", + @"--platform-view-clippath-with-transform" : @"platform_view_clippath_with_transform", @"--platform-view-transform" : @"platform_view_transform", @"--platform-view-opacity" : @"platform_view_opacity", @"--platform-view-with-other-backdrop-filter" : @"platform_view_with_other_backdrop_filter", diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenTestManager.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenTestManager.m index 4b6f15e5e85c0..ad1a400bb7d9a 100644 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenTestManager.m +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/GoldenTestManager.m @@ -30,6 +30,9 @@ - (instancetype)initWithLaunchArg:(NSString*)launchArg { @"--platform-view-cliprect" : @"platform_view_cliprect", @"--platform-view-cliprrect" : @"platform_view_cliprrect", @"--platform-view-clippath" : @"platform_view_clippath", + @"--platform-view-cliprrect-with-transform" : @"platform_view_cliprrect_with_transform", + @"--platform-view-cliprect-with-transform" : @"platform_view_cliprect_with_transform", + @"--platform-view-clippath-with-transform" : @"platform_view_clippath_with_transform", @"--platform-view-transform" : @"platform_view_transform", @"--platform-view-opacity" : @"platform_view_opacity", @"--platform-view-with-other-backdrop-filter" : @"platform_view_with_other_backdrop_filter", diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewUITests.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewUITests.m index 4da67c0ab1a72..cfec0aa1ca84b 100644 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewUITests.m +++ b/testing/scenario_app/ios/Scenarios/ScenariosUITests/PlatformViewUITests.m @@ -134,6 +134,60 @@ - (void)testPlatformView { @end +@interface PlatformViewMutationClipRectWithTransformTests : GoldenPlatformViewTests + +@end + +@implementation PlatformViewMutationClipRectWithTransformTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = + [[GoldenTestManager alloc] initWithLaunchArg:@"--platform-view-cliprect-with-transform"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + +@interface PlatformViewMutationClipRRectWithTransformTests : GoldenPlatformViewTests + +@end + +@implementation PlatformViewMutationClipRRectWithTransformTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = + [[GoldenTestManager alloc] initWithLaunchArg:@"--platform-view-cliprrect-with-transform"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + +@interface PlatformViewMutationClipPathWithTransformTests : GoldenPlatformViewTests + +@end + +@implementation PlatformViewMutationClipPathWithTransformTests + +- (instancetype)initWithInvocation:(NSInvocation*)invocation { + GoldenTestManager* manager = + [[GoldenTestManager alloc] initWithLaunchArg:@"--platform-view-clippath-with-transform"]; + return [super initWithManager:manager invocation:invocation]; +} + +- (void)testPlatformView { + [self checkPlatformViewGolden]; +} + +@end + @interface PlatformViewMutationTransformTests : GoldenPlatformViewTests @end diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_with_transform_iPhone 8_13.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_with_transform_iPhone 8_13.0_simulator.png new file mode 100644 index 0000000000000000000000000000000000000000..b494f84298ea530db5fcc9793f7657f531d0238c GIT binary patch literal 18254 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 literal 0 HcmV?d00001 diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_with_transform_iPhone 8_13.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprect_with_transform_iPhone 8_13.0_simulator.png new file mode 100644 index 0000000000000000000000000000000000000000..883528a1882184c5e8af6d258ce3d00556111641 GIT binary patch literal 18794 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 VWENT(<3zZZn(}?6JO%TY{|D>>QAhv) literal 0 HcmV?d00001 diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprrect_with_transform_iPhone 8_13.0_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_cliprrect_with_transform_iPhone 8_13.0_simulator.png new file mode 100644 index 0000000000000000000000000000000000000000..b3adaa22e1b3cead0496722aa1245d0dd1dd8956 GIT binary patch literal 18730 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 V=f15A?!OZvQB``NSgc_7@_+R?4H*Cc literal 0 HcmV?d00001 diff --git a/testing/scenario_app/lib/src/platform_view.dart b/testing/scenario_app/lib/src/platform_view.dart index 11d2267942779..7e989b6998ed8 100644 --- a/testing/scenario_app/lib/src/platform_view.dart +++ b/testing/scenario_app/lib/src/platform_view.dart @@ -620,7 +620,7 @@ class PlatformViewClipRRectScenario extends PlatformViewScenario { /// Platform view with clip path. class PlatformViewClipPathScenario extends PlatformViewScenario { - /// Constructs a platform view with clip rrect scenario. + /// Constructs a platform view with clip path scenario. PlatformViewClipPathScenario( PlatformDispatcher dispatcher, { int id = 0, @@ -645,6 +645,135 @@ class PlatformViewClipPathScenario extends PlatformViewScenario { } } +/// Platform view with clip rect after transformed. +class PlatformViewClipRectWithTransformScenario extends PlatformViewScenario { + /// Constructs a platform view with clip rect with transform scenario. + PlatformViewClipRectWithTransformScenario( + PlatformDispatcher dispatcher, { + int id = 0, + }) : super(dispatcher, id: id); + + @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)); + + addPlatformView( + id, + dispatcher: dispatcher, + 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. + PlatformViewClipRRectWithTransformScenario( + PlatformDispatcher dispatcher, { + int id = 0, + }) : super(dispatcher, id: id); + + @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), + ), + ); + addPlatformView( + id, + dispatcher: dispatcher, + 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( + PlatformDispatcher dispatcher, { + int id = 0, + }) : super(dispatcher, id: id); + + @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: dispatcher, + 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 transform. class PlatformViewTransformScenario extends PlatformViewScenario { /// Constructs a platform view with transform scenario. diff --git a/testing/scenario_app/lib/src/scenarios.dart b/testing/scenario_app/lib/src/scenarios.dart index cbf4e6f528658..c992eea814fcd 100644 --- a/testing/scenario_app/lib/src/scenarios.dart +++ b/testing/scenario_app/lib/src/scenarios.dart @@ -31,8 +31,11 @@ Map _scenarios = { 'platform_view_multiple_without_overlays': () => MultiPlatformViewWithoutOverlaysScenario(PlatformDispatcher.instance, firstId: _viewId++, secondId: _viewId++), 'platform_view_max_overlays': () => PlatformViewMaxOverlaysScenario(PlatformDispatcher.instance, id: _viewId++), 'platform_view_cliprect': () => PlatformViewClipRectScenario(PlatformDispatcher.instance, id: _viewId++), + 'platform_view_cliprect_with_transform': () => PlatformViewClipRectWithTransformScenario(PlatformDispatcher.instance, id: _viewId++), 'platform_view_cliprrect': () => PlatformViewClipRRectScenario(PlatformDispatcher.instance, id: _viewId++), + 'platform_view_cliprrect_with_transform': () => PlatformViewClipRRectWithTransformScenario(PlatformDispatcher.instance, id: _viewId++), 'platform_view_clippath': () => PlatformViewClipPathScenario(PlatformDispatcher.instance, id: _viewId++), + 'platform_view_clippath_with_transform': () => PlatformViewClipPathWithTransformScenario(PlatformDispatcher.instance, id: _viewId++), 'platform_view_transform': () => PlatformViewTransformScenario(PlatformDispatcher.instance, id: _viewId++), 'platform_view_opacity': () => PlatformViewOpacityScenario(PlatformDispatcher.instance, id: _viewId++), 'platform_view_with_other_backdrop_filter': () => PlatformViewWithOtherBackDropFilter(PlatformDispatcher.instance, id: _viewId++), From e93023a67bbc0f5b4c6c8d65a8bf2522657cc369 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Thu, 17 Nov 2022 17:58:07 -0800 Subject: [PATCH 2/2] remove mistakenly checked-in code --- .../darwin/ios/framework/Source/FlutterEngine.mm | 15 +++++++-------- .../ios/framework/Source/FlutterPlatformViews.mm | 1 - 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 7efe80c072e89..9a0352a360604 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -527,14 +527,13 @@ - (void)setupChannels { // This will be invoked once the shell is done setting up and the isolate ID // for the UI isolate is available. fml::WeakPtr weakSelf = [self getWeakPtr]; - __block FlutterBinaryMessageHandler handler; - handler = ^(NSData* message, FlutterBinaryReply reply) { - if (weakSelf) { - weakSelf.get().isolateId = [[FlutterStringCodec sharedInstance] decode:message]; - } - }; - Block_release(handler); - [_binaryMessenger setMessageHandlerOnChannel:@"flutter/isolate" binaryMessageHandler:handler]; + [_binaryMessenger setMessageHandlerOnChannel:@"flutter/isolate" + binaryMessageHandler:^(NSData* message, FlutterBinaryReply reply) { + if (weakSelf) { + weakSelf.get().isolateId = + [[FlutterStringCodec sharedInstance] decode:message]; + } + }]; _localizationChannel.reset([[FlutterMethodChannel alloc] initWithName:@"flutter/localization" diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index 12bdf28269d67..9208bbf0f89e1 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -800,7 +800,6 @@ static bool ClipBoundsContainsPlatformViewBoundingRect(const SkRect& clip_bounds return layer; } SkCanvas* overlay_canvas = frame->SkiaCanvas(); - overlay_canvas->clipRect(rect); overlay_canvas->clear(SK_ColorTRANSPARENT); if (frame->GetDisplayListBuilder()) { slice->render_into(frame->GetDisplayListBuilder().get());