diff options
author | Julian Rex <julian.rex@mapbox.com> | 2019-03-29 00:34:13 -0400 |
---|---|---|
committer | Julian Rex <julian.rex@mapbox.com> | 2019-04-02 18:44:52 -0400 |
commit | d9379c18ce8d25b5c4f040cf18f58b7e80ff457f (patch) | |
tree | 06de9c1ac9eaed4d40079cd3fdad76ac31bb3445 | |
parent | bf21fa1ff8412089606c6c3aa4cc0dbebfe91b2d (diff) | |
download | qtlocation-mapboxgl-d9379c18ce8d25b5c4f040cf18f58b7e80ff457f.tar.gz |
[ios] Enable/disable presentsWithTransaction when moving to/from a window.
Added change log
Recreate GL views if rendering takes > 1 second. (since glClear is blocked for 1 sec)
Use presentsWithTransaction only if we have annotation UIViews.
Re-add annotation views.
-rw-r--r-- | platform/ios/CHANGELOG.md | 2 | ||||
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 103 |
2 files changed, 102 insertions, 3 deletions
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 3e59ae1da8..cf14c50acc 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -24,6 +24,8 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Added `MGLOrnamentPosition` enum and margin properties to customize scale bar, compass, logo, and attribution position within the map view. ([#13911](https://github.com/mapbox/mapbox-gl-native/pull/13911)) * Added an `MGLMapView.prefetchesTiles` property to configure lower-resolution tile prefetching behavior. ([#14031](https://github.com/mapbox/mapbox-gl-native/pull/14031)) +* Fixed a performance issue seen on iOS 12.2, when an `MGLMapView` is repeatedly removed and re-added in a view hierarchy. ([#14264](https://github.com/mapbox/mapbox-gl-native/pull/14264)) + ## 4.9.0 - February 27, 2019 diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index c94cf477ef..83c75909bd 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -252,6 +252,7 @@ public: @property (nonatomic) MGLAnnotationContainerView *annotationContainerView; @property (nonatomic) MGLUserLocation *userLocation; @property (nonatomic) NSMutableDictionary<NSString *, NSMutableArray<MGLAnnotationView *> *> *annotationViewReuseQueueByIdentifier; +@property (nonatomic) BOOL enablePresentsWithTransaction; /// Experimental rendering performance measurement. @property (nonatomic) BOOL experimental_enableFrameRateMeasurement; @@ -702,7 +703,7 @@ public: _glView.delegate = self; CAEAGLLayer *eaglLayer = MGL_OBJC_DYNAMIC_CAST(_glView.layer, CAEAGLLayer); - eaglLayer.presentsWithTransaction = YES; + eaglLayer.presentsWithTransaction = NO; [_glView bindDrawable]; [self insertSubview:_glView atIndex:0]; @@ -1101,6 +1102,13 @@ public: { MGLAssertIsMainThread(); + // Not "visible" - this isn't a full definition of visibility, but if + // the map view doesn't have a window then it *cannot* be visible. + if (!self.window) { + return; + } + + // Mismatched display link if (displayLink && displayLink != _displayLink) { return; } @@ -1114,7 +1122,22 @@ public: [self updateAnnotationViews]; [self updateCalloutView]; - [self.glView display]; + if (self.enablePresentsWithTransaction) + { + CFTimeInterval before = CACurrentMediaTime(); + [self.glView display]; + CFTimeInterval after = CACurrentMediaTime(); + + if (after-before >= 1.0) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self emergencyRecreateGL]; + }); + } + } + else + { + [self.glView display]; + } } if (self.experimental_enableFrameRateMeasurement) @@ -1231,15 +1254,85 @@ public: [self updateDisplayLinkPreferredFramesPerSecond]; } +// See https://github.com/mapbox/mapbox-gl-native/issues/14232 +- (void)emergencyRecreateGL { + MGLLogError(@"Rendering took too long - creating GL views"); + + CAEAGLLayer *eaglLayer = MGL_OBJC_DYNAMIC_CAST(_glView.layer, CAEAGLLayer); + eaglLayer.presentsWithTransaction = NO; + + [self sleepGL:nil]; + + // Just performing a sleepGL/wakeGL pair isn't sufficient - in this case + // we can still get errors when calling bindDrawable. Here we completely + // recreate the GLKView + + [self.userLocationAnnotationView removeFromSuperview]; + [_glView removeFromSuperview]; + + _glView = [[GLKView alloc] initWithFrame:self.bounds context:_context]; + _glView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _glView.enableSetNeedsDisplay = NO; + _glView.drawableStencilFormat = GLKViewDrawableStencilFormat8; + _glView.drawableDepthFormat = GLKViewDrawableDepthFormat16; + _glView.contentScaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale]; + _glView.layer.opaque = _opaque; + _glView.delegate = self; + + [self insertSubview:_glView atIndex:0]; + _glView.contentMode = UIViewContentModeCenter; + + if (self.annotationContainerView) + { + [_glView insertSubview:self.annotationContainerView atIndex:0]; + } + + [self updateUserLocationAnnotationView]; + + // Do not bind...yet + + if (self.window) { + [self wakeGL:nil]; + CAEAGLLayer *eaglLayer = MGL_OBJC_DYNAMIC_CAST(_glView.layer, CAEAGLLayer); + eaglLayer.presentsWithTransaction = self.enablePresentsWithTransaction; + } + else { + MGLLogDebug(@"No window - skipping wakeGL"); + } +} + - (void)willMoveToWindow:(UIWindow *)newWindow { [super willMoveToWindow:newWindow]; [self refreshSupportedInterfaceOrientationsWithWindow:newWindow]; + + if (!newWindow) + { + // See https://github.com/mapbox/mapbox-gl-native/issues/14232 + // In iOS 12.2, CAEAGLLayer.presentsWithTransaction can cause dramatic + // slow down. The exact cause of this is unknown, but this work around + // appears to lessen the effects. + // + // Also, consider calling the new mbgl::Renderer::flush() + CAEAGLLayer *eaglLayer = MGL_OBJC_DYNAMIC_CAST(_glView.layer, CAEAGLLayer); + eaglLayer.presentsWithTransaction = NO; + + // Moved from didMoveToWindow + [self validateDisplayLink]; + } } - (void)didMoveToWindow { - [self validateDisplayLink]; [super didMoveToWindow]; + + if (self.window) + { + // See above comment + CAEAGLLayer *eaglLayer = MGL_OBJC_DYNAMIC_CAST(_glView.layer, CAEAGLLayer); + eaglLayer.presentsWithTransaction = self.enablePresentsWithTransaction; + + [self validateDisplayLink]; + } } - (void)didMoveToSuperview @@ -4151,6 +4244,8 @@ public: [newAnnotationContainerView addSubviews:annotationViews]; [_glView insertSubview:newAnnotationContainerView atIndex:0]; self.annotationContainerView = newAnnotationContainerView; + + self.enablePresentsWithTransaction = (self.annotationContainerView.annotationViews.count > 0); } /// Initialize and return a default annotation image that depicts a round pin @@ -4324,6 +4419,8 @@ public: annotationView.annotation = nil; [annotationView removeFromSuperview]; [self.annotationContainerView.annotationViews removeObject:annotationView]; + + self.enablePresentsWithTransaction = (self.annotationContainerView.annotationViews.count > 0); if (annotationTag == _selectedAnnotationTag) { |