summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--ios/benchmark/MBXBenchViewController.mm8
-rw-r--r--platform/ios/src/MGLMapView.mm56
3 files changed, 51 insertions, 14 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e321f9b349..45d1c59fd4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -38,6 +38,7 @@ Known issues:
## iOS master
+- Fixed an issue causing the entire MGLMapView to leak. ([#3447](https://github.com/mapbox/mapbox-gl-native/pull/3447))
- `MGLMapView` methods that alter the viewport now accept optional completion handlers. ([#3090](https://github.com/mapbox/mapbox-gl-native/pull/3090))
- You can now modify an annotation’s image after adding the annotation to the map. ([#3146](https://github.com/mapbox/mapbox-gl-native/pull/3146))
- Tapping now selects annotations more reliably. Tapping near the top of a large annotation image now selects that annotation. An annotation image’s alignment insets influence how far away the user can tap and still select the annotation. For example, if your annotation image has a large shadow, you can keep that shadow from being tappable by excluding it from the image’s alignment rect. ([#3261](https://github.com/mapbox/mapbox-gl-native/pull/3261))
diff --git a/ios/benchmark/MBXBenchViewController.mm b/ios/benchmark/MBXBenchViewController.mm
index 2af2cacd1f..8a4e053460 100644
--- a/ios/benchmark/MBXBenchViewController.mm
+++ b/ios/benchmark/MBXBenchViewController.mm
@@ -11,7 +11,7 @@
#pragma mark - Debugging
/** Triggers another render pass even when it is not necessary. */
-- (void)invalidate;
+- (void)setNeedsGLDisplay;
/** Returns whether the map view is currently loading or processing any assets required to render the map */
- (BOOL)isFullyLoaded;
@@ -119,7 +119,7 @@ static const int benchmarkDuration = 200; // frames
idx++;
[self startBenchmarkIteration];
} else {
- [mapView invalidate];
+ [mapView setNeedsGLDisplay];
}
return;
}
@@ -134,7 +134,7 @@ static const int benchmarkDuration = 200; // frames
started = Clock::now();
NSLog(@"- Benchmarking for %d frames...", benchmarkDuration);
}
- [mapView invalidate];
+ [mapView setNeedsGLDisplay];
return;
}
@@ -146,7 +146,7 @@ static const int benchmarkDuration = 200; // frames
state = State::WarmingUp;
[self.mapView emptyMemoryCache];
NSLog(@"- Warming up for %d frames...", warmupDuration);
- [mapView invalidate];
+ [mapView setNeedsGLDisplay];
}
return;
}
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index c0909f873d..c7c5eda59b 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -287,12 +287,6 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
// setup mbgl map
_mbglMap = new mbgl::Map(*_mbglView, *_mbglFileSource, mbgl::MapMode::Continuous);
- // setup refresh driver
- _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateFromDisplayLink)];
- _displayLink.frameInterval = MGLTargetFrameInterval;
- [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
- _needsDisplayRefresh = YES;
-
// start paused if in IB
if (_isTargetingInterfaceBuilder || background) {
self.dormant = YES;
@@ -489,6 +483,8 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[MGLAccountManager sharedManager] removeObserver:self forKeyPath:@"accessToken"];
+
+ [self validateDisplayLink];
if (_mbglMap)
{
@@ -785,7 +781,7 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
}
}
-- (void)invalidate
+- (void)setNeedsGLDisplay
{
MGLAssertIsMainThread();
@@ -798,21 +794,53 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
if ( ! self.isDormant)
{
+ [self validateDisplayLink];
self.dormant = YES;
_mbglMap->pause();
[self.glView deleteDrawable];
}
}
+- (void)validateDisplayLink
+{
+ BOOL isVisible = self.superview && self.window;
+ if (isVisible && ! _displayLink)
+ {
+ _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateFromDisplayLink)];
+ _displayLink.frameInterval = MGLTargetFrameInterval;
+ [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
+ _needsDisplayRefresh = YES;
+ }
+ else if ( ! isVisible && _displayLink)
+ {
+ [_displayLink invalidate];
+ _displayLink = nil;
+ }
+}
+
+- (void)didMoveToWindow
+{
+ [self validateDisplayLink];
+ [super didMoveToWindow];
+}
+
+- (void)didMoveToSuperview
+{
+ [self validateDisplayLink];
+ [super didMoveToSuperview];
+}
+
- (void)sleepGL:(__unused NSNotification *)notification
{
MGLAssertIsMainThread();
- if ( ! self.isDormant)
+ if ( ! self.dormant)
{
self.dormant = YES;
[MGLMapboxEvents flush];
+
+ _displayLink.paused = YES;
if ( ! self.glSnapshotView)
{
@@ -843,7 +871,7 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
{
MGLAssertIsMainThread();
- if (self.isDormant && [UIApplication sharedApplication].applicationState != UIApplicationStateBackground)
+ if (self.dormant && [UIApplication sharedApplication].applicationState != UIApplicationStateBackground)
{
self.dormant = NO;
@@ -857,9 +885,17 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
[self.glView bindDrawable];
_mbglMap->resume();
+
+ _displayLink.paused = NO;
}
}
+- (void)setHidden:(BOOL)hidden
+{
+ super.hidden = hidden;
+ _displayLink.paused = hidden;
+}
+
- (void)tintColorDidChange
{
for (UIView *subview in self.subviews) [self updateTintColorForView:subview];
@@ -3423,7 +3459,7 @@ class MBGLView : public mbgl::View
void invalidate() override
{
- [nativeView performSelectorOnMainThread:@selector(invalidate)
+ [nativeView performSelectorOnMainThread:@selector(setNeedsGLDisplay)
withObject:nil
waitUntilDone:NO];
}