Skip to content

Commit

Permalink
recycle maskView at the begining of the frame
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Yang committed Apr 28, 2023
1 parent 1d25906 commit f384936
Show file tree
Hide file tree
Showing 12 changed files with 376 additions and 47 deletions.
Expand Up @@ -18,8 +18,6 @@
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
#import "flutter/shell/platform/darwin/ios/ios_surface.h"

static const NSUInteger kFlutterClippingMaskViewPoolCapacity = 5;

@implementation UIView (FirstResponder)
- (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
if (self.isFirstResponder) {
Expand Down Expand Up @@ -461,11 +459,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
NSMutableArray* blurFilters = [[[NSMutableArray alloc] init] autorelease];
FML_DCHECK(!clipView.maskView ||
[clipView.maskView isKindOfClass:[FlutterClippingMaskView class]]);
if (mask_view_pool_.get() == nil) {
mask_view_pool_.reset([[FlutterClippingMaskViewPool alloc]
initWithCapacity:kFlutterClippingMaskViewPoolCapacity]);
}
[mask_view_pool_.get() recycleMaskViews];

clipView.maskView = nil;
CGFloat screenScale = [UIScreen mainScreen].scale;
auto iter = mutators_stack.Begin();
Expand Down Expand Up @@ -899,6 +893,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
slices_.clear();
composition_order_.clear();
visited_platform_views_.clear();
[mask_view_pool_.get() recycleMaskViews];
}

} // namespace flutter
Expand Down
Expand Up @@ -2727,17 +2727,17 @@ - (void)testClipMaskViewIsReused {
auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
screenScaleMatrix, SkSize::Make(10, 10), stack1);

flutter::MutatorsStack stack2;
auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
screenScaleMatrix, SkSize::Make(10, 10), stack2);

flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams1));
flutterPlatformViewsController->CompositeEmbeddedView(1);
UIView* childClippingView1 = gMockPlatformView.superview.superview;
UIView* maskView1 = childClippingView1.maskView;
XCTAssertNotNil(maskView1);

// Composite a new frame.
flutterPlatformViewsController->BeginFrame(SkISize::Make(100, 100));
flutter::MutatorsStack stack2;
auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
screenScaleMatrix, SkSize::Make(10, 10), stack2);
auto embeddedViewParams3 = std::make_unique<flutter::EmbeddedViewParams>(
screenScaleMatrix, SkSize::Make(10, 10), stack2);
flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams3));
Expand All @@ -2763,6 +2763,77 @@ - (void)testClipMaskViewIsReused {
XCTAssertNil(childClippingView1.maskView);
}

