-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Optimize annotation view updates #5987
Optimize annotation view updates #5987
Conversation
f44cdeb
to
bcc3d9c
Compare
- Get sets of visible and offscreen annotations and update and enqueue as required - Query viewport adjusted if tilted (avoid apparent issue with queryPointAnnotations when the query box is larger than the actual viewport) - Add a small debugging display in iOS app to see annotations going in and out of the reuse queue
This works around a performance issue that made getting an annotation context expensive. It also works around an issue with the underlying mbgl query so that even if it (rarely) returns an incorrect result, the correct visual effect still occurs and the reuse queue is added to and drained as expected.
But implement it with _annotationContextsByAnnotation to avoid the expensive lookup in annotationTagForAnnotation:
d374b45
to
a8c481b
Compare
The fix of #6055 freed us up to make some long desired changes to the way annotation views are updated and queued for reuse. The summary of changes here so far is:
When testing for 1 minute with 10,000 annotation views, high zoom (to trigger heavy reuse queue usage), and a constant panning gesture, the performance increase is significant: Before: total weight of ~50 seconds and
|
Noting also that while this is not a complete fix for #5489, I'm seeing much better results when scrolling since, I think, the main thread as a whole is taxed far less than before. |
typedef std::map<MGLAnnotationTag, MGLAnnotationContext> MGLAnnotationContextMap; | ||
typedef std::map<MGLAnnotationTag, MGLAnnotationContext> MGLAnnotationTagContextMap; | ||
|
||
typedef std::map<id<MGLAnnotation>, MGLAnnotationContext> MGLAnnotationObjectContextMap; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if we instead have a mapping from annotation objects to annotation tags? It would be an additional hop, but also less parallel state to keep in sync.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. Done in fc8d77a
@@ -129,7 +129,9 @@ typedef NS_ENUM(NSUInteger, MGLUserTrackingState) { | |||
|
|||
/// Mapping from an annotation tag to metadata about that annotation, including | |||
/// the annotation itself. | |||
typedef std::map<MGLAnnotationTag, MGLAnnotationContext> MGLAnnotationContextMap; | |||
typedef std::map<MGLAnnotationTag, MGLAnnotationContext> MGLAnnotationTagContextMap; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename this type in the macOS implementation as well to keep the two implementations from diverging too much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in fc8d77a
This creates an extra hop to get the context but eliminates the need to sync two sets of references to each context object. This also syncs up the ios and macos names (and types) for MGLAnnotationTagContextMap
@@ -189,6 +192,7 @@ - (void)accessibilityDecrement | |||
MGLAnnotationAccessibilityElement *accessibilityElement; | |||
MGLAnnotationView *annotationView; | |||
NSString *viewReuseIdentifier; | |||
MGLAnnotationTag annotationTag; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unused, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 8e67bef
@@ -1506,9 +1527,24 @@ - (void)mapView:(MGLMapView *)mapView tapOnCalloutForAnnotation:(id <MGLAnnotati | |||
- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style | |||
{ | |||
// Default Mapbox styles use {name_en} as their label language, which means | |||
NSUInteger queuedAnnotations = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a bad merge occurred.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Fixed in #6882
Streamlined -[MGLMapView annotationTagForAnnotation:] to use the mapping added in #5987. Reverted an unsafe access into that mapping that was added in #5987; returning nil is preferable when no such annotation can be found. Return the user location annotation view when given the user location annotation.
Streamlined -[MGLMapView annotationTagForAnnotation:] to use the mapping added in #5987. Reverted an unsafe access into that mapping that was added in #5987; returning nil is preferable when no such annotation can be found. Return the user location annotation view when given the user location annotation.
Now that #5165 has landed, we can address the issues reported in #5787 and again in #5489 (comment). This PR will:
MGLAnnotationView
subclassesqueryPointAnnotations
(from Replace getPointAnnotationsInBounds() w/ queryPointAnnotations() #5165) to operate on potentially less view backed annotations when updating themFixes #5787
cc @incanus @1ec5