| Flutter iOS Embedder |

FlutterPlatformViews_Internal.mm
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h"
6
7 #include "flutter/display_list/effects/dl_image_filter.h"
8 #include "flutter/fml/platform/darwin/cf_utils.h"
9 #import "flutter/shell/platform/darwin/ios/ios_surface.h"
10
11 static constexpr int kMaxPointsInVerb = 4;
12 static constexpr NSUInteger kFlutterClippingMaskViewPoolCapacity = 5;
13
14 namespace flutter {
15
16 FlutterPlatformViewLayer::FlutterPlatformViewLayer(
17 const fml::scoped_nsobject<UIView>& overlay_view,
18 const fml::scoped_nsobject<UIView>& overlay_view_wrapper,
19 std::unique_ptr<IOSSurface> ios_surface,
20 std::unique_ptr<Surface> surface)
21 : overlay_view(overlay_view),
22 overlay_view_wrapper(overlay_view_wrapper),
23 ios_surface(std::move(ios_surface)),
24 surface(std::move(surface)){};
25
26 FlutterPlatformViewLayer::~FlutterPlatformViewLayer() = default;
27
28 FlutterPlatformViewsController::FlutterPlatformViewsController()
29 : layer_pool_(std::make_unique<FlutterPlatformViewLayerPool>()),
30 weak_factory_(std::make_unique<fml::WeakPtrFactory<FlutterPlatformViewsController>>(this)) {
31 mask_view_pool_.reset(
32 [[FlutterClippingMaskViewPool alloc] initWithCapacity:kFlutterClippingMaskViewPoolCapacity]);
33 };
34
35 FlutterPlatformViewsController::~FlutterPlatformViewsController() = default;
36
37 fml::WeakPtr<flutter::FlutterPlatformViewsController> FlutterPlatformViewsController::GetWeakPtr() {
38 return weak_factory_->GetWeakPtr();
39 }
40
41 CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix& matrix) {
42 // Skia only supports 2D transform so we don't map z.
43 CATransform3D transform = CATransform3DIdentity;
44 transform.m11 = matrix.getScaleX();
45 transform.m21 = matrix.getSkewX();
46 transform.m41 = matrix.getTranslateX();
47 transform.m14 = matrix.getPerspX();
48
49 transform.m12 = matrix.getSkewY();
50 transform.m22 = matrix.getScaleY();
51 transform.m42 = matrix.getTranslateY();
52 transform.m24 = matrix.getPerspY();
53 return transform;
54 }
55
56 void ResetAnchor(CALayer* layer) {
57 // Flow uses (0, 0) to apply transform matrix so we need to match that in Quartz.
58 layer.anchorPoint = CGPointZero;
59 layer.position = CGPointZero;
60 }
61
62 CGRect GetCGRectFromSkRect(const SkRect& clipSkRect) {
63 return CGRectMake(clipSkRect.fLeft, clipSkRect.fTop, clipSkRect.fRight - clipSkRect.fLeft,
64 clipSkRect.fBottom - clipSkRect.fTop);
65 }
66
67 BOOL BlurRadiusEqualToBlurRadius(CGFloat radius1, CGFloat radius2) {
68 const CGFloat epsilon = 0.01;
69 return radius1 - radius2 < epsilon;
70 }
71
72 } // namespace flutter
73
74 @interface PlatformViewFilter ()
75
76 // `YES` if the backdropFilterView has been configured at least once.
77 @property(nonatomic) BOOL backdropFilterViewConfigured;
78 @property(nonatomic, retain) UIVisualEffectView* backdropFilterView;
79
80 // Updates the `visualEffectView` with the current filter parameters.
81 // Also sets `self.backdropFilterView` to the updated visualEffectView.
82 - (void)updateVisualEffectView:(UIVisualEffectView*)visualEffectView;
83
84 @end
85
86 @implementation PlatformViewFilter
87
88 static NSObject* _gaussianBlurFilter = nil;
89 // The index of "_UIVisualEffectBackdropView" in UIVisualEffectView's subViews.
90 static NSInteger _indexOfBackdropView = -1;
91 // The index of "_UIVisualEffectSubview" in UIVisualEffectView's subViews.
92 static NSInteger _indexOfVisualEffectSubview = -1;
93 static BOOL _preparedOnce = NO;
94
95 - (instancetype)initWithFrame:(CGRect)frame
96 blurRadius:(CGFloat)blurRadius
97 visualEffectView:(UIVisualEffectView*)visualEffectView {
98 if (self = [super init]) {
99 _frame = frame;
100 _blurRadius = blurRadius;
101 [PlatformViewFilter prepareOnce:visualEffectView];
102 if (![PlatformViewFilter isUIVisualEffectViewImplementationValid]) {
103 FML_DLOG(ERROR) << "Apple's API for UIVisualEffectView changed. Update the implementation to "
104 "access the gaussianBlur CAFilter.";
105 [self release];
106 return nil;
107 }
108 _backdropFilterView = [visualEffectView retain];
109 _backdropFilterViewConfigured = NO;
110 }
111 return self;
112 }
113
114 + (void)resetPreparation {
115 _preparedOnce = NO;
116 [_gaussianBlurFilter release];
117 _gaussianBlurFilter = nil;
118 _indexOfBackdropView = -1;
119 _indexOfVisualEffectSubview = -1;
120 }
121
122 + (void)prepareOnce:(UIVisualEffectView*)visualEffectView {
123 if (_preparedOnce) {
124 return;
125 }
126 for (NSUInteger i = 0; i < visualEffectView.subviews.count; i++) {
127 UIView* view = visualEffectView.subviews[i];
128 if ([NSStringFromClass([view class]) hasSuffix:@"BackdropView"]) {
129 _indexOfBackdropView = i;
130 for (NSObject* filter in view.layer.filters) {
131 if ([[filter valueForKey:@"name"] isEqual:@"gaussianBlur"] &&
132 [[filter valueForKey:@"inputRadius"] isKindOfClass:[NSNumber class]]) {
133 _gaussianBlurFilter = [filter retain];
134 break;
135 }
136 }
137 } else if ([NSStringFromClass([view class]) hasSuffix:@"VisualEffectSubview"]) {
138 _indexOfVisualEffectSubview = i;
139 }
140 }
141 _preparedOnce = YES;
142 }
143
144 + (BOOL)isUIVisualEffectViewImplementationValid {
145 return _indexOfBackdropView > -1 && _indexOfVisualEffectSubview > -1 && _gaussianBlurFilter;
146 }
147
148 - (void)dealloc {
149 [_backdropFilterView release];
150 _backdropFilterView = nil;
151
152 [super dealloc];
153 }
154
155 - (UIVisualEffectView*)backdropFilterView {
156 FML_DCHECK(_backdropFilterView);
157 if (!self.backdropFilterViewConfigured) {
158 [self updateVisualEffectView:_backdropFilterView];
159 self.backdropFilterViewConfigured = YES;
160 }
161 return _backdropFilterView;
162 }
163
164 - (void)updateVisualEffectView:(UIVisualEffectView*)visualEffectView {
165 NSObject* gaussianBlurFilter = [[_gaussianBlurFilter copy] autorelease];
166 FML_DCHECK(gaussianBlurFilter);
167 UIView* backdropView = visualEffectView.subviews[_indexOfBackdropView];
168 [gaussianBlurFilter setValue:@(_blurRadius) forKey:@"inputRadius"];
169 backdropView.layer.filters = @[ gaussianBlurFilter ];
170
171 UIView* visualEffectSubview = visualEffectView.subviews[_indexOfVisualEffectSubview];
172 visualEffectSubview.layer.backgroundColor = UIColor.clearColor.CGColor;
173 visualEffectView.frame = _frame;
174
175 if (_backdropFilterView != visualEffectView) {
176 _backdropFilterView = [visualEffectView retain];
177 }
178 }
179
180 @end
181
182 @interface ChildClippingView ()
183
184 @property(retain, nonatomic) NSArray<PlatformViewFilter*>* filters;
185 @property(retain, nonatomic) NSMutableArray<UIVisualEffectView*>* backdropFilterSubviews;
186
187 @end
188
189 @implementation ChildClippingView
190
191 // The ChildClippingView's frame is the bounding rect of the platform view. we only want touches to
192 // be hit tested and consumed by this view if they are inside the embedded platform view which could
193 // be smaller the embedded platform view is rotated.
194 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event {
195 for (UIView* view in self.subviews) {
196 if ([view pointInside:[self convertPoint:point toView:view] withEvent:event]) {
197 return YES;
198 }
199 }
200 return NO;
201 }
202
203 - (void)applyBlurBackdropFilters:(NSArray<PlatformViewFilter*>*)filters {
204 FML_DCHECK(self.filters.count == self.backdropFilterSubviews.count);
205 if (self.filters.count == 0 && filters.count == 0) {
206 return;
207 }
208 self.filters = filters;
209 NSUInteger index = 0;
210 for (index = 0; index < self.filters.count; index++) {
211 UIVisualEffectView* backdropFilterView;
212 PlatformViewFilter* filter = self.filters[index];
213 if (self.backdropFilterSubviews.count <= index) {
214 backdropFilterView = filter.backdropFilterView;
215 [self addSubview:backdropFilterView];
216 [self.backdropFilterSubviews addObject:backdropFilterView];
217 } else {
218 [filter updateVisualEffectView:self.backdropFilterSubviews[index]];
219 }
220 }
221 for (NSUInteger i = self.backdropFilterSubviews.count; i > index; i--) {
222 [self.backdropFilterSubviews[i - 1] removeFromSuperview];
223 [self.backdropFilterSubviews removeLastObject];
224 }
225 }
226
227 - (void)dealloc {
228 [_filters release];
229 _filters = nil;
230
231 [_backdropFilterSubviews release];
232 _backdropFilterSubviews = nil;
233
234 [super dealloc];
235 }
236
237 - (NSMutableArray*)backdropFilterSubviews {
238 if (!_backdropFilterSubviews) {
239 _backdropFilterSubviews = [[NSMutableArray alloc] init];
240 }
241 return _backdropFilterSubviews;
242 }
243
244 @end
245
246 @interface FlutterClippingMaskView ()
247
248 // A `CATransform3D` matrix represnts a scale transform that revese UIScreen.scale.
249 //
250 // The transform matrix passed in clipRect/clipRRect/clipPath methods are in device coordinate
251 // space. The transfrom matrix concats `reverseScreenScale` to create a transform matrix in the iOS
252 // logical coordinates (points).
253 //
254 // See https://developer.apple.com/documentation/uikit/uiscreen/1617836-scale?language=objc for
255 // information about screen scale.
256 @property(nonatomic) CATransform3D reverseScreenScale;
257
258 - (fml::CFRef<CGPathRef>)getTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix;
259
260 @end
261
262 @implementation FlutterClippingMaskView {
263 std::vector<fml::CFRef<CGPathRef>> paths_;
264 }
265
266 - (instancetype)initWithFrame:(CGRect)frame {
267 return [self initWithFrame:frame screenScale:[UIScreen mainScreen].scale];
268 }
269
270 - (instancetype)initWithFrame:(CGRect)frame screenScale:(CGFloat)screenScale {
271 if (self = [super initWithFrame:frame]) {
272 self.backgroundColor = UIColor.clearColor;
273 _reverseScreenScale = CATransform3DMakeScale(1 / screenScale, 1 / screenScale, 1);
274 }
275 return self;
276 }
277
278 - (void)reset {
279 paths_.clear();
280 [self setNeedsDisplay];
281 }
282
283 // In some scenarios, when we add this view as a maskView of the ChildClippingView, iOS added
284 // this view as a subview of the ChildClippingView.
285 // This results this view blocking touch events on the ChildClippingView.
286 // So we should always ignore any touch events sent to this view.
287 // See https://github.com/flutter/flutter/issues/66044
288 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event {
289 return NO;
290 }
291
292 - (void)drawRect:(CGRect)rect {
293 CGContextRef context = UIGraphicsGetCurrentContext();
294 CGContextSaveGState(context);
295
296 // For mask view, only the alpha channel is used.
297 CGContextSetAlpha(context, 1);
298
299 for (size_t i = 0; i < paths_.size(); i++) {
300 CGContextAddPath(context, paths_.at(i));
301 CGContextClip(context);
302 }
303 CGContextFillRect(context, rect);
304 CGContextRestoreGState(context);
305 }
306
307 - (void)clipRect:(const SkRect&)clipSkRect matrix:(const SkMatrix&)matrix {
308 CGRect clipRect = flutter::GetCGRectFromSkRect(clipSkRect);
309 CGPathRef path = CGPathCreateWithRect(clipRect, nil);
310 // The `matrix` is based on the physical pixels, convert it to UIKit points.
311 CATransform3D matrixInPoints =
312 CATransform3DConcat(flutter::GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale);
313 paths_.push_back([self getTransformedPath:path matrix:matrixInPoints]);
314 }
315
316 - (void)clipRRect:(const SkRRect&)clipSkRRect matrix:(const SkMatrix&)matrix {
317 CGPathRef pathRef = nullptr;
318 switch (clipSkRRect.getType()) {
319 case SkRRect::kEmpty_Type: {
320 break;
321 }
322 case SkRRect::kRect_Type: {
323 [self clipRect:clipSkRRect.rect() matrix:matrix];
324 return;
325 }
326 case SkRRect::kOval_Type:
327 case SkRRect::kSimple_Type: {
328 CGRect clipRect = flutter::GetCGRectFromSkRect(clipSkRRect.rect());
329 pathRef = CGPathCreateWithRoundedRect(clipRect, clipSkRRect.getSimpleRadii().x(),
330 clipSkRRect.getSimpleRadii().y(), nil);
331 break;
332 }
333 case SkRRect::kNinePatch_Type:
334 case SkRRect::kComplex_Type: {
335 CGMutablePathRef mutablePathRef = CGPathCreateMutable();
336 // Complex types, we manually add each corner.
337 SkRect clipSkRect = clipSkRRect.rect();
338 SkVector topLeftRadii = clipSkRRect.radii(SkRRect::kUpperLeft_Corner);
339 SkVector topRightRadii = clipSkRRect.radii(SkRRect::kUpperRight_Corner);
340 SkVector bottomRightRadii = clipSkRRect.radii(SkRRect::kLowerRight_Corner);
341 SkVector bottomLeftRadii = clipSkRRect.radii(SkRRect::kLowerLeft_Corner);
342
343 // Start drawing RRect
344 // Move point to the top left corner adding the top left radii's x.
345 CGPathMoveToPoint(mutablePathRef, nil, clipSkRect.fLeft + topLeftRadii.x(), clipSkRect.fTop);
346 // Move point horizontally right to the top right corner and add the top right curve.
347 CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fRight - topRightRadii.x(),
348 clipSkRect.fTop);
349 CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fRight, clipSkRect.fTop,
350 clipSkRect.fRight, clipSkRect.fTop + topRightRadii.y(),
351 clipSkRect.fRight, clipSkRect.fTop + topRightRadii.y());
352 // Move point vertically down to the bottom right corner and add the bottom right curve.
353 CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fRight,
354 clipSkRect.fBottom - bottomRightRadii.y());
355 CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fRight, clipSkRect.fBottom,
356 clipSkRect.fRight - bottomRightRadii.x(), clipSkRect.fBottom,
357 clipSkRect.fRight - bottomRightRadii.x(), clipSkRect.fBottom);
358 // Move point horizontally left to the bottom left corner and add the bottom left curve.
359 CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fLeft + bottomLeftRadii.x(),
360 clipSkRect.fBottom);
361 CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fLeft, clipSkRect.fBottom,
362 clipSkRect.fLeft, clipSkRect.fBottom - bottomLeftRadii.y(),
363 clipSkRect.fLeft, clipSkRect.fBottom - bottomLeftRadii.y());
364 // Move point vertically up to the top left corner and add the top left curve.
365 CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fLeft,
366 clipSkRect.fTop + topLeftRadii.y());
367 CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fLeft, clipSkRect.fTop,
368 clipSkRect.fLeft + topLeftRadii.x(), clipSkRect.fTop,
369 clipSkRect.fLeft + topLeftRadii.x(), clipSkRect.fTop);
370 CGPathCloseSubpath(mutablePathRef);
371
372 pathRef = mutablePathRef;
373 break;
374 }
375 }
376 // The `matrix` is based on the physical pixels, convert it to UIKit points.
377 CATransform3D matrixInPoints =
378 CATransform3DConcat(flutter::GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale);
379 // TODO(cyanglaz): iOS does not seem to support hard edge on CAShapeLayer. It clearly stated that
380 // the CAShaperLayer will be drawn antialiased. Need to figure out a way to do the hard edge
381 // clipping on iOS.
382 paths_.push_back([self getTransformedPath:pathRef matrix:matrixInPoints]);
383 }
384
385 - (void)clipPath:(const SkPath&)path matrix:(const SkMatrix&)matrix {
386 if (!path.isValid()) {
387 return;
388 }
389 if (path.isEmpty()) {
390 return;
391 }
392 CGMutablePathRef pathRef = CGPathCreateMutable();
393
394 // Loop through all verbs and translate them into CGPath
395 SkPath::Iter iter(path, true);
396 SkPoint pts[kMaxPointsInVerb];
397 SkPath::Verb verb = iter.next(pts);
398 SkPoint last_pt_from_last_verb = SkPoint::Make(0, 0);
399 while (verb != SkPath::kDone_Verb) {
400 if (verb == SkPath::kLine_Verb || verb == SkPath::kQuad_Verb || verb == SkPath::kConic_Verb ||
401 verb == SkPath::kCubic_Verb) {
402 FML_DCHECK(last_pt_from_last_verb == pts[0]);
403 }
404 switch (verb) {
405 case SkPath::kMove_Verb: {
406 CGPathMoveToPoint(pathRef, nil, pts[0].x(), pts[0].y());
407 last_pt_from_last_verb = pts[0];
408 break;
409 }
410 case SkPath::kLine_Verb: {
411 CGPathAddLineToPoint(pathRef, nil, pts[1].x(), pts[1].y());
412 last_pt_from_last_verb = pts[1];
413 break;
414 }
415 case SkPath::kQuad_Verb: {
416 CGPathAddQuadCurveToPoint(pathRef, nil, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y());
417 last_pt_from_last_verb = pts[2];
418 break;
419 }
420 case SkPath::kConic_Verb: {
421 // Conic is not available in quartz, we use quad to approximate.
422 // TODO(cyanglaz): Better approximate the conic path.
423 // https://github.com/flutter/flutter/issues/35062
424 CGPathAddQuadCurveToPoint(pathRef, nil, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y());
425 last_pt_from_last_verb = pts[2];
426 break;
427 }
428 case SkPath::kCubic_Verb: {
429 CGPathAddCurveToPoint(pathRef, nil, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y(),
430 pts[3].x(), pts[3].y());
431 last_pt_from_last_verb = pts[3];
432 break;
433 }
434 case SkPath::kClose_Verb: {
435 CGPathCloseSubpath(pathRef);
436 break;
437 }
438 case SkPath::kDone_Verb: {
439 break;
440 }
441 }
442 verb = iter.next(pts);
443 }
444 // The `matrix` is based on the physical pixels, convert it to UIKit points.
445 CATransform3D matrixInPoints =
446 CATransform3DConcat(flutter::GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale);
447 paths_.push_back([self getTransformedPath:pathRef matrix:matrixInPoints]);
448 }
449
450 - (fml::CFRef<CGPathRef>)getTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix {
451 CGAffineTransform affine =
452 CGAffineTransformMake(matrix.m11, matrix.m12, matrix.m21, matrix.m22, matrix.m41, matrix.m42);
453 CGPathRef transformedPath = CGPathCreateCopyByTransformingPath(path, &affine);
454 CGPathRelease(path);
455 return fml::CFRef<CGPathRef>(transformedPath);
456 }
457
458 @end
459
460 @interface FlutterClippingMaskViewPool ()
461
462 // The maximum number of `FlutterClippingMaskView` the pool can contain.
463 // This prevents the pool to grow infinately and limits the maximum memory a pool can use.
464 @property(assign, nonatomic) NSUInteger capacity;
465
466 // The pool contains the views that are available to use.
467 // The number of items in the pool must not excceds `capacity`.
468 @property(retain, nonatomic) NSMutableSet<FlutterClippingMaskView*>* pool;
469
470 @end
471
472 @implementation FlutterClippingMaskViewPool : NSObject
473
474 - (instancetype)initWithCapacity:(NSInteger)capacity {
475 if (self = [super init]) {
476 // Most of cases, there are only one PlatformView in the scene.
477 // Thus init with the capacity of 1.
478 _pool = [[NSMutableSet alloc] initWithCapacity:1];
479 _capacity = capacity;
480 }
481 return self;
482 }
483
484 - (FlutterClippingMaskView*)getMaskViewWithFrame:(CGRect)frame {
485 FML_DCHECK(self.pool.count <= self.capacity);
486 if (self.pool.count == 0) {
487 // The pool is empty, alloc a new one.
488 return
489 [[[FlutterClippingMaskView alloc] initWithFrame:frame
490 screenScale:[UIScreen mainScreen].scale] autorelease];
491 }
492 FlutterClippingMaskView* maskView = [[[self.pool anyObject] retain] autorelease];
493 maskView.frame = frame;
494 [maskView reset];
495 [self.pool removeObject:maskView];
496 return maskView;
497 }
498
499 - (void)insertViewToPoolIfNeeded:(FlutterClippingMaskView*)maskView {
500 FML_DCHECK(![self.pool containsObject:maskView]);
501 FML_DCHECK(self.pool.count <= self.capacity);
502 if (self.pool.count == self.capacity) {
503 return;
504 }
505 [self.pool addObject:maskView];
506 }
507
508 - (void)dealloc {
509 [_pool release];
510
511 [super dealloc];
512 }
513
514 @end
kMaxPointsInVerb
static constexpr int kMaxPointsInVerb
Definition: FlutterPlatformViews_Internal.mm:11
-[flutter::FlutterPlatformViewsController FlutterPlatformViewsController]
FlutterPlatformViewsController()
Definition: FlutterPlatformViews_Internal.mm:28
-[flutter::FlutterPlatformViewLayer ~FlutterPlatformViewLayer]
~FlutterPlatformViewLayer()
-[flutter::FlutterPlatformViewsController GetWeakPtr]
fml::WeakPtr< flutter::FlutterPlatformViewsController > GetWeakPtr()
Definition: FlutterPlatformViews_Internal.mm:37
_gaussianBlurFilter
static NSObject * _gaussianBlurFilter
Definition: FlutterPlatformViews_Internal.mm:88
PlatformViewFilter::frame
CGRect frame
Definition: FlutterPlatformViews_Internal.h:82
flutter::BlurRadiusEqualToBlurRadius
BOOL BlurRadiusEqualToBlurRadius(CGFloat radius1, CGFloat radius2)
Definition: FlutterPlatformViews_Internal.mm:67
_indexOfVisualEffectSubview
static NSInteger _indexOfVisualEffectSubview
Definition: FlutterPlatformViews_Internal.mm:92
_preparedOnce
static BOOL _preparedOnce
Definition: FlutterPlatformViews_Internal.mm:93
-[FlutterClippingMaskView clipRect:matrix:]
void clipRect:matrix:(const SkRect &clipSkRect,[matrix] const SkMatrix &matrix)
Definition: FlutterPlatformViews_Internal.mm:307
initWithFrame
instancetype initWithFrame
Definition: FlutterTextInputPlugin.h:167
flutter::ResetAnchor
void ResetAnchor(CALayer *layer)
Definition: FlutterPlatformViews_Internal.mm:56
-[ChildClippingView backdropFilterSubviews]
NSMutableArray * backdropFilterSubviews()
Definition: FlutterPlatformViews_Internal.mm:237
kFlutterClippingMaskViewPoolCapacity
static constexpr NSUInteger kFlutterClippingMaskViewPoolCapacity
Definition: FlutterPlatformViews_Internal.mm:12
PlatformViewFilter::blurRadius
CGFloat blurRadius
Definition: FlutterPlatformViews_Internal.h:87
ios_surface.h
flutter::FlutterPlatformViewLayerPool
Definition: FlutterPlatformViews_Internal.h:165
-[FlutterClippingMaskView reset]
void reset()
Definition: FlutterPlatformViews_Internal.mm:278
PlatformViewFilter::backdropFilterView
UIVisualEffectView * backdropFilterView
Definition: FlutterPlatformViews_Internal.h:93
flutter
Definition: accessibility_bridge.h:28
FlutterPlatformViews_Internal.h
_indexOfBackdropView
static NSInteger _indexOfBackdropView
Definition: FlutterPlatformViews_Internal.mm:90
-[flutter::FlutterPlatformViewsController ~FlutterPlatformViewsController]
~FlutterPlatformViewsController()
FlutterClippingMaskViewPool
Definition: FlutterPlatformViews_Internal.h:60
-[flutter::FlutterPlatformViewLayer FlutterPlatformViewLayer]
FlutterPlatformViewLayer(const fml::scoped_nsobject< UIView > &overlay_view, const fml::scoped_nsobject< UIView > &overlay_view_wrapper, std::unique_ptr< IOSSurface > ios_surface, std::unique_ptr< Surface > surface)
Definition: FlutterPlatformViews_Internal.mm:16
ChildClippingView
Definition: FlutterPlatformViews_Internal.h:117
+[PlatformViewFilter resetPreparation]
void resetPreparation()
Definition: FlutterPlatformViews_Internal.mm:114
flutter::GetCATransform3DFromSkMatrix
CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix &matrix)
Definition: FlutterPlatformViews_Internal.mm:41
flutter::GetCGRectFromSkRect
CGRect GetCGRectFromSkRect(const SkRect &clipSkRect)
Definition: FlutterPlatformViews_Internal.mm:62
PlatformViewFilter
Definition: FlutterPlatformViews_Internal.h:78
flutter::FlutterPlatformViewsController
Definition: FlutterPlatformViews_Internal.h:203
FlutterClippingMaskView
Definition: FlutterPlatformViews_Internal.h:29