diff options
Diffstat (limited to 'platform/ios/src/MGLMapView.mm')
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index cdacfb462b..918506067c 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -53,6 +53,7 @@ #import "NSProcessInfo+MGLAdditions.h" #import "NSString+MGLAdditions.h" #import "NSURL+MGLAdditions.h" +#import "UIDevice+MGLAdditions.h" #import "UIImage+MGLAdditions.h" #import "UIViewController+MGLAdditions.h" @@ -87,6 +88,10 @@ const CGFloat MGLMapViewDecelerationRateNormal = UIScrollViewDecelerationRateNor const CGFloat MGLMapViewDecelerationRateFast = UIScrollViewDecelerationRateFast; const CGFloat MGLMapViewDecelerationRateImmediate = 0.0; +const MGLMapViewPreferredFramesPerSecond MGLMapViewPreferredFramesPerSecondDefault = -1; +const MGLMapViewPreferredFramesPerSecond MGLMapViewPreferredFramesPerSecondLowPower = 30; +const MGLMapViewPreferredFramesPerSecond MGLMapViewPreferredFramesPerSecondMaximum = 60; + /// Indicates the manner in which the map view is tracking the user location. typedef NS_ENUM(NSUInteger, MGLUserTrackingState) { /// The map view is not yet tracking the user location. @@ -118,8 +123,6 @@ const double MGLMinimumZoomLevelForUserTracking = 10.5; /// Initial zoom level when entering user tracking mode from a low zoom level. const double MGLDefaultZoomLevelForUserTracking = 14.0; -const NSUInteger MGLTargetFrameInterval = 1; // Target FPS will be 60 divided by this value - /// Tolerance for snapping to true north, measured in degrees in either direction. const CLLocationDirection MGLToleranceForSnappingToNorth = 7; @@ -403,6 +406,9 @@ public: self.backgroundColor = [UIColor clearColor]; self.clipsToBounds = YES; if (@available(iOS 11.0, *)) { self.accessibilityIgnoresInvertColors = YES; } + + self.preferredFramesPerSecond = MGLMapViewPreferredFramesPerSecondDefault; + // setup mbgl view _mbglView = new MBGLView(self); @@ -1125,7 +1131,7 @@ public: } _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateFromDisplayLink)]; - _displayLink.frameInterval = MGLTargetFrameInterval; + [self updateDisplayLinkPreferredFramesPerSecond]; [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; _needsDisplayRefresh = YES; [self updateFromDisplayLink]; @@ -1137,6 +1143,49 @@ public: } } +- (void)updateDisplayLinkPreferredFramesPerSecond +{ + if (!_displayLink) + { + return; + } + + NSInteger newFrameRate; + if (_preferredFramesPerSecond == MGLMapViewPreferredFramesPerSecondDefault) + { + // On legacy devices that cannot maintain a reasonable frame rate, set + // a lower limit to avoid jank. + newFrameRate = UIDevice.currentDevice.mgl_isLegacyDevice ? MGLMapViewPreferredFramesPerSecondLowPower : MGLMapViewPreferredFramesPerSecondMaximum; + } + else + { + newFrameRate = _preferredFramesPerSecond; + } + + if (@available(iOS 10.0, *)) + { + _displayLink.preferredFramesPerSecond = newFrameRate; + } + else + { + // CADisplayLink.frameInterval does not support more than 60 FPS (and + // no device that supports >60 FPS ever supported iOS 9). + NSInteger maximumFrameRate = 60; + _displayLink.frameInterval = maximumFrameRate / MIN(newFrameRate, maximumFrameRate); + } +} + +- (void)setPreferredFramesPerSecond:(MGLMapViewPreferredFramesPerSecond)preferredFramesPerSecond +{ + if (_preferredFramesPerSecond == preferredFramesPerSecond) + { + return; + } + + _preferredFramesPerSecond = preferredFramesPerSecond; + [self updateDisplayLinkPreferredFramesPerSecond]; +} + - (void)didMoveToWindow { [self validateDisplayLink]; |