From 58487a9638166cdf6bc2295f6b08e20e3cb0bcf9 Mon Sep 17 00:00:00 2001 From: Matteo Crippa Date: Mon, 8 Mar 2021 20:44:28 +0100 Subject: [PATCH] Feature/ios performances (#44) * improved ios performances * fix merge issue * cleanup playground * update gitignore for playground --- .gitignore | 3 + .gitignore.swp | Bin 0 -> 12288 bytes .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++ .../xcshareddata/xcschemes/iosapp.xcscheme | 10 +- platform/ios/platform/ios/src/MGLMapView.mm | 128 +++++++++++++----- 5 files changed, 108 insertions(+), 41 deletions(-) create mode 100644 .gitignore.swp create mode 100644 platform/ios/platform/ios/ios.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/.gitignore b/.gitignore index 69fc13925..f834afc94 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,10 @@ /cmake-build-debug /platform/android/build /platform/android/MapboxGLAndroidSDK/src/main/assets/sdk_versions/com.mapbox.mapboxsdk +/platform/ios/platform/ios/Mapbox.playground/build/ *.code-workspace + +.DS_Store /build **/.idea /platform/android/MapboxGLAndroidSDKTestApp/local.properties diff --git a/.gitignore.swp b/.gitignore.swp new file mode 100644 index 0000000000000000000000000000000000000000..19432fd5f18b12dcea608dc6db39c162aac1e3bc GIT binary patch literal 12288 zcmeI2&x_PB6vy8RdeK$UgD42QdXa%9ySj{XT^RgsxqCxCJ<5c@>jT!ca^mOIzw2%l80U|&IhyW2F z0z`la5P_3VAWPTaHKu{j{Ykqz?bnX<(;;<4fCvx)B0vO)01+SpM1Tko0U|&Ih`1QE z-)Qp(>O1Ny>I>>4>JT;YcLI4)$V7k$5CI}U1c(3;AOb{y2&_neC+c8ehQmlFib)@M z8i{OZY|KR>tqr9Y z_6PlJQZn3Pfsx8PFm~ip5vT=6+PJyb@u2d^Fp`&{HF+W{b9`Y>b8y_*0PB}^!i94x zbKJ?%pitInlQ_W1I{N%Cg4!@=;C?YRl-(9bYfR%9subIfq N_|YxLGP2|l{sP7!gns}4 literal 0 HcmV?d00001 diff --git a/platform/ios/platform/ios/ios.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/platform/ios/platform/ios/ios.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/platform/ios/platform/ios/ios.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/platform/ios/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/iosapp.xcscheme b/platform/ios/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/iosapp.xcscheme index a1237e015..0a934c883 100644 --- a/platform/ios/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/iosapp.xcscheme +++ b/platform/ios/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/iosapp.xcscheme @@ -1,6 +1,6 @@ @@ -31,7 +31,7 @@ @@ -54,7 +54,7 @@ @@ -78,7 +78,7 @@ diff --git a/platform/ios/platform/ios/src/MGLMapView.mm b/platform/ios/platform/ios/src/MGLMapView.mm index c17ba1bec..f54a97598 100644 --- a/platform/ios/platform/ios/src/MGLMapView.mm +++ b/platform/ios/platform/ios/src/MGLMapView.mm @@ -158,6 +158,12 @@ enum { MGLAnnotationTagNotFound = UINT32_MAX }; /// The threshold used to consider when a tilt gesture should start. const CLLocationDegrees MGLHorizontalTiltToleranceDegrees = 45.0; +/// The time between background snapshot attempts. +const NSTimeInterval MGLBackgroundSnapshotImageInterval = 60.0; + +/// The delay after the map has idled before a background snapshot is attempted. +const NSTimeInterval MGLBackgroundSnapshotImageIdleDelay = 3.0; + /// Mapping from an annotation tag to metadata about that annotation, including /// the annotation itself. typedef std::unordered_map MGLAnnotationTagContextMap; @@ -1552,23 +1558,27 @@ public: _displayLink.paused = YES; [self processPendingBlocks]; - if ( ! self.glSnapshotView) + if (self.lastSnapshotImage) { - self.glSnapshotView = [[UIImageView alloc] initWithFrame: _mbglView->getView().frame]; - self.glSnapshotView.autoresizingMask = _mbglView->getView().autoresizingMask; - self.glSnapshotView.contentMode = UIViewContentModeCenter; - [self insertSubview:self.glSnapshotView aboveSubview:_mbglView->getView()]; - } + if ( ! self.glSnapshotView) + { + self.glSnapshotView = [[UIImageView alloc] initWithFrame: _mbglView->getView().frame]; + self.glSnapshotView.autoresizingMask = _mbglView->getView().autoresizingMask; + self.glSnapshotView.contentMode = UIViewContentModeCenter; + [self insertSubview:self.glSnapshotView aboveSubview:_mbglView->getView()]; + } + + self.glSnapshotView.image = self.lastSnapshotImage; + self.glSnapshotView.hidden = NO; + self.glSnapshotView.alpha = 1; - self.glSnapshotView.image = self.lastSnapshotImage; - self.glSnapshotView.hidden = NO; - - if (self.debugMask && [self.glSnapshotView.subviews count] == 0) - { - UIView *snapshotTint = [[UIView alloc] initWithFrame:self.glSnapshotView.bounds]; - snapshotTint.autoresizingMask = self.glSnapshotView.autoresizingMask; - snapshotTint.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.25]; - [self.glSnapshotView addSubview:snapshotTint]; + if (self.debugMask && [self.glSnapshotView.subviews count] == 0) + { + UIView *snapshotTint = [[UIView alloc] initWithFrame:self.glSnapshotView.bounds]; + snapshotTint.autoresizingMask = self.glSnapshotView.autoresizingMask; + snapshotTint.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.25]; + [self.glSnapshotView addSubview:snapshotTint]; + } } _mbglView->deleteView(); @@ -1586,9 +1596,15 @@ public: _mbglView->createView(); - self.glSnapshotView.hidden = YES; - - [self.glSnapshotView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + [UIView transitionWithView:self + duration:0.25 + options:UIViewAnimationOptionTransitionCrossDissolve + animations:^{ + self.glSnapshotView.hidden = YES; + } + completion:^(BOOL finished) { + [self.glSnapshotView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + }]; _displayLink.paused = NO; @@ -5946,29 +5962,32 @@ public: - (void)locationManager:(__unused id)manager didUpdateHeading:(CLHeading *)newHeading { - if ( ! _showsUserLocation || self.pan.state == UIGestureRecognizerStateBegan || newHeading.headingAccuracy < 0) return; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { + if ( ! self->_showsUserLocation || self.pan.state == UIGestureRecognizerStateBegan || newHeading.headingAccuracy < 0) return; - self.userLocation.heading = newHeading; + self.userLocation.heading = newHeading; - if (self.showsUserHeadingIndicator || self.userTrackingMode == MGLUserTrackingModeFollowWithHeading) - { - [self updateUserLocationAnnotationView]; - } + if (self.showsUserHeadingIndicator || self.userTrackingMode == MGLUserTrackingModeFollowWithHeading) + { + [self updateUserLocationAnnotationView]; + } - if ([self.delegate respondsToSelector:@selector(mapView:didUpdateUserLocation:)]) - { - [self.delegate mapView:self didUpdateUserLocation:self.userLocation]; + if ([self.delegate respondsToSelector:@selector(mapView:didUpdateUserLocation:)]) + { + [self.delegate mapView:self didUpdateUserLocation:self.userLocation]; - if ( ! _showsUserLocation) return; - } + if (!self->_showsUserLocation) return; + } - CLLocationDirection headingDirection = (newHeading.trueHeading >= 0 ? newHeading.trueHeading : newHeading.magneticHeading); + CLLocationDirection headingDirection = (newHeading.trueHeading >= 0 ? newHeading.trueHeading : newHeading.magneticHeading); - if (headingDirection >= 0 && self.userTrackingMode == MGLUserTrackingModeFollowWithHeading - && self.userTrackingState != MGLUserTrackingStateBegan) - { - [self _setDirection:headingDirection animated:YES]; - } + if (headingDirection >= 0 && self.userTrackingMode == MGLUserTrackingModeFollowWithHeading + && self.userTrackingState != MGLUserTrackingStateBegan) + { + [self _setDirection:headingDirection animated:YES]; + [self updateUserLocationAnnotationView]; + } + }); } - (void)locationManager:(__unused id)manager didFailWithError:(NSError *)error @@ -6353,6 +6372,8 @@ public: } - (void)mapViewWillStartRenderingFrame { + [self cancelBackgroundSnapshot]; + if (!_mbglMap) { return; @@ -6412,7 +6433,9 @@ public: if (!_mbglMap) { return; } - + + [self queueBackgroundSnapshot]; + if ([self.delegate respondsToSelector:@selector(mapViewDidBecomeIdle:)]) { [self.delegate mapViewDidBecomeIdle:self]; } @@ -6891,6 +6914,39 @@ public: return _annotationViewReuseQueueByIdentifier[identifier]; } +#pragma mark - Snapshot image - + +- (void)attemptBackgroundSnapshot { + static NSTimeInterval lastSnapshotTime = 0.0; + + if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) { + return; + } + + NSTimeInterval now = CACurrentMediaTime(); + + if (lastSnapshotTime == 0.0 || (now - lastSnapshotTime > MGLBackgroundSnapshotImageInterval)) { + self.lastSnapshotImage = _mbglView->snapshot(); + lastSnapshotTime = now; + } +} + +- (void)cancelBackgroundSnapshot +{ + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(attemptBackgroundSnapshot) object:nil]; +} + +- (void)queueBackgroundSnapshot { + if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) { + return; + } + + [self cancelBackgroundSnapshot]; + [self performSelector:@selector(attemptBackgroundSnapshot) + withObject:nil + afterDelay:MGLBackgroundSnapshotImageIdleDelay]; +} + @end #pragma mark - IBAdditions methods