summaryrefslogtreecommitdiff
path: root/platform/ios/MGLMapView.mm
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2015-07-01 23:48:16 -0700
committerMinh Nguyễn <mxn@1ec5.org>2015-07-08 14:53:11 -0700
commit1a3ae887868e9ecd6f0fd69add4b7b504d941b95 (patch)
tree7b8ebe247541913c075e5759053c09214ee24c60 /platform/ios/MGLMapView.mm
parentc53610f6eee857780f2ede17ddef6a8b12004961 (diff)
downloadqtlocation-mapboxgl-1a3ae887868e9ecd6f0fd69add4b7b504d941b95.tar.gz
Defer initialization until app enters foreground
Defer the creation of EAGLEContext and GLKView and the loading of OpenGL ES extensions. It is GLKView that drives the background crash, and Apple documentation specifically warns not to initialize an EAGLContext in the background. All the while, it should be safe for client code to avail itself of any public methods on MGLMapView. Fixes #1460.
Diffstat (limited to 'platform/ios/MGLMapView.mm')
-rw-r--r--platform/ios/MGLMapView.mm105
1 files changed, 64 insertions, 41 deletions
diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm
index 32ba5a03cb..055877194c 100644
--- a/platform/ios/MGLMapView.mm
+++ b/platform/ios/MGLMapView.mm
@@ -206,58 +206,28 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
- (void)commonInit
{
_isTargetingInterfaceBuilder = NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent;
+
+ BOOL background = [UIApplication sharedApplication].applicationState == UIApplicationStateBackground;
+ if (!background)
+ {
+ [self createGLView];
+ }
- // create context
- //
- _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
- NSAssert(_context, @"Failed to create OpenGL ES context.");
- // setup accessibility
- //
self.accessibilityLabel = @"Map";
-
- // create GL view
- //
- _glView = [[GLKView alloc] initWithFrame:self.bounds context:_context];
- _glView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- _glView.enableSetNeedsDisplay = YES;
- _glView.drawableStencilFormat = GLKViewDrawableStencilFormat8;
- _glView.drawableDepthFormat = GLKViewDrawableDepthFormat16;
-
- const float scaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale];
- _glView.contentScaleFactor = scaleFactor;
- _glView.delegate = self;
- [_glView bindDrawable];
- [self insertSubview:_glView atIndex:0];
-
- _glView.contentMode = UIViewContentModeCenter;
-
self.backgroundColor = [UIColor clearColor];
self.clipsToBounds = YES;
- // load extensions
- //
- mbgl::gl::InitializeExtensions([](const char * name) {
- static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengles"));
- if (!framework) {
- throw std::runtime_error("Failed to load OpenGL framework.");
- }
-
- CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
- void* symbol = CFBundleGetFunctionPointerForName(framework, str);
- CFRelease(str);
-
- return reinterpret_cast<mbgl::gl::glProc>(symbol);
- });
-
// setup mbgl map
//
+ const float scaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale];
_mbglView = new MBGLView(self, scaleFactor);
_mbglFileSource = new mbgl::DefaultFileSource([MGLFileCache obtainSharedCacheWithObject:self]);
- // Start paused on the IB canvas
+ // Start paused
_mbglMap = new mbgl::Map(*_mbglView, *_mbglFileSource, mbgl::MapMode::Continuous);
- if (_isTargetingInterfaceBuilder) {
+ if (_isTargetingInterfaceBuilder || background) {
+ self.dormant = YES;
_mbglMap->pause();
}
@@ -404,7 +374,59 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
}];
}
--(void)reachabilityChanged:(NSNotification*)notification
+- (void)createGLView
+{
+ if (_context || [UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
+ return;
+ }
+
+ // create context
+ //
+ _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+ NSAssert(_context, @"Failed to create OpenGL ES context.");
+
+ // create GL view
+ //
+ _glView = [[GLKView alloc] initWithFrame:self.bounds context:_context];
+ _glView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ _glView.enableSetNeedsDisplay = YES;
+ _glView.drawableStencilFormat = GLKViewDrawableStencilFormat8;
+ _glView.drawableDepthFormat = GLKViewDrawableDepthFormat16;
+ _glView.contentScaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale];
+ _glView.delegate = self;
+ [_glView bindDrawable];
+ [self insertSubview:_glView atIndex:0];
+
+ _glView.contentMode = UIViewContentModeCenter;
+
+ // load extensions
+ //
+ mbgl::gl::InitializeExtensions([](const char * name) {
+ static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengles"));
+ if (!framework) {
+ throw std::runtime_error("Failed to load OpenGL framework.");
+ }
+
+ CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
+ void* symbol = CFBundleGetFunctionPointerForName(framework, str);
+ CFRelease(str);
+
+ return reinterpret_cast<mbgl::gl::glProc>(symbol);
+ });
+}
+
+- (void)viewWillEnterForeground
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:UIApplicationWillEnterForegroundNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:UIApplicationDidBecomeActiveNotification
+ object:nil];
+ [self commonInit];
+}
+
+- (void)reachabilityChanged:(NSNotification *)notification
{
MGLReachability *reachability = [notification object];
if ([reachability isReachable]) {
@@ -775,6 +797,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
{
MGLAssertIsMainThread();
+ [self createGLView];
if (self.isDormant)
{
self.dormant = NO;