diff options
author | Julian Rex <julian.rex@mapbox.com> | 2019-04-02 09:10:35 -0400 |
---|---|---|
committer | Julian Rex <julian.rex@mapbox.com> | 2019-04-02 09:12:53 -0400 |
commit | 3e70b5522414fd0d70c08b31e2050782281490e4 (patch) | |
tree | 064d5ae3bac1c980748b9b34128ce51b0f1edf09 | |
parent | f06803f1908a3c49fad3aa569c0f8fec40e09c46 (diff) | |
download | qtlocation-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.mm | 53 |
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]; |