This commit is contained in:
@@ -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))
|
||||
* Speculatively 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
|
||||
|
||||
|
||||
@@ -156,6 +156,10 @@ const CGFloat MGLAnnotationImagePaddingForCallout = 1;
|
||||
|
||||
const CGSize MGLAnnotationAccessibilityElementMinimumSize = CGSizeMake(10, 10);
|
||||
|
||||
/// The number of view annotations (excluding the user location view) that must
|
||||
/// be descendents of `MGLMapView` before presentsWithTransaction is enabled.
|
||||
static const NSUInteger MGLPresentsWithTransactionAnnotationCount = 0;
|
||||
|
||||
/// An indication that the requested annotation was not found or is nonexistent.
|
||||
enum { MGLAnnotationTagNotFound = UINT32_MAX };
|
||||
|
||||
@@ -252,6 +256,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;
|
||||
@@ -328,6 +333,9 @@ public:
|
||||
CFTimeInterval _frameCounterStartTime;
|
||||
NSInteger _frameCount;
|
||||
CFTimeInterval _frameDurations;
|
||||
|
||||
BOOL _atLeastiOS_12_2_0;
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - Setup & Teardown -
|
||||
@@ -441,6 +449,7 @@ public:
|
||||
{
|
||||
_isTargetingInterfaceBuilder = NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent;
|
||||
_opaque = NO;
|
||||
_atLeastiOS_12_2_0 = [NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){12,2,0}];
|
||||
|
||||
BOOL background = [UIApplication sharedApplication].applicationState == UIApplicationStateBackground;
|
||||
if (!background)
|
||||
@@ -681,6 +690,20 @@ public:
|
||||
static_cast<uint32_t>(self.glView.drawableHeight) };
|
||||
}
|
||||
|
||||
+ (GLKView *)GLKViewWithFrame:(CGRect)frame context:(EAGLContext *)context opaque:(BOOL)opaque
|
||||
{
|
||||
GLKView *glView = [[GLKView alloc] initWithFrame:frame 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.contentMode = UIViewContentModeCenter;
|
||||
|
||||
return glView;
|
||||
}
|
||||
|
||||
- (void)createGLView
|
||||
{
|
||||
if (_context) return;
|
||||
@@ -692,21 +715,14 @@ public:
|
||||
|
||||
// create GL view
|
||||
//
|
||||
_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 = [MGLMapView GLKViewWithFrame:self.bounds context:_context opaque:_opaque];
|
||||
_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];
|
||||
_glView.contentMode = UIViewContentModeCenter;
|
||||
}
|
||||
|
||||
- (UIImage *)compassImage
|
||||
@@ -1101,6 +1117,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;
|
||||
}
|
||||
@@ -1113,8 +1136,28 @@ public:
|
||||
[self updateUserLocationAnnotationView];
|
||||
[self updateAnnotationViews];
|
||||
[self updateCalloutView];
|
||||
|
||||
[self.glView display];
|
||||
|
||||
#ifdef MGL_RECREATE_GL_IN_AN_EMERGENCY
|
||||
// See https://github.com/mapbox/mapbox-gl-native/issues/14232
|
||||
// glClear can be blocked for 1 second. This code is an "escape hatch",
|
||||
// an attempt to detect this situation and rebuild the GL views.
|
||||
if (self.enablePresentsWithTransaction && _atLeastiOS_12_2_0)
|
||||
{
|
||||
CFTimeInterval before = CACurrentMediaTime();
|
||||
[self.glView display];
|
||||
CFTimeInterval after = CACurrentMediaTime();
|
||||
|
||||
if (after-before >= 1.0) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self emergencyRecreateGL];
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
[self.glView display];
|
||||
}
|
||||
}
|
||||
|
||||
if (self.experimental_enableFrameRateMeasurement)
|
||||
@@ -1231,15 +1274,96 @@ public:
|
||||
[self updateDisplayLinkPreferredFramesPerSecond];
|
||||
}
|
||||
|
||||
- (void)setEnablePresentsWithTransaction:(BOOL)enablePresentsWithTransaction
|
||||
{
|
||||
if (_enablePresentsWithTransaction == enablePresentsWithTransaction)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_enablePresentsWithTransaction = enablePresentsWithTransaction;
|
||||
|
||||
// If the map is visible, change the layer property too
|
||||
if (self.window) {
|
||||
CAEAGLLayer *eaglLayer = MGL_OBJC_DYNAMIC_CAST(_glView.layer, CAEAGLLayer);
|
||||
eaglLayer.presentsWithTransaction = enablePresentsWithTransaction;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MGL_RECREATE_GL_IN_AN_EMERGENCY
|
||||
// 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 = [MGLMapView GLKViewWithFrame:self.bounds context:_context opaque:_opaque];
|
||||
_glView.delegate = self;
|
||||
|
||||
[self insertSubview:_glView atIndex:0];
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
- (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 +4275,8 @@ public:
|
||||
[newAnnotationContainerView addSubviews:annotationViews];
|
||||
[_glView insertSubview:newAnnotationContainerView atIndex:0];
|
||||
self.annotationContainerView = newAnnotationContainerView;
|
||||
|
||||
self.enablePresentsWithTransaction = (self.annotationContainerView.annotationViews.count > MGLPresentsWithTransactionAnnotationCount);
|
||||
}
|
||||
|
||||
/// Initialize and return a default annotation image that depicts a round pin
|
||||
@@ -4324,6 +4450,8 @@ public:
|
||||
annotationView.annotation = nil;
|
||||
[annotationView removeFromSuperview];
|
||||
[self.annotationContainerView.annotationViews removeObject:annotationView];
|
||||
|
||||
self.enablePresentsWithTransaction = (self.annotationContainerView.annotationViews.count > MGLPresentsWithTransactionAnnotationCount);
|
||||
|
||||
if (annotationTag == _selectedAnnotationTag)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user