@@ -2384,6 +2384,111 @@ - (void)testHasFirstResponderInViewHierarchySubtree_descendantViewBecomesFirstRe
2384
2384
XCTAssertFalse (view.flt_hasFirstResponderInViewHierarchySubtree );
2385
2385
}
2386
2386
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
+
2387
2492
// Return true if a correct visual effect view is found. It also implies all the validation in this
2388
2493
// method passes.
2389
2494
//
0 commit comments