diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index 16ce9ba0dd..d6ec9b5ddf 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -209,10 +209,6 @@ static BOOL _preparedOnce = NO; CGRect rectSoFar_; } -- (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; @@ -473,12 +469,11 @@ static BOOL _preparedOnce = NO; return self; } -- (FlutterClippingMaskView*)getMaskViewWithFrame:(CGRect)frame { +- (FlutterClippingMaskView*)getMaskViewWithFrame:(CGRect)frame screenScale:(CGFloat)screenScale { FML_DCHECK(self.pool.count <= self.capacity); if (self.pool.count == 0) { // The pool is empty, alloc a new one. - return [[FlutterClippingMaskView alloc] initWithFrame:frame - screenScale:UIScreen.mainScreen.scale]; + return [[FlutterClippingMaskView alloc] initWithFrame:frame screenScale:screenScale]; } FlutterClippingMaskView* maskView = [self.pool anyObject]; maskView.frame = frame; diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm index 7a452ba744..abe3571ae5 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm @@ -11,6 +11,7 @@ #include "flutter/fml/synchronization/count_down_latch.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/UIViewController+FlutterScreenAndSceneIfLoaded.h" #include "flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.h" #import "flutter/shell/platform/darwin/ios/ios_surface.h" @@ -248,7 +249,8 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, /// Runs on the platform thread. - (void)createLayerWithIosContext:(const std::shared_ptr&)iosContext grContext:(GrDirectContext*)grContext - pixelFormat:(MTLPixelFormat)pixelFormat; + pixelFormat:(MTLPixelFormat)pixelFormat + screenScale:(CGFloat)screenScale; /// Removes overlay views and platform views that aren't needed in the current frame. /// Must run on the platform thread. @@ -561,7 +563,9 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, CGRect frame = CGRectMake(-clipView.frame.origin.x, -clipView.frame.origin.y, CGRectGetWidth(self.flutterView.bounds), CGRectGetHeight(self.flutterView.bounds)); - clipView.maskView = [self.maskViewPool getMaskViewWithFrame:frame]; + clipView.maskView = [self.maskViewPool + getMaskViewWithFrame:frame + screenScale:[self.flutterViewController flutterScreenIfViewLoaded].scale]; } - (void)applyMutators:(const flutter::MutatorsStack&)mutatorsStack @@ -582,7 +586,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, [self.maskViewPool insertViewToPoolIfNeeded:(FlutterClippingMaskView*)(clipView.maskView)]; clipView.maskView = nil; } - CGFloat screenScale = [UIScreen mainScreen].scale; + CGFloat screenScale = [self.flutterViewController flutterScreenIfViewLoaded].scale; auto iter = mutatorsStack.Begin(); while (iter != mutatorsStack.End()) { switch ((*iter)->GetType()) { @@ -698,7 +702,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, // when we apply the transforms matrix in |applyMutators:embeddedView:boundingRect|, we need // to remember to do a reverse translate. const SkRect& rect = params.finalBoundingRect(); - CGFloat screenScale = [UIScreen mainScreen].scale; + CGFloat screenScale = [self.flutterViewController flutterScreenIfViewLoaded].scale; clippingView.frame = CGRectMake(rect.x() / screenScale, rect.y() / screenScale, rect.width() / screenScale, rect.height() / screenScale); [self applyMutators:mutatorStack embeddedView:touchInterceptor boundingRect:rect]; @@ -860,7 +864,8 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, for (auto i = 0u; i < missingLayerCount; i++) { [self createLayerWithIosContext:iosContext grContext:grContext - pixelFormat:((FlutterView*)self.flutterView).pixelFormat]; + pixelFormat:((FlutterView*)self.flutterView).pixelFormat + screenScale:((FlutterView*)self.flutterView).screen.scale]; } latch->CountDown(); }); @@ -965,8 +970,9 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, - (void)createLayerWithIosContext:(const std::shared_ptr&)iosContext grContext:(GrDirectContext*)grContext - pixelFormat:(MTLPixelFormat)pixelFormat { - self.layerPool->CreateLayer(grContext, iosContext, pixelFormat); + pixelFormat:(MTLPixelFormat)pixelFormat + screenScale:(CGFloat)screenScale { + self.layerPool->CreateLayer(grContext, iosContext, pixelFormat, screenScale); } - (void)removeUnusedLayers:(const std::vector>&)unusedLayers diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index 98bbf6b85e..2f0e413be1 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -234,6 +234,24 @@ const float kFloatCompareEpsilon = 0.001; } @end +@interface FlutterPlatformViewsTestMockFlutterViewController : FlutterViewController + +- (UIScreen*)flutterScreenIfViewLoaded; + +@end + +@implementation FlutterPlatformViewsTestMockFlutterViewController + +- (UIScreen*)flutterScreenIfViewLoaded { + UIScreen* mockScreen = OCMClassMock([UIScreen class]); + CGFloat screenScale = 3; + OCMStub([mockScreen scale]).andReturn(screenScale); + + return mockScreen; +} + +@end + namespace flutter { namespace { class FlutterPlatformViewsTestMockPlatformViewDelegate : public PlatformView::Delegate { @@ -329,13 +347,16 @@ fml::RefPtr GetDefaultTaskRunner() { @"viewType" : @"MockFlutterPlatformView" }] result:result]; + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; flutterPlatformViewsController.flutterView = 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a translate matrix SkMatrix translateMatrix = SkMatrix::Translate(100, 100); @@ -490,12 +511,15 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack - CGFloat screenScale = [UIScreen mainScreen].scale; + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a backdrop filter @@ -573,12 +597,15 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack - CGFloat screenScale = [UIScreen mainScreen].scale; + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a backdrop filter @@ -656,12 +683,15 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack - CGFloat screenScale = [UIScreen mainScreen].scale; + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push backdrop filters @@ -740,12 +770,15 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack - CGFloat screenScale = [UIScreen mainScreen].scale; + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a backdrop filter @@ -869,12 +902,15 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack - CGFloat screenScale = [UIScreen mainScreen].scale; + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push backdrop filters @@ -1025,12 +1061,15 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack - CGFloat screenScale = [UIScreen mainScreen].scale; + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push backdrop filters @@ -1326,12 +1365,15 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack - CGFloat screenScale = [UIScreen mainScreen].scale; + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a dilate backdrop filter @@ -1659,13 +1701,16 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; flutterPlatformViewsController.flutterView = 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a translate matrix SkMatrix translateMatrix = SkMatrix::Translate(100, 100); @@ -1726,12 +1771,15 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = flutterView; // Create embedded view params flutter::MutatorsStack stack; // Layer tree always pushes a screen scale factor to the stack - CGFloat screenScale = [UIScreen mainScreen].scale; + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); @@ -1836,13 +1884,16 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; flutterPlatformViewsController.flutterView = 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a rotate matrix SkMatrix rotateMatrix; @@ -1918,13 +1969,16 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)]; flutterPlatformViewsController.flutterView = 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); SkMatrix translateMatrix = SkMatrix::Translate(5, 5); // The platform view's rect for this test will be (5, 5, 10, 10). @@ -1996,13 +2050,16 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)]; flutterPlatformViewsController.flutterView = 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); SkMatrix translateMatrix = SkMatrix::Translate(5, 5); // The platform view's rect for this test will be (5, 5, 10, 10). @@ -2073,13 +2130,16 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a clip rect SkRect rect = SkRect::MakeXYWH(2, 2, 3, 3); @@ -2155,13 +2215,16 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a clip rect SkRect rect1 = SkRect::MakeXYWH(2, 2, 3, 3); @@ -2257,13 +2320,16 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a clip rrect SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(2, 2, 6, 6), 1, 1); @@ -2366,13 +2432,16 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a clip rrect SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(2, 2, 6, 6), 1, 1); @@ -2492,13 +2561,16 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a clip path SkPath path; @@ -2602,13 +2674,16 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a clip path SkPath path; @@ -3473,6 +3548,10 @@ fml::RefPtr GetDefaultTaskRunner() { XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; + // Create embedded view params flutter::MutatorsStack stack; SkMatrix finalMatrix; @@ -3596,6 +3675,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*worker_task_runner=*/nil, /*is_gpu_disabled_jsync_switch=*/std::make_shared()); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; flutterPlatformViewsController.flutterView = flutterView; @@ -3667,6 +3749,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*worker_task_runner=*/nil, /*is_gpu_disabled_jsync_switch=*/std::make_shared()); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; flutterPlatformViewsController.flutterView = flutterView; @@ -3782,6 +3867,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*worker_task_runner=*/nil, /*is_gpu_disabled_jsync_switch=*/std::make_shared()); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; flutterPlatformViewsController.flutterView = flutterView; @@ -3926,13 +4014,13 @@ fml::RefPtr GetDefaultTaskRunner() { - (void)testFlutterClippingMaskViewPoolReuseViewsAfterRecycle { FlutterClippingMaskViewPool* pool = [[FlutterClippingMaskViewPool alloc] initWithCapacity:2]; - FlutterClippingMaskView* view1 = [pool getMaskViewWithFrame:CGRectZero]; - FlutterClippingMaskView* view2 = [pool getMaskViewWithFrame:CGRectZero]; + FlutterClippingMaskView* view1 = [pool getMaskViewWithFrame:CGRectZero screenScale:1]; + FlutterClippingMaskView* view2 = [pool getMaskViewWithFrame:CGRectZero screenScale:1]; [pool insertViewToPoolIfNeeded:view1]; [pool insertViewToPoolIfNeeded:view2]; CGRect newRect = CGRectMake(0, 0, 10, 10); - FlutterClippingMaskView* view3 = [pool getMaskViewWithFrame:newRect]; - FlutterClippingMaskView* view4 = [pool getMaskViewWithFrame:newRect]; + FlutterClippingMaskView* view3 = [pool getMaskViewWithFrame:newRect screenScale:1]; + FlutterClippingMaskView* view4 = [pool getMaskViewWithFrame:newRect screenScale:1]; // view3 and view4 should randomly get either of view1 and view2. NSSet* set1 = [NSSet setWithObjects:view1, view2, nil]; NSSet* set2 = [NSSet setWithObjects:view3, view4, nil]; @@ -3943,9 +4031,9 @@ fml::RefPtr GetDefaultTaskRunner() { - (void)testFlutterClippingMaskViewPoolAllocsNewMaskViewsAfterReachingCapacity { FlutterClippingMaskViewPool* pool = [[FlutterClippingMaskViewPool alloc] initWithCapacity:2]; - FlutterClippingMaskView* view1 = [pool getMaskViewWithFrame:CGRectZero]; - FlutterClippingMaskView* view2 = [pool getMaskViewWithFrame:CGRectZero]; - FlutterClippingMaskView* view3 = [pool getMaskViewWithFrame:CGRectZero]; + FlutterClippingMaskView* view1 = [pool getMaskViewWithFrame:CGRectZero screenScale:1]; + FlutterClippingMaskView* view2 = [pool getMaskViewWithFrame:CGRectZero screenScale:1]; + FlutterClippingMaskView* view3 = [pool getMaskViewWithFrame:CGRectZero screenScale:1]; XCTAssertNotEqual(view1, view3); XCTAssertNotEqual(view2, view3); } @@ -3954,7 +4042,7 @@ fml::RefPtr GetDefaultTaskRunner() { __weak UIView* weakView; @autoreleasepool { FlutterClippingMaskViewPool* pool = [[FlutterClippingMaskViewPool alloc] initWithCapacity:2]; - FlutterClippingMaskView* view = [pool getMaskViewWithFrame:CGRectZero]; + FlutterClippingMaskView* view = [pool getMaskViewWithFrame:CGRectZero screenScale:1]; weakView = view; XCTAssertNotNil(weakView); } @@ -3999,13 +4087,16 @@ fml::RefPtr GetDefaultTaskRunner() { result:result]; XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = flutterView; // 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack1.PushTransform(screenScaleMatrix); // Push a clip rect SkRect rect = SkRect::MakeXYWH(2, 2, 3, 3); @@ -4114,13 +4205,16 @@ fml::RefPtr GetDefaultTaskRunner() { UIView* view2 = gMockPlatformView; XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = flutterView; // 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack1.PushTransform(screenScaleMatrix); // Push a clip rect SkRect rect = SkRect::MakeXYWH(2, 2, 3, 3); @@ -4193,13 +4287,16 @@ fml::RefPtr GetDefaultTaskRunner() { result:result]; XCTAssertNotNil(gMockPlatformView); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]; flutterPlatformViewsController.flutterView = flutterView; // 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack1.PushTransform(screenScaleMatrix); // Push a clip rect SkRect rect = SkRect::MakeXYWH(2, 2, 3, 3); @@ -4274,6 +4371,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*worker_task_runner=*/nil, /*is_gpu_disabled_jsync_switch=*/std::make_shared()); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; flutterPlatformViewsController.flutterView = flutterView; @@ -4414,13 +4514,16 @@ fml::RefPtr GetDefaultTaskRunner() { @"viewType" : @"MockFlutterPlatformView" }] result:result]; + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; flutterPlatformViewsController.flutterView = 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a translate matrix SkMatrix translateMatrix = SkMatrix::Translate(100, 100); @@ -4491,14 +4594,17 @@ fml::RefPtr GetDefaultTaskRunner() { @"viewType" : @"MockFlutterPlatformView" }] result:result]; + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; flutterPlatformViewsController.flutterView = 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); + CGFloat screenScale = [mockFlutterViewController flutterScreenIfViewLoaded].scale; + SkMatrix screenScaleMatrix = SkMatrix::Scale(screenScale, screenScale); stack.PushTransform(screenScaleMatrix); // Push a translate matrix SkMatrix translateMatrix = SkMatrix::Translate(100, 100); @@ -4546,9 +4652,9 @@ fml::RefPtr GetDefaultTaskRunner() { auto pool = flutter::OverlayLayerPool{}; // Add layers to the pool. - pool.CreateLayer(gr_context.get(), ios_context, MTLPixelFormatBGRA8Unorm); + pool.CreateLayer(gr_context.get(), ios_context, MTLPixelFormatBGRA8Unorm, 1); XCTAssertEqual(pool.size(), 1u); - pool.CreateLayer(gr_context.get(), ios_context, MTLPixelFormatBGRA8Unorm); + pool.CreateLayer(gr_context.get(), ios_context, MTLPixelFormatBGRA8Unorm, 1); XCTAssertEqual(pool.size(), 2u); // Mark all layers as unused. @@ -4582,6 +4688,9 @@ fml::RefPtr GetDefaultTaskRunner() { /*worker_task_runner=*/nil, /*is_gpu_disabled_jsync_switch=*/std::make_shared()); + FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController = + [[FlutterPlatformViewsTestMockFlutterViewController alloc] init]; + flutterPlatformViewsController.flutterViewController = mockFlutterViewController; UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; flutterPlatformViewsController.flutterView = flutterView; diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h index b23d532cf4..0ac51f4559 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h @@ -67,7 +67,7 @@ - (instancetype)initWithCapacity:(NSInteger)capacity; // Reuse a maskView from the pool, or allocate a new one. -- (FlutterClippingMaskView*)getMaskViewWithFrame:(CGRect)frame; +- (FlutterClippingMaskView*)getMaskViewWithFrame:(CGRect)frame screenScale:(CGFloat)screenScale; // Insert the `maskView` into the pool. - (void)insertViewToPoolIfNeeded:(FlutterClippingMaskView*)maskView; diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.h index 530dc782c6..c9137d0d2a 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.h @@ -65,7 +65,8 @@ class OverlayLayerPool { /// This method can only be called on the Platform thread. void CreateLayer(GrDirectContext* gr_context, const std::shared_ptr& ios_context, - MTLPixelFormat pixel_format); + MTLPixelFormat pixel_format, + CGFloat screenScale); /// @brief Removes unused layers from the pool. Returns the unused layers. std::vector> RemoveUnusedLayers(); diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.mm index ee409b778d..da5c518a04 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.mm @@ -5,6 +5,7 @@ #include "flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h" #import "flutter/shell/platform/darwin/ios/ios_surface.h" namespace flutter { @@ -22,7 +23,7 @@ void OverlayLayer::UpdateViewState(UIView* flutter_view, SkRect rect, int64_t view_id, int64_t overlay_id) { - auto screenScale = [UIScreen mainScreen].scale; + auto screenScale = ((FlutterView*)flutter_view).screen.scale; // Set the size of the overlay view wrapper. // This wrapper view masks the overlay view. overlay_view_wrapper.frame = CGRectMake(rect.x() / screenScale, rect.y() / screenScale, @@ -54,7 +55,8 @@ std::shared_ptr OverlayLayerPool::GetNextLayer() { void OverlayLayerPool::CreateLayer(GrDirectContext* gr_context, const std::shared_ptr& ios_context, - MTLPixelFormat pixel_format) { + MTLPixelFormat pixel_format, + CGFloat screenScale) { FML_DCHECK([[NSThread currentThread] isMainThread]); std::shared_ptr layer; UIView* overlay_view; @@ -72,7 +74,6 @@ void OverlayLayerPool::CreateLayer(GrDirectContext* gr_context, layer = std::make_shared(overlay_view, overlay_view_wrapper, std::move(ios_surface), std::move(surface)); } else { - CGFloat screenScale = [UIScreen mainScreen].scale; overlay_view = [[FlutterOverlayView alloc] initWithContentsScale:screenScale pixelFormat:pixel_format]; overlay_view_wrapper = [[FlutterOverlayView alloc] initWithContentsScale:screenScale