macOS: render the Metal map on demand (#4480)

This commit is contained in:
Bouke van der Bijl
2026-08-14 15:24:14 +02:00
committed by GitHub
parent 743ed53794
commit d508e65692
5 changed files with 29 additions and 9 deletions

View File

@@ -22,6 +22,8 @@ public:
virtual CGLContextObj getCGLContextObj() { return nullptr; } virtual CGLContextObj getCGLContextObj() { return nullptr; }
virtual void display();
#if MLN_RENDER_BACKEND_METAL #if MLN_RENDER_BACKEND_METAL
// Returns the backend resource for Metal rendering in custom layers // Returns the backend resource for Metal rendering in custom layers
virtual MLNBackendResource* getObject() { return nullptr; } virtual MLNBackendResource* getObject() { return nullptr; }

View File

@@ -23,6 +23,8 @@ MLNMapViewImpl::MLNMapViewImpl(MLNMapView* nativeView_) : mapView(nativeView_) {
void MLNMapViewImpl::render() { [mapView renderSync]; } void MLNMapViewImpl::render() { [mapView renderSync]; }
void MLNMapViewImpl::display() { [mapView.layer setNeedsDisplay]; }
void MLNMapViewImpl::onCameraWillChange(mbgl::MapObserver::CameraChangeMode mode) { void MLNMapViewImpl::onCameraWillChange(mbgl::MapObserver::CameraChangeMode mode) {
bool animated = mode == mbgl::MapObserver::CameraChangeMode::Animated; bool animated = mode == mbgl::MapObserver::CameraChangeMode::Animated;
[mapView cameraWillChangeAnimated:animated]; [mapView cameraWillChangeAnimated:animated];

View File

@@ -37,7 +37,8 @@ public:
mbgl::PremultipliedImage readStillImage() override; mbgl::PremultipliedImage readStillImage() override;
MLNBackendResource* getObject() override; MLNBackendResource* getObject() override;
void display() override;
private: private:
bool presentsWithTransaction = false; bool presentsWithTransaction = true;
}; };

View File

@@ -70,12 +70,16 @@ public:
void swap() override { void swap() override {
id<CAMetalDrawable> currentDrawable = [mtlView currentDrawable]; id<CAMetalDrawable> currentDrawable = [mtlView currentDrawable];
[commandBuffer presentDrawable:currentDrawable]; if (currentDrawable) {
[commandBuffer commit]; if (presentsWithTransaction) {
[commandBuffer commit];
// Un-comment for synchronous, which can help troubleshoot rendering problems, [commandBuffer waitUntilCompleted];
// particularly those related to resource tracking and multiple queued buffers. [currentDrawable present];
//[commandBuffer waitUntilCompleted]; } else {
[commandBuffer presentDrawable:currentDrawable];
[commandBuffer commit];
}
}
commandBuffer = nil; commandBuffer = nil;
commandBufferPtr.reset(); commandBufferPtr.reset();
@@ -99,6 +103,7 @@ public:
MTKView* mtlView = nil; MTKView* mtlView = nil;
id<MTLCommandBuffer> commandBuffer; id<MTLCommandBuffer> commandBuffer;
id<MTLCommandQueue> commandQueue; id<MTLCommandQueue> commandQueue;
bool presentsWithTransaction = false;
// We count how often the context was activated/deactivated so that we can truly deactivate it // We count how often the context was activated/deactivated so that we can truly deactivate it
// after the activation count drops to 0. // after the activation count drops to 0.
@@ -122,9 +127,11 @@ MLNMapViewMetalImpl::MLNMapViewMetalImpl(MLNMapView* nativeView_)
resource.mtlView.colorPixelFormat = MTLPixelFormatBGRA8Unorm; resource.mtlView.colorPixelFormat = MTLPixelFormatBGRA8Unorm;
resource.mtlView.depthStencilPixelFormat = MTLPixelFormatDepth32Float_Stencil8; resource.mtlView.depthStencilPixelFormat = MTLPixelFormatDepth32Float_Stencil8;
resource.mtlView.layer.opaque = mapView.opaque; resource.mtlView.layer.opaque = mapView.opaque;
resource.mtlView.enableSetNeedsDisplay = NO; resource.mtlView.paused = YES;
resource.mtlView.enableSetNeedsDisplay = YES;
CAMetalLayer* metalLayer = MLN_OBJC_DYNAMIC_CAST(resource.mtlView.layer, CAMetalLayer); CAMetalLayer* metalLayer = MLN_OBJC_DYNAMIC_CAST(resource.mtlView.layer, CAMetalLayer);
metalLayer.presentsWithTransaction = presentsWithTransaction; metalLayer.presentsWithTransaction = presentsWithTransaction;
resource.presentsWithTransaction = presentsWithTransaction;
[mapView addSubview:resource.mtlView positioned:NSWindowBelow relativeTo:nil]; [mapView addSubview:resource.mtlView positioned:NSWindowBelow relativeTo:nil];
} }
@@ -159,6 +166,11 @@ mbgl::PremultipliedImage MLNMapViewMetalImpl::readStillImage() {
return {}; return {};
} }
void MLNMapViewMetalImpl::display() {
auto& resource = getResource<MLNMapViewMetalRenderableResource>();
resource.mtlView.needsDisplay = YES;
}
MLNBackendResource* MLNMapViewMetalImpl::getObject() { MLNBackendResource* MLNMapViewMetalImpl::getObject() {
auto& resource = getResource<MLNMapViewMetalRenderableResource>(); auto& resource = getResource<MLNMapViewMetalRenderableResource>();

View File

@@ -939,7 +939,10 @@ public:
- (void)setNeedsRerender { - (void)setNeedsRerender {
MLNAssertIsMainThread(); MLNAssertIsMainThread();
[self.layer setNeedsDisplay]; if (!_mbglView) {
return;
}
_mbglView->display();
} }
- (void)cameraWillChangeAnimated:(BOOL)animated { - (void)cameraWillChangeAnimated:(BOOL)animated {