- (void)testDifferentClipMaskViewIsUsedForEachView {
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<flutter::FlutterPlatformViewsController>();
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
/*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" : @1, @"viewType" : @"MockFlutterPlatformView"}],
result);
UIView* view1 = gMockPlatformView;

// This overwrites `gMockPlatformView` to another view.
flutterPlatformViewsController->OnMethodCall(
[FlutterMethodCall
methodCallWithMethodName:@"create"
arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}],
result);
UIView* view2 = gMockPlatformView;

XCTAssertNotNil(gMockPlatformView);
UIView* mockFlutterView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)] autorelease];
flutterPlatformViewsController->SetFlutterView(mockFlutterView);
// Create embedded view params
flutter::MutatorsStack stack1;
// Layer tree always pushes a screen scale factor to the stack
SkMatrix screenScaleMatrix =
SkMatrix::Scale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale);
stack1.PushTransform(screenScaleMatrix);
// Push a clip rect
SkRect rect = SkRect::MakeXYWH(2, 2, 3, 3);
stack1.PushClipRect(rect);

auto embeddedViewParams1 = std::make_unique<flutter::EmbeddedViewParams>(
screenScaleMatrix, SkSize::Make(10, 10), stack1);

flutter::MutatorsStack stack2;
stack2.PushClipRect(rect);
auto embeddedViewParams2 = std::make_unique<flutter::EmbeddedViewParams>(
screenScaleMatrix, SkSize::Make(10, 10), stack2);

flutterPlatformViewsController->PrerollCompositeEmbeddedView(1, std::move(embeddedViewParams1));
flutterPlatformViewsController->CompositeEmbeddedView(1);
UIView* childClippingView1 = view1.superview.superview;

flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams2));
flutterPlatformViewsController->CompositeEmbeddedView(2);
UIView* childClippingView2 = view2.superview.superview;
UIView* maskView1 = childClippingView1.maskView;
UIView* maskView2 = childClippingView2.maskView;
XCTAssertNotEqual(maskView1, maskView2);
}

// Return true if a correct visual effect view is found. It also implies all the validation in this
// method passes.
//
Expand Down
Expand Up @@ -9,6 +9,7 @@
#import "flutter/shell/platform/darwin/ios/ios_surface.h"

static int kMaxPointsInVerb = 4;
static const NSUInteger kFlutterClippingMaskViewPoolCapacity = 5;

namespace flutter {

Expand All @@ -26,7 +27,10 @@

FlutterPlatformViewsController::FlutterPlatformViewsController()
: layer_pool_(std::make_unique<FlutterPlatformViewLayerPool>()),
weak_factory_(std::make_unique<fml::WeakPtrFactory<FlutterPlatformViewsController>>(this)){};
weak_factory_(std::make_unique<fml::WeakPtrFactory<FlutterPlatformViewsController>>(this)) {
mask_view_pool_.reset(
[[FlutterClippingMaskViewPool alloc] initWithCapacity:kFlutterClippingMaskViewPoolCapacity]);
};

FlutterPlatformViewsController::~FlutterPlatformViewsController() = default;

Expand Down
Expand Up @@ -38,6 +38,9 @@
6816DBA12317573300A51400 /* GoldenImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 6816DBA02317573300A51400 /* GoldenImage.m */; };
6816DBA42318358200A51400 /* GoldenTestManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6816DBA32318358200A51400 /* GoldenTestManager.m */; };
682C5873299C182A00915E5C /* golden_platform_view_cliprect_after_moved_iPhone 8_16.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 682C5872299C182A00915E5C /* golden_platform_view_cliprect_after_moved_iPhone 8_16.0_simulator.png */; };
684FFF9329FB89EF00281002 /* golden_two_platform_view_clip_rrect_iPhone 8_16.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 684FFF9029FB89EE00281002 /* golden_two_platform_view_clip_rrect_iPhone 8_16.0_simulator.png */; };
684FFF9429FB89EF00281002 /* golden_two_platform_view_clip_path_iPhone 8_16.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 684FFF9129FB89EF00281002 /* golden_two_platform_view_clip_path_iPhone 8_16.0_simulator.png */; };
684FFF9529FB89EF00281002 /* golden_two_platform_view_clip_rect_iPhone 8_16.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 684FFF9229FB89EF00281002 /* golden_two_platform_view_clip_rect_iPhone 8_16.0_simulator.png */; };
685B9F392977B73100B45442 /* golden_platform_view_large_cliprrect_with_transform_iPhone 8_16.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 685B9F372977B73100B45442 /* golden_platform_view_large_cliprrect_with_transform_iPhone 8_16.0_simulator.png */; };
685B9F3A2977B73100B45442 /* golden_platform_view_large_cliprrect_iPhone 8_16.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 685B9F382977B73100B45442 /* golden_platform_view_large_cliprrect_iPhone 8_16.0_simulator.png */; };
687AF8E9291EBDE0003912C7 /* golden_platform_view_clippath_with_transform_iPhone 8_16.0_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 687AF8E8291EBDE0003912C7 /* golden_platform_view_clippath_with_transform_iPhone 8_16.0_simulator.png */; };
Expand Down Expand Up @@ -155,6 +158,9 @@
6816DBA22318358200A51400 /* GoldenTestManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GoldenTestManager.h; sourceTree = "<group>"; };
6816DBA32318358200A51400 /* GoldenTestManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoldenTestManager.m; sourceTree = "<group>"; };
682C5872299C182A00915E5C /* golden_platform_view_cliprect_after_moved_iPhone 8_16.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_after_moved_iPhone 8_16.0_simulator.png"; sourceTree = "<group>"; };
684FFF9029FB89EE00281002 /* golden_two_platform_view_clip_rrect_iPhone 8_16.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_two_platform_view_clip_rrect_iPhone 8_16.0_simulator.png"; sourceTree = "<group>"; };
684FFF9129FB89EF00281002 /* golden_two_platform_view_clip_path_iPhone 8_16.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_two_platform_view_clip_path_iPhone 8_16.0_simulator.png"; sourceTree = "<group>"; };
684FFF9229FB89EF00281002 /* golden_two_platform_view_clip_rect_iPhone 8_16.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_two_platform_view_clip_rect_iPhone 8_16.0_simulator.png"; sourceTree = "<group>"; };
685B9F372977B73100B45442 /* golden_platform_view_large_cliprrect_with_transform_iPhone 8_16.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_large_cliprrect_with_transform_iPhone 8_16.0_simulator.png"; sourceTree = "<group>"; };
685B9F382977B73100B45442 /* golden_platform_view_large_cliprrect_iPhone 8_16.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_large_cliprrect_iPhone 8_16.0_simulator.png"; sourceTree = "<group>"; };
687AF8E8291EBDE0003912C7 /* golden_platform_view_clippath_with_transform_iPhone 8_16.0_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_clippath_with_transform_iPhone 8_16.0_simulator.png"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -302,6 +308,9 @@
F7B464DC2759D02B00079189 /* Goldens */ = {
isa = PBXGroup;
children = (
684FFF9129FB89EF00281002 /* golden_two_platform_view_clip_path_iPhone 8_16.0_simulator.png */,
684FFF9229FB89EF00281002 /* golden_two_platform_view_clip_rect_iPhone 8_16.0_simulator.png */,
684FFF9029FB89EE00281002 /* golden_two_platform_view_clip_rrect_iPhone 8_16.0_simulator.png */,
682C5872299C182A00915E5C /* golden_platform_view_cliprect_after_moved_iPhone 8_16.0_simulator.png */,
685B9F382977B73100B45442 /* golden_platform_view_large_cliprrect_iPhone 8_16.0_simulator.png */,
685B9F372977B73100B45442 /* golden_platform_view_large_cliprrect_with_transform_iPhone 8_16.0_simulator.png */,
Expand Down Expand Up @@ -461,15 +470,18 @@
F7B464EE2759D0A900079189 /* golden_platform_view_transform_iPhone 8_16.0_simulator.png in Resources */,
F7B464F32759D0A900079189 /* golden_platform_view_multiple_background_foreground_iPhone 8_16.0_simulator.png in Resources */,
F7B464F72759D0A900079189 /* golden_platform_view_rotate_iPhone 8_16.0_simulator.png in Resources */,
684FFF9329FB89EF00281002 /* golden_two_platform_view_clip_rrect_iPhone 8_16.0_simulator.png in Resources */,
F7B464ED2759D0A900079189 /* golden_platform_view_cliprrect_iPhone 8_16.0_simulator.png in Resources */,
685B9F3A2977B73100B45442 /* golden_platform_view_large_cliprrect_iPhone 8_16.0_simulator.png in Resources */,
68D5003F291ED645001ACFE1 /* golden_platform_view_cliprrect_with_transform_iPhone 8_16.0_simulator.png in Resources */,
F7B464EB2759D0A900079189 /* golden_two_platform_views_with_other_backdrop_filter_iPhone 8_16.0_simulator.png in Resources */,
684FFF9529FB89EF00281002 /* golden_two_platform_view_clip_rect_iPhone 8_16.0_simulator.png in Resources */,
F7B464F42759D0A900079189 /* golden_platform_view_with_other_backdrop_filter_iPhone 8_16.0_simulator.png in Resources */,
687AF8E9291EBDE0003912C7 /* golden_platform_view_clippath_with_transform_iPhone 8_16.0_simulator.png in Resources */,
685B9F392977B73100B45442 /* golden_platform_view_large_cliprrect_with_transform_iPhone 8_16.0_simulator.png in Resources */,
F769EB53276312BB007AC10F /* golden_platform_view_cliprect_iPhone 8_16.0_simulator.png in Resources */,
F7B464EF2759D0A900079189 /* golden_platform_view_multiple_iPhone 8_16.0_simulator.png in Resources */,
684FFF9429FB89EF00281002 /* golden_two_platform_view_clip_path_iPhone 8_16.0_simulator.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
5 changes: 4 additions & 1 deletion testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m
Expand Up @@ -69,7 +69,10 @@ - (BOOL)application:(UIApplication*)application
@"--spawn-engine-works" : @"spawn_engine_works",
@"--pointer-events" : @"pointer_events",
@"--platform-view-scrolling-under-widget" : @"platform_view_scrolling_under_widget",
@"--platform-view-cliprect-after-moved" : @"platform_view_cliprect_after_moved"
@"--platform-view-cliprect-after-moved" : @"platform_view_cliprect_after_moved",
@"--two-platform-view-clip-rect" : @"two_platform_view_clip_rect",
@"--two-platform-view-clip-rrect" : @"two_platform_view_clip_rrect",
@"--two-platform-view-clip-path" : @"two_platform_view_clip_path",
};
__block NSString* flutterViewControllerTestName = nil;
[launchArgsMap
Expand Down
Expand Up @@ -47,6 +47,9 @@ - (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",
@"--two-platform-view-clip-rect" : @"two_platform_view_clip_rect",
@"--two-platform-view-clip-rrect" : @"two_platform_view_clip_rrect",
@"--two-platform-view-clip-path" : @"two_platform_view_clip_path",
};
});
_identifier = launchArgsMap[launchArg];
Expand Down
Expand Up @@ -254,6 +254,60 @@ - (void)testPlatformView {

@end

@interface TwoPlatformViewClipRectTests : GoldenPlatformViewTests

@end

@implementation TwoPlatformViewClipRectTests

- (instancetype)initWithInvocation:(NSInvocation*)invocation {
GoldenTestManager* manager =
[[GoldenTestManager alloc] initWithLaunchArg:@"--two-platform-view-clip-rect"];
return [super initWithManager:manager invocation:invocation];
}

- (void)testPlatformView {
[self checkPlatformViewGolden];
}

@end

@interface TwoPlatformViewClipRRectTests : GoldenPlatformViewTests

@end

@implementation TwoPlatformViewClipRRectTests

- (instancetype)initWithInvocation:(NSInvocation*)invocation {
GoldenTestManager* manager =
[[GoldenTestManager alloc] initWithLaunchArg:@"--two-platform-view-clip-rrect"];
return [super initWithManager:manager invocation:invocation];
}

- (void)testPlatformView {
[self checkPlatformViewGolden];
}

@end

@interface TwoPlatformViewClipPathTests : GoldenPlatformViewTests

@end

@implementation TwoPlatformViewClipPathTests

- (instancetype)initWithInvocation:(NSInvocation*)invocation {
GoldenTestManager* manager =
[[GoldenTestManager alloc] initWithLaunchArg:@"--two-platform-view-clip-path"];
return [super initWithManager:manager invocation:invocation];
}

- (void)testPlatformView {
[self checkPlatformViewGolden];
}

@end

@interface PlatformViewMutationTransformTests : GoldenPlatformViewTests

@end
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit f384936

Please sign in to comment.