iOS: Eliminate global in platformviews controller (flutter/engine#56805)
This is a minor refactoring that moves a global bool to a boolean ivar in FlutterPlatformViewsController. The purpose of this variable is simply to avoid the overhead of trying to create backdrop filters if we've ever failed to create one in the past. Given that this class will only ever have the one instance created and held by per engine with the same duration, and that most apps only ever have one engine, the performance win will be identical for most apps. For the few add-to-app cases with multiple engines either at once or over the course of an app's lifetime, the costs associated with firing up an engine are already a far bigger hit than those being saved by this bool. Also migrates from C++ style namespace { ... } to Obj-C style static functions. These are entirely equivalent as both restrict symbols to the current translation unit. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
parent
db142a30bf
commit
cea4600caa
@ -11,22 +11,39 @@
|
|||||||
#include "flutter/fml/synchronization/count_down_latch.h"
|
#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/FlutterOverlayView.h"
|
||||||
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h"
|
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h"
|
||||||
|
#include "flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.h"
|
||||||
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
|
#import "flutter/shell/platform/darwin/ios/ios_surface.h"
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// The number of frames the rasterizer task runner will continue
|
// The number of frames the rasterizer task runner will continue
|
||||||
// to run on the platform thread after no platform view is rendered.
|
// to run on the platform thread after no platform view is rendered.
|
||||||
//
|
//
|
||||||
// Note: this is an arbitrary number.
|
// Note: this is an arbitrary number.
|
||||||
static const int kDefaultMergedLeaseDuration = 10;
|
static constexpr int kDefaultMergedLeaseDuration = 10;
|
||||||
|
|
||||||
static constexpr NSUInteger kFlutterClippingMaskViewPoolCapacity = 5;
|
static constexpr NSUInteger kFlutterClippingMaskViewPoolCapacity = 5;
|
||||||
|
|
||||||
|
struct LayerData {
|
||||||
|
SkRect rect;
|
||||||
|
int64_t view_id;
|
||||||
|
int64_t overlay_id;
|
||||||
|
std::shared_ptr<flutter::OverlayLayer> layer;
|
||||||
|
};
|
||||||
|
using LayersMap = std::unordered_map<int64_t, LayerData>;
|
||||||
|
|
||||||
|
/// Each of the following structs stores part of the platform view hierarchy according to its
|
||||||
|
/// ID.
|
||||||
|
///
|
||||||
|
/// This data must only be accessed on the platform thread.
|
||||||
|
struct PlatformViewData {
|
||||||
|
NSObject<FlutterPlatformView>* view;
|
||||||
|
FlutterTouchInterceptingView* touch_interceptor;
|
||||||
|
UIView* root_view;
|
||||||
|
};
|
||||||
|
|
||||||
// Converts a SkMatrix to CATransform3D.
|
// Converts a SkMatrix to CATransform3D.
|
||||||
//
|
//
|
||||||
// Certain fields are ignored in CATransform3D since SkMatrix is 3x3 and CATransform3D is 4x4.
|
// Certain fields are ignored in CATransform3D since SkMatrix is 3x3 and CATransform3D is 4x4.
|
||||||
CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix& matrix) {
|
static CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix& matrix) {
|
||||||
// Skia only supports 2D transform so we don't map z.
|
// Skia only supports 2D transform so we don't map z.
|
||||||
CATransform3D transform = CATransform3DIdentity;
|
CATransform3D transform = CATransform3DIdentity;
|
||||||
transform.m11 = matrix.getScaleX();
|
transform.m11 = matrix.getScaleX();
|
||||||
@ -44,13 +61,13 @@ CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix& matrix) {
|
|||||||
// Reset the anchor of `layer` to match the transform operation from flow.
|
// Reset the anchor of `layer` to match the transform operation from flow.
|
||||||
//
|
//
|
||||||
// The position of the `layer` should be unchanged after resetting the anchor.
|
// The position of the `layer` should be unchanged after resetting the anchor.
|
||||||
void ResetAnchor(CALayer* layer) {
|
static void ResetAnchor(CALayer* layer) {
|
||||||
// Flow uses (0, 0) to apply transform matrix so we need to match that in Quartz.
|
// Flow uses (0, 0) to apply transform matrix so we need to match that in Quartz.
|
||||||
layer.anchorPoint = CGPointZero;
|
layer.anchorPoint = CGPointZero;
|
||||||
layer.position = CGPointZero;
|
layer.position = CGPointZero;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGRect GetCGRectFromSkRect(const SkRect& clipSkRect) {
|
static CGRect GetCGRectFromSkRect(const SkRect& clipSkRect) {
|
||||||
return CGRectMake(clipSkRect.fLeft, clipSkRect.fTop, clipSkRect.fRight - clipSkRect.fLeft,
|
return CGRectMake(clipSkRect.fLeft, clipSkRect.fTop, clipSkRect.fRight - clipSkRect.fLeft,
|
||||||
clipSkRect.fBottom - clipSkRect.fTop);
|
clipSkRect.fBottom - clipSkRect.fTop);
|
||||||
}
|
}
|
||||||
@ -63,9 +80,9 @@ CGRect GetCGRectFromSkRect(const SkRect& clipSkRect) {
|
|||||||
//
|
//
|
||||||
// `platformview_boundingrect` is the final bounding rect of the PlatformView in the coordinate
|
// `platformview_boundingrect` is the final bounding rect of the PlatformView in the coordinate
|
||||||
// space where the PlatformView is displayed.
|
// space where the PlatformView is displayed.
|
||||||
bool ClipRectContainsPlatformViewBoundingRect(const SkRect& clip_rect,
|
static bool ClipRectContainsPlatformViewBoundingRect(const SkRect& clip_rect,
|
||||||
const SkRect& platformview_boundingrect,
|
const SkRect& platformview_boundingrect,
|
||||||
const SkMatrix& transform_matrix) {
|
const SkMatrix& transform_matrix) {
|
||||||
SkRect transformed_rect = transform_matrix.mapRect(clip_rect);
|
SkRect transformed_rect = transform_matrix.mapRect(clip_rect);
|
||||||
return transformed_rect.contains(platformview_boundingrect);
|
return transformed_rect.contains(platformview_boundingrect);
|
||||||
}
|
}
|
||||||
@ -78,9 +95,9 @@ bool ClipRectContainsPlatformViewBoundingRect(const SkRect& clip_rect,
|
|||||||
//
|
//
|
||||||
// `platformview_boundingrect` is the final bounding rect of the PlatformView in the coordinate
|
// `platformview_boundingrect` is the final bounding rect of the PlatformView in the coordinate
|
||||||
// space where the PlatformView is displayed.
|
// space where the PlatformView is displayed.
|
||||||
bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
|
static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
|
||||||
const SkRect& platformview_boundingrect,
|
const SkRect& platformview_boundingrect,
|
||||||
const SkMatrix& transform_matrix) {
|
const SkMatrix& transform_matrix) {
|
||||||
SkVector upper_left = clip_rrect.radii(SkRRect::Corner::kUpperLeft_Corner);
|
SkVector upper_left = clip_rrect.radii(SkRRect::Corner::kUpperLeft_Corner);
|
||||||
SkVector upper_right = clip_rrect.radii(SkRRect::Corner::kUpperRight_Corner);
|
SkVector upper_right = clip_rrect.radii(SkRRect::Corner::kUpperRight_Corner);
|
||||||
SkVector lower_right = clip_rrect.radii(SkRRect::Corner::kLowerRight_Corner);
|
SkVector lower_right = clip_rrect.radii(SkRRect::Corner::kLowerRight_Corner);
|
||||||
@ -103,27 +120,6 @@ bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
|
|||||||
return transformed_rrect.contains(platformview_boundingrect);
|
return transformed_rrect.contains(platformview_boundingrect);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LayerData {
|
|
||||||
SkRect rect;
|
|
||||||
int64_t view_id;
|
|
||||||
int64_t overlay_id;
|
|
||||||
std::shared_ptr<flutter::OverlayLayer> layer;
|
|
||||||
};
|
|
||||||
|
|
||||||
using LayersMap = std::unordered_map<int64_t, LayerData>;
|
|
||||||
|
|
||||||
/// Each of the following structs stores part of the platform view hierarchy according to its
|
|
||||||
/// ID.
|
|
||||||
///
|
|
||||||
/// This data must only be accessed on the platform thread.
|
|
||||||
struct PlatformViewData {
|
|
||||||
NSObject<FlutterPlatformView>* view;
|
|
||||||
FlutterTouchInterceptingView* touch_interceptor;
|
|
||||||
UIView* root_view;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
@interface FlutterPlatformViewsController ()
|
@interface FlutterPlatformViewsController ()
|
||||||
|
|
||||||
// The pool of reusable view layers. The pool allows to recycle layer in each frame.
|
// The pool of reusable view layers. The pool allows to recycle layer in each frame.
|
||||||
@ -196,6 +192,11 @@ struct PlatformViewData {
|
|||||||
/// Only accessed from the raster thread.
|
/// Only accessed from the raster thread.
|
||||||
@property(nonatomic, assign) BOOL hadPlatformViews;
|
@property(nonatomic, assign) BOOL hadPlatformViews;
|
||||||
|
|
||||||
|
/// Whether blurred backdrop filters can be applied.
|
||||||
|
///
|
||||||
|
/// Defaults to YES, but becomes NO if blurred backdrop filters cannot be applied.
|
||||||
|
@property(nonatomic, assign) BOOL canApplyBlurBackdrop;
|
||||||
|
|
||||||
/// Populate any missing overlay layers.
|
/// Populate any missing overlay layers.
|
||||||
///
|
///
|
||||||
/// This requires posting a task to the platform thread and blocking on its completion.
|
/// This requires posting a task to the platform thread and blocking on its completion.
|
||||||
@ -264,14 +265,6 @@ struct PlatformViewData {
|
|||||||
- (void)resetFrameState;
|
- (void)resetFrameState;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// TODO(cbracken): Eliminate the use of globals.
|
|
||||||
// Becomes NO if Apple's API changes and blurred backdrop filters cannot be applied.
|
|
||||||
BOOL canApplyBlurBackdrop = YES;
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
@implementation FlutterPlatformViewsController {
|
@implementation FlutterPlatformViewsController {
|
||||||
// TODO(cbracken): Replace with Obj-C types and use @property declarations to automatically
|
// TODO(cbracken): Replace with Obj-C types and use @property declarations to automatically
|
||||||
// synthesize the ivars.
|
// synthesize the ivars.
|
||||||
@ -301,6 +294,7 @@ BOOL canApplyBlurBackdrop = YES;
|
|||||||
_maskViewPool =
|
_maskViewPool =
|
||||||
[[FlutterClippingMaskViewPool alloc] initWithCapacity:kFlutterClippingMaskViewPoolCapacity];
|
[[FlutterClippingMaskViewPool alloc] initWithCapacity:kFlutterClippingMaskViewPoolCapacity];
|
||||||
_hadPlatformViews = NO;
|
_hadPlatformViews = NO;
|
||||||
|
_canApplyBlurBackdrop = YES;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -630,7 +624,7 @@ BOOL canApplyBlurBackdrop = YES;
|
|||||||
break;
|
break;
|
||||||
case flutter::kBackdropFilter: {
|
case flutter::kBackdropFilter: {
|
||||||
// Only support DlBlurImageFilter for BackdropFilter.
|
// Only support DlBlurImageFilter for BackdropFilter.
|
||||||
if (!flutter::canApplyBlurBackdrop || !(*iter)->GetFilterMutation().GetFilter().asBlur()) {
|
if (!self.canApplyBlurBackdrop || !(*iter)->GetFilterMutation().GetFilter().asBlur()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CGRect filterRect = GetCGRectFromSkRect((*iter)->GetFilterMutation().GetFilterRect());
|
CGRect filterRect = GetCGRectFromSkRect((*iter)->GetFilterMutation().GetFilterRect());
|
||||||
@ -656,7 +650,7 @@ BOOL canApplyBlurBackdrop = YES;
|
|||||||
blurRadius:blurRadius
|
blurRadius:blurRadius
|
||||||
visualEffectView:visualEffectView];
|
visualEffectView:visualEffectView];
|
||||||
if (!filter) {
|
if (!filter) {
|
||||||
flutter::canApplyBlurBackdrop = NO;
|
self.canApplyBlurBackdrop = NO;
|
||||||
} else {
|
} else {
|
||||||
[blurFilters addObject:filter];
|
[blurFilters addObject:filter];
|
||||||
}
|
}
|
||||||
@ -666,7 +660,7 @@ BOOL canApplyBlurBackdrop = YES;
|
|||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flutter::canApplyBlurBackdrop) {
|
if (self.canApplyBlurBackdrop) {
|
||||||
[clipView applyBlurBackdropFilters:blurFilters];
|
[clipView applyBlurBackdropFilters:blurFilters];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user