summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Rex <julian.rex@mapbox.com>2019-04-02 09:10:35 -0400
committerJulian Rex <julian.rex@mapbox.com>2019-04-02 09:12:53 -0400
commit3e70b5522414fd0d70c08b31e2050782281490e4 (patch)
tree064d5ae3bac1c980748b9b34128ce51b0f1edf09
parentf06803f1908a3c49fad3aa569c0f8fec40e09c46 (diff)
downloadqtlocation-mapboxgl-3e70b5522414fd0d70c08b31e2050782281490e4.tar.gz
Recreate GL views if rendering takes > 1 second. (since glClear is blocked for 1 sec)
-rw-r--r--platform/ios/src/MGLMapView.mm53
1 files changed, 53 insertions, 0 deletions
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 89fc1e8fab..97b20f97e6 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -1101,6 +1101,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 +1121,15 @@ public:
[self updateAnnotationViews];
[self updateCalloutView];
+ CFTimeInterval before = CACurrentMediaTime();
[self.glView display];
+ CFTimeInterval after = CACurrentMediaTime();
+
+ if (after-before >= 1.0) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self emergencyRecreateGL];
+ });
+ }
}
if (self.experimental_enableFrameRateMeasurement)
@@ -1231,6 +1246,44 @@ 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
+ [_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;
+
+ // Do not bind...yet
+
+ if (self.window) {
+ [self wakeGL:nil];
+ CAEAGLLayer *eaglLayer = MGL_OBJC_DYNAMIC_CAST(_glView.layer, CAEAGLLayer);
+ eaglLayer.presentsWithTransaction = YES;
+ }
+ else {
+ MGLLogDebug(@"No window - skipping wakeGL");
+ }
+}
+
- (void)willMoveToWindow:(UIWindow *)newWindow {
[super willMoveToWindow:newWindow];
[self refreshSupportedInterfaceOrientationsWithWindow:newWindow];