replace deprecated [UIScreen mainScreen] in iOS (#162785)

<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

1. Replaced `mainScreen` in `FlutterPlatformViewsController` with the
`screeScale` of the `screen` that the `flutterViewController` is
attached to. Updated API usage of `FlutterClippingMaskViewPool` and
`OverlayLayerPool` by providing the correct `screenScale` from the
screen that the `flutterViewController` is attached to.
2. Replaced `mainScreen` in `OverlayLayerPool` by adding an API for the
`screenScale` to be provided by the class user.
3. Replaced `mainScreen` in `FlutterClippingMaskViewPool` by adding an
API for the `screenScale` to be provided by the class user.
4. Replaced `mainScreen` in `FlutterPlatformViewsTest` by adding a
mocked `FlutterViewController` which has a mocked `screen` with a mocked
`screenScale`. The `flutterViewController` is then provided the to the
`flutterPlatformViewsController`.

All of the above changes allow platform views and their overlays
displayed on an external screen to be properly scaled when rendered.

Fixes #130832. I believe this fixed #130825 since
FlutterPlatformViews_Internal.mm does not exist but the definition of
the interfaces declared in FlutterPlatformViews_Internal.h are part of
the files modified by this pr. This pr also replaces `mainScreen` in
`overlay_layer_pool.mm`.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [x] I updated/added new tests to check the change I am making, or this
PR is [test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
Dimitar Kyurtov 2025-02-19 22:41:44 +02:00 committed by GitHub
parent b4d05f4867
commit 3d2ab872b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 181 additions and 69 deletions

View File

@ -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;

View File

@ -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<flutter::IOSContext>&)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<flutter::IOSContext>&)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<std::shared_ptr<flutter::OverlayLayer>>&)unusedLayers

View File

@ -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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> GetDefaultTaskRunner() {
/*worker_task_runner=*/nil,
/*is_gpu_disabled_jsync_switch=*/std::make_shared<fml::SyncSwitch>());
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<fml::TaskRunner> GetDefaultTaskRunner() {
/*worker_task_runner=*/nil,
/*is_gpu_disabled_jsync_switch=*/std::make_shared<fml::SyncSwitch>());
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<fml::TaskRunner> GetDefaultTaskRunner() {
/*worker_task_runner=*/nil,
/*is_gpu_disabled_jsync_switch=*/std::make_shared<fml::SyncSwitch>());
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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> GetDefaultTaskRunner() {
/*worker_task_runner=*/nil,
/*is_gpu_disabled_jsync_switch=*/std::make_shared<fml::SyncSwitch>());
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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> 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<fml::TaskRunner> GetDefaultTaskRunner() {
/*worker_task_runner=*/nil,
/*is_gpu_disabled_jsync_switch=*/std::make_shared<fml::SyncSwitch>());
FlutterPlatformViewsTestMockFlutterViewController* mockFlutterViewController =
[[FlutterPlatformViewsTestMockFlutterViewController alloc] init];
flutterPlatformViewsController.flutterViewController = mockFlutterViewController;
UIView* flutterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
flutterPlatformViewsController.flutterView = flutterView;

View File

@ -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;

View File

@ -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<IOSContext>& ios_context,
MTLPixelFormat pixel_format);
MTLPixelFormat pixel_format,
CGFloat screenScale);
/// @brief Removes unused layers from the pool. Returns the unused layers.
std::vector<std::shared_ptr<OverlayLayer>> RemoveUnusedLayers();

View File

@ -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<OverlayLayer> OverlayLayerPool::GetNextLayer() {
void OverlayLayerPool::CreateLayer(GrDirectContext* gr_context,
const std::shared_ptr<IOSContext>& ios_context,
MTLPixelFormat pixel_format) {
MTLPixelFormat pixel_format,
CGFloat screenScale) {
FML_DCHECK([[NSThread currentThread] isMainThread]);
std::shared_ptr<OverlayLayer> layer;
UIView* overlay_view;
@ -72,7 +74,6 @@ void OverlayLayerPool::CreateLayer(GrDirectContext* gr_context,
layer = std::make_shared<OverlayLayer>(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