Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Synchronous rendering on Metal when annotation views are visible #2334

Merged
merged 4 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions platform/ios/src/MLNMapView+Impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ class MLNMapViewImpl : public mbgl::MapObserver {
void render();

virtual MLNBackendResource getObject() = 0;

virtual void setSynchronous(bool value) {};
virtual bool getSynchronous() const { return false; };


// mbgl::MapObserver implementation
void onCameraWillChange(mbgl::MapObserver::CameraChangeMode) override;
Expand Down
3 changes: 3 additions & 0 deletions platform/ios/src/MLNMapView+Metal.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class MLNMapViewMetalImpl final : public MLNMapViewImpl,
MLNBackendResource getObject() override;
// End implementation of MLNMapViewImpl

void setSynchronous(bool value) override { synchronousFrame = value; };
bool getSynchronous() const override { return synchronousFrame; };
private:
bool presentsWithTransaction = false;
bool synchronousFrame = false;
};
10 changes: 8 additions & 2 deletions platform/ios/src/MLNMapView+Metal.mm
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,15 @@ void swap() override {
}
[commandBuffer commit];

// Un-comment for synchronous, which can help troubleshoot rendering problems,
// Synchronous rendering can help troubleshoot rendering problems,
// particularly those related to resource tracking and multiple queued buffers.
//[commandBuffer waitUntilCompleted];
// The conditional logic for synchronous rendering is commanded from MLNMapView.updateAnnotationViews:
// `_mbglView->setSynchronous(haveVisibleAnnotationViews);`
// and fixes the desynchronization of UIView annotation when the map is rendered on the Metal backend
// Issue: https://github.com/maplibre/maplibre-native/issues/2053
if (backend.getSynchronous()) {
[commandBuffer waitUntilCompleted];
}

commandBuffer = nil;
commandBufferPtr.reset();
Expand Down
12 changes: 12 additions & 0 deletions platform/ios/src/MLNMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -6917,6 +6917,9 @@ - (void)updateAnnotationViews
NSMutableArray *offscreenAnnotations = [self.annotations mutableCopy];
[offscreenAnnotations removeObjectsInArray:visibleAnnotations];

// Dynamic flag used to drive the backend's synchronous frame rendering (see comment below)
bool haveVisibleAnnotationViews = false;

// Update the center of visible annotation views
for (id<MLNAnnotation> annotation in visibleAnnotations)
{
Expand Down Expand Up @@ -6953,6 +6956,7 @@ - (void)updateAnnotationViews
if (annotationView)
{
annotationView.center = MLNPointRounded([self convertCoordinate:annotationContext.annotation.coordinate toPointToView:self]);
haveVisibleAnnotationViews = true;
}
}

Expand Down Expand Up @@ -7000,6 +7004,14 @@ - (void)updateAnnotationViews
}
}
}

// Switch synchronous frame rendering on if we have visible annotation views.
// Only implemented on Metal, just a stub on OpenGL.
// This logic is needed to fix the desynchronization of UIView annotations when the map is rendered on the Metal backend with asynchronous frames.
// Root cause: the Map transform is updated immediately and the annotations are positioned on the screen using it,
// while the map rendered surface catches up when the frame is complete.
// Issue: https://github.com/maplibre/maplibre-native/issues/2053
_mbglView->setSynchronous(haveVisibleAnnotationViews);
}

- (BOOL)hasAnAnchoredAnnotationCalloutView
Expand Down
Loading