diff --git a/platform/macos/src/MLNMapView+Impl.h b/platform/macos/src/MLNMapView+Impl.h index c7215f240..1c653d8a1 100644 --- a/platform/macos/src/MLNMapView+Impl.h +++ b/platform/macos/src/MLNMapView+Impl.h @@ -22,6 +22,8 @@ public: virtual CGLContextObj getCGLContextObj() { return nullptr; } + virtual void display(); + #if MLN_RENDER_BACKEND_METAL // Returns the backend resource for Metal rendering in custom layers virtual MLNBackendResource* getObject() { return nullptr; } diff --git a/platform/macos/src/MLNMapView+Impl.mm b/platform/macos/src/MLNMapView+Impl.mm index 6828cba38..923164590 100644 --- a/platform/macos/src/MLNMapView+Impl.mm +++ b/platform/macos/src/MLNMapView+Impl.mm @@ -23,6 +23,8 @@ MLNMapViewImpl::MLNMapViewImpl(MLNMapView* nativeView_) : mapView(nativeView_) { void MLNMapViewImpl::render() { [mapView renderSync]; } +void MLNMapViewImpl::display() { [mapView.layer setNeedsDisplay]; } + void MLNMapViewImpl::onCameraWillChange(mbgl::MapObserver::CameraChangeMode mode) { bool animated = mode == mbgl::MapObserver::CameraChangeMode::Animated; [mapView cameraWillChangeAnimated:animated]; diff --git a/platform/macos/src/MLNMapView+Metal.h b/platform/macos/src/MLNMapView+Metal.h index 2b0e569f1..d24778f98 100644 --- a/platform/macos/src/MLNMapView+Metal.h +++ b/platform/macos/src/MLNMapView+Metal.h @@ -37,7 +37,8 @@ public: mbgl::PremultipliedImage readStillImage() override; MLNBackendResource* getObject() override; + void display() override; private: - bool presentsWithTransaction = false; + bool presentsWithTransaction = true; }; diff --git a/platform/macos/src/MLNMapView+Metal.mm b/platform/macos/src/MLNMapView+Metal.mm index f77e6c7f7..bc4f9c42c 100644 --- a/platform/macos/src/MLNMapView+Metal.mm +++ b/platform/macos/src/MLNMapView+Metal.mm @@ -70,12 +70,16 @@ public: void swap() override { id currentDrawable = [mtlView currentDrawable]; - [commandBuffer presentDrawable:currentDrawable]; - [commandBuffer commit]; - - // Un-comment for synchronous, which can help troubleshoot rendering problems, - // particularly those related to resource tracking and multiple queued buffers. - //[commandBuffer waitUntilCompleted]; + if (currentDrawable) { + if (presentsWithTransaction) { + [commandBuffer commit]; + [commandBuffer waitUntilCompleted]; + [currentDrawable present]; + } else { + [commandBuffer presentDrawable:currentDrawable]; + [commandBuffer commit]; + } + } commandBuffer = nil; commandBufferPtr.reset(); @@ -99,6 +103,7 @@ public: MTKView* mtlView = nil; id commandBuffer; id commandQueue; + bool presentsWithTransaction = false; // We count how often the context was activated/deactivated so that we can truly deactivate it // after the activation count drops to 0. @@ -122,9 +127,11 @@ MLNMapViewMetalImpl::MLNMapViewMetalImpl(MLNMapView* nativeView_) resource.mtlView.colorPixelFormat = MTLPixelFormatBGRA8Unorm; resource.mtlView.depthStencilPixelFormat = MTLPixelFormatDepth32Float_Stencil8; 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); metalLayer.presentsWithTransaction = presentsWithTransaction; + resource.presentsWithTransaction = presentsWithTransaction; [mapView addSubview:resource.mtlView positioned:NSWindowBelow relativeTo:nil]; } @@ -159,6 +166,11 @@ mbgl::PremultipliedImage MLNMapViewMetalImpl::readStillImage() { return {}; } +void MLNMapViewMetalImpl::display() { + auto& resource = getResource(); + resource.mtlView.needsDisplay = YES; +} + MLNBackendResource* MLNMapViewMetalImpl::getObject() { auto& resource = getResource(); diff --git a/platform/macos/src/MLNMapView.mm b/platform/macos/src/MLNMapView.mm index 9ce4674c4..e39a4cc81 100644 --- a/platform/macos/src/MLNMapView.mm +++ b/platform/macos/src/MLNMapView.mm @@ -939,7 +939,10 @@ public: - (void)setNeedsRerender { MLNAssertIsMainThread(); - [self.layer setNeedsDisplay]; + if (!_mbglView) { + return; + } + _mbglView->display(); } - (void)cameraWillChangeAnimated:(BOOL)animated {