Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit d2e8e43

Browse files
author
Chris Yang
committed
test
1 parent faf1f50 commit d2e8e43

File tree

2 files changed

+109
-1
lines changed

2 files changed

+109
-1
lines changed

shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
1919
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
2020

21+
static const NSUInteger kFlutterClippingMaskViewPoolCapacity = 5;
22+
2123
@implementation UIView (FirstResponder)
2224
- (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
2325
if (self.isFirstResponder) {
@@ -445,7 +447,8 @@ static bool ClipBoundsContainsPlatformViewBoundingRect(const SkRect& clip_bounds
445447
FML_DCHECK(!clipView.maskView ||
446448
[clipView.maskView isKindOfClass:[FlutterClippingMaskView class]]);
447449
if (mask_view_pool_.get() == nil) {
448-
mask_view_pool_.reset([[FlutterClippingMaskViewPool alloc] initWithCapacity:5]);
450+
mask_view_pool_.reset([[FlutterClippingMaskViewPool alloc]
451+
initWithCapacity:kFlutterClippingMaskViewPoolCapacity]);
449452
}
450453
[mask_view_pool_.get() recycleMaskViews];
451454
clipView.maskView = nil;

shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2384,6 +2384,111 @@ - (void)testHasFirstResponderInViewHierarchySubtree_descendantViewBecomesFirstRe
23842384
XCTAssertFalse(view.flt_hasFirstResponderInViewHierarchySubtree);
23852385
}
23862386

2387+
- (void)testFlutterClippingMaskViewPoolReuseViewsAfterRecycle {
2388+
FlutterClippingMaskViewPool* pool =
2389+
[[[FlutterClippingMaskViewPool alloc] initWithCapacity:2] autorelease];
2390+
FlutterClippingMaskView* view1 = [pool getMaskViewWithFrame:CGRectZero];
2391+
FlutterClippingMaskView* view2 = [pool getMaskViewWithFrame:CGRectZero];
2392+
[pool recycleMaskViews];
2393+
CGRect newRect = CGRectMake(0, 0, 10, 10);
2394+
FlutterClippingMaskView* view3 = [pool getMaskViewWithFrame:newRect];
2395+
FlutterClippingMaskView* view4 = [pool getMaskViewWithFrame:newRect];
2396+
XCTAssertEqual(view1, view3);
2397+
XCTAssertEqual(view2, view4);
2398+
XCTAssertTrue(CGRectEqualToRect(view3.frame, newRect));
2399+
XCTAssertTrue(CGRectEqualToRect(view4.frame, newRect));
2400+
}
2401+
2402+
- (void)testFlutterClippingMaskViewPoolAllocsNewMaskViewsAfterReachingCapacity {
2403+
FlutterClippingMaskViewPool* pool =
2404+
[[[FlutterClippingMaskViewPool alloc] initWithCapacity:2] autorelease];
2405+
FlutterClippingMaskView* view1 = [pool getMaskViewWithFrame:CGRectZero];
2406+
FlutterClippingMaskView* view2 = [pool getMaskViewWithFrame:CGRectZero];
2407+
FlutterClippingMaskView* view3 = [pool getMaskViewWithFrame:CGRectZero];
2408+
XCTAssertNotEqual(view1, view3);
2409+
XCTAssertNotEqual(view2, view3);
2410+
}
2411+
2412+
- (void)testClipMaskViewIsReused {
2413+
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
2414+
auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest");
2415+
flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
2416+
/*platform=*/thread_task_runner,
2417+
/*raster=*/thread_task_runner,
2418+
/*ui=*/thread_task_runner,
2419+
/*io=*/thread_task_runner);
2420+
auto flutterPlatformViewsController = std::make_shared<flutter::FlutterPlatformViewsController>();
2421+
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
2422+
/*delegate=*/mock_delegate,
2423+
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
2424+
/*platform_views_controller=*/flutterPlatformViewsController,
2425+
/*task_runners=*/runners);
2426+
2427+
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
2428+
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
2429+
flutterPlatformViewsController->RegisterViewFactory(
2430+
factory, @"MockFlutterPlatformView",
2431+
FlutterPlatformViewGestureRecognizersBlockingPolicyEager);
2432+
FlutterResult result = ^(id result) {
2433+
};
2434+
flutterPlatformViewsController->OnMethodCall(
2435+
[FlutterMethodCall
2436+
methodCallWithMethodName:@"create"
2437+
arguments:@{@"id" : @1, @"viewType" : @"MockFlutterPlatformView"}],
2438+
result);
2439+
2440+
XCTAssertNotNil(gMockPlatformView);
2441+
UIView* mockFlutterView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)] autorelease];
2442+
flutterPlatformViewsController->SetFlutterView(mockFlutterView);
2443+
// Create embedded view params
2444+
flutter::MutatorsStack stack1;
2445+
// Layer tree always pushes a screen scale factor to the stack
2446+
SkMatrix screenScaleMatrix =
2447+
SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
2448+
stack1.PushTransform(screenScaleMatrix);
2449+
// Push a clip rect
2450+
SkRect rect = SkRect::MakeXYWH(2, 2, 3, 3);
2451+
stack1.PushClipRect(rect);
2452+
2453+
auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
2454+
screenScaleMatrix, SkSize::Make(10, 10), stack1);
2455+
2456+
flutter::MutatorsStack stack2;
2457+
auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
2458+
screenScaleMatrix, SkSize::Make(10, 10), stack2);
2459+
2460+
flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams1));
2461+
flutterPlatformViewsController->CompositeEmbeddedView(1);
2462+
UIView* childClippingView1 = gMockPlatformView.superview.superview;
2463+
UIView* maskView1 = childClippingView1.maskView;
2464+
XCTAssertNotNil(maskView1);
2465+
2466+
// Composite a new frame.
2467+
auto embeddedViewParams3 = std::make_unique<flutter::EmbeddedViewParams>(
2468+
screenScaleMatrix, SkSize::Make(10, 10), stack2);
2469+
flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams3));
2470+
flutterPlatformViewsController->CompositeEmbeddedView(1);
2471+
childClippingView1 = gMockPlatformView.superview.superview;
2472+
2473+
// This overrides gMockPlatformView to point to the newly created platform view.
2474+
flutterPlatformViewsController->OnMethodCall(
2475+
[FlutterMethodCall
2476+
methodCallWithMethodName:@"create"
2477+
arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}],
2478+
result);
2479+
2480+
auto embeddedViewParams4 = std::make_unique<flutter::EmbeddedViewParams>(
2481+
screenScaleMatrix, SkSize::Make(10, 10), stack1);
2482+
flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams4));
2483+
flutterPlatformViewsController->CompositeEmbeddedView(2);
2484+
UIView* childClippingView2 = gMockPlatformView.superview.superview;
2485+
2486+
UIView* maskView2 = childClippingView2.maskView;
2487+
XCTAssertEqual(maskView1, maskView2);
2488+
XCTAssertNotNil(childClippingView2.maskView);
2489+
XCTAssertNil(childClippingView1.maskView);
2490+
}
2491+
23872492
// Return true if a correct visual effect view is found. It also implies all the validation in this
23882493
// method passes.
23892494
//

0 commit comments

Comments
 (0)