From 816363f0afe0ca04af5aea27a10761c63d670367 Mon Sep 17 00:00:00 2001 From: Chen Date: Sun, 5 Apr 2026 16:15:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(capture):=20=E4=BF=AE=E5=A4=8D=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=AE=BF=E4=B8=BB=E8=A7=86=E5=9B=BE=E5=B8=83=E5=B1=80?= =?UTF-8?q?=E9=80=92=E5=BD=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除 layout 中的图层同步,改用自动尺寸调整 - 避免重复挂载同一个预览图层 - 补充宿主视图图层挂载测试 --- .../Views/ZeroCopyPreviewRenderer.swift | 19 +++++++++---------- .../Views/ZeroCopyPreviewRendererTests.swift | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/VoidDisplay/Features/Capture/Views/ZeroCopyPreviewRenderer.swift b/VoidDisplay/Features/Capture/Views/ZeroCopyPreviewRenderer.swift index 76ea630..06a33cd 100644 --- a/VoidDisplay/Features/Capture/Views/ZeroCopyPreviewRenderer.swift +++ b/VoidDisplay/Features/Capture/Views/ZeroCopyPreviewRenderer.swift @@ -164,23 +164,23 @@ final class ZeroCopyHostView: NSView { private weak var displayLayer: AVSampleBufferDisplayLayer? func hostDisplayLayer(_ layer: AVSampleBufferDisplayLayer) { + if displayLayer === layer { + return + } + wantsLayer = true + if self.layer == nil { + self.layer = CALayer() + } layerContentsRedrawPolicy = .duringViewResize layer.frame = bounds + layer.autoresizingMask = [.layerWidthSizable, .layerHeightSizable] + displayLayer?.removeFromSuperlayer() self.layer?.addSublayer(layer) displayLayer = layer syncLayerScale() } - override func layout() { - super.layout() - CATransaction.begin() - CATransaction.setDisableActions(true) - displayLayer?.frame = bounds - CATransaction.commit() - syncLayerScale() - } - override func viewDidMoveToWindow() { super.viewDidMoveToWindow() syncLayerScale() @@ -193,7 +193,6 @@ final class ZeroCopyHostView: NSView { private func syncLayerScale() { let scale = max(1, window?.backingScaleFactor ?? NSScreen.main?.backingScaleFactor ?? 1) - layer?.contentsScale = scale displayLayer?.contentsScale = scale } } diff --git a/VoidDisplayTests/Features/Capture/Views/ZeroCopyPreviewRendererTests.swift b/VoidDisplayTests/Features/Capture/Views/ZeroCopyPreviewRendererTests.swift index b610bde..c75fb05 100644 --- a/VoidDisplayTests/Features/Capture/Views/ZeroCopyPreviewRendererTests.swift +++ b/VoidDisplayTests/Features/Capture/Views/ZeroCopyPreviewRendererTests.swift @@ -1,3 +1,5 @@ +import AppKit +import AVFoundation import CoreGraphics import Testing @testable import VoidDisplay @@ -92,6 +94,18 @@ struct ZeroCopyPreviewRendererTests { #expect(renderer.hasReceivedFrame == false) } + @Test func hostViewDoesNotDuplicateHostedLayer() { + let view = ZeroCopyHostView(frame: NSRect(x: 0, y: 0, width: 320, height: 180)) + let layer = AVSampleBufferDisplayLayer() + + view.hostDisplayLayer(layer) + view.hostDisplayLayer(layer) + + #expect(view.layer != nil) + #expect(view.layer?.sublayers?.count == 1) + #expect(view.layer?.sublayers?.first === layer) + } + private func waitUntil( timeout: Duration = .seconds(1), condition: @escaping @Sendable () async -> Bool