Skip to content
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
19 changes: 9 additions & 10 deletions VoidDisplay/Features/Capture/Views/ZeroCopyPreviewRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import AppKit
import AVFoundation
import CoreGraphics
import Testing
@testable import VoidDisplay
Expand Down Expand Up @@ -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
Expand Down