diff --git a/Sources/HgiMetal/include/HgiMetal/texture.h b/Sources/HgiMetal/include/HgiMetal/texture.h index fbc2aa973..d95b4f52a 100644 --- a/Sources/HgiMetal/include/HgiMetal/texture.h +++ b/Sources/HgiMetal/include/HgiMetal/texture.h @@ -9,6 +9,8 @@ #include +#include "Arch/swiftInterop.h" + #include "Hgi/texture.h" #include "HgiMetal/api.h" #include "pxr/pxrns.h" @@ -59,7 +61,7 @@ class HgiMetalTexture final : public HgiTexture { HgiMetalTexture(const HgiMetalTexture &) = delete; id _textureId; -}; +} SWIFT_IMMORTAL_REFERENCE; PXR_NAMESPACE_CLOSE_SCOPE diff --git a/Sources/UsdView/Hydra/Hydra+RenderEngine.swift b/Sources/UsdView/Hydra/Hydra+RenderEngine.swift index 78960cee7..7c6daf1e3 100644 --- a/Sources/UsdView/Hydra/Hydra+RenderEngine.swift +++ b/Sources/UsdView/Hydra/Hydra+RenderEngine.swift @@ -41,6 +41,9 @@ public enum Hydra sceneDelegateId: Sdf.Path.absoluteRootPath(), driver: driver ) + + engine.setEnablePresentation(false) + engine.setRenderer(aov: .color) } public func render(at timeCode: Double, viewSize: CGSize) -> Pixar.HgiTextureHandle diff --git a/Sources/UsdView/Hydra/Hydra+View.swift b/Sources/UsdView/Hydra/Hydra+View.swift index ef0462af3..ea0efd07d 100644 --- a/Sources/UsdView/Hydra/Hydra+View.swift +++ b/Sources/UsdView/Hydra/Hydra+View.swift @@ -33,11 +33,11 @@ public extension Hydra public extension Hydra.Viewport { - init(engine: Hydra.RenderEngine, rgba: (Double, Double, Double, Double)) + init(engine: Hydra.RenderEngine) { #if canImport(Metal) && !os(visionOS) let renderer = Hydra.MTLRenderer(device: engine.hydraDevice, hydra: engine) - self.init(hydra: engine, renderer: renderer, rgba: rgba) + self.init(hydra: engine, renderer: renderer) #endif // canImport(Metal) && !os(visionOS) } } diff --git a/Sources/UsdView/Hydra/MTL/Hydra+MTLRenderer.swift b/Sources/UsdView/Hydra/MTL/Hydra+MTLRenderer.swift index 3929c16d1..12d4ba3bb 100644 --- a/Sources/UsdView/Hydra/MTL/Hydra+MTLRenderer.swift +++ b/Sources/UsdView/Hydra/MTL/Hydra+MTLRenderer.swift @@ -24,7 +24,7 @@ import PixarUSD private var hydra: Hydra.RenderEngine? private var pipelineState: MTLRenderPipelineState? - private var inFlightSemaphore = DispatchSemaphore(value: 1) + private var inFlightSemaphore = DispatchSemaphore(value: 3) convenience init(device: MTLDevice, hydra: Hydra.RenderEngine) { @@ -87,6 +87,11 @@ import PixarUSD public func draw(in view: MTKView) { + view.drawableSize = CGSize( + width: (view.frame.size.width > 0) ? view.frame.size.width : 400, + height: (view.frame.size.height > 0) ? view.frame.size.height : 300 + ) + drawFrame(in: view, timeCode: 0.0) } @@ -109,7 +114,7 @@ import PixarUSD let viewSize = view.drawableSize guard let hgiTexture = hydra?.render(at: timeCode, viewSize: viewSize), - let metalTexture = hgiTexture.GetId() as? MTLTexture, + let metalTexture = getMetalTexture(from: hgiTexture), let commandBuffer = hgi.pointee.GetPrimaryCommandBuffer() else { Msg.logger.error("HYDRA: Failed to draw the scene."); return false } @@ -154,6 +159,24 @@ import PixarUSD commandBuffer.present(drawable) } } + + public func getMetalTexture(from hgiTexture: Pixar.HgiTextureHandle) -> MTLTexture? + { + // get the hgi texture handle. + guard let hgiTex = hgiTexture.Get() + else { Msg.logger.error("HYDRA: Failed to retrieve the hgi texture."); return nil } + + // get the raw pointer from the hgi handle. + let rawPtr = UnsafeRawPointer(hgiTex) + + // get the hgi texture from the raw pointer. + let texPtr: Pixar.HgiMetalTexture = Unmanaged.fromOpaque(rawPtr).takeUnretainedValue() + + // get the metal texture from the hgi texture. + let metalTexture = texPtr.GetTextureId() + + return metalTexture + } } } #endif // canImport(Metal) && !os(visionOS) diff --git a/Sources/UsdView/Hydra/MTL/Hydra+MTLView.swift b/Sources/UsdView/Hydra/MTL/Hydra+MTLView.swift index 4d938e385..9f08f7a1e 100644 --- a/Sources/UsdView/Hydra/MTL/Hydra+MTLView.swift +++ b/Sources/UsdView/Hydra/MTL/Hydra+MTLView.swift @@ -38,35 +38,43 @@ import PixarUSD private let device: MTLDevice! private let renderer: MTLRenderer! - var rgba: (Double, Double, Double, Double) - - public init(hydra: Hydra.RenderEngine, renderer: MTLRenderer, rgba: (Double, Double, Double, Double)) + public init(hydra: Hydra.RenderEngine, renderer: MTLRenderer) { self.hydra = hydra - self.device = hydra.hydraDevice + device = hydra.hydraDevice self.renderer = renderer - self.rgba = rgba } public func makeCoordinator() -> Coordinator { - Coordinator() + let mtkView = MTKView() + mtkView.isPaused = false + mtkView.framebufferOnly = true + if let mode = CGDisplayCopyDisplayMode(CGMainDisplayID()) + { + mtkView.preferredFramesPerSecond = Int(mode.refreshRate) + } + else + { + mtkView.preferredFramesPerSecond = 60 + } + mtkView.drawableSize = mtkView.frame.size + + return Coordinator(mtkView: mtkView) } public func makeNSView(context: Context) -> MTKView { let metalView = context.coordinator.metalView + metalView.device = device metalView.delegate = renderer - metalView.clearColor = MTLClearColorMake(rgba.0, rgba.1, rgba.2, rgba.3) - metalView.apply(context.environment) - - context.coordinator.setNeedsDisplayTrigger = context.environment.setNeedsDisplayTrigger + metalView.becomeFirstResponder() return metalView } - public func updateNSView(_ view: MTKView, context: Context) + public func updateNSView(_ view: MTKView, context _: Context) { renderer.draw(in: view) } @@ -74,12 +82,13 @@ import PixarUSD public class Coordinator { private var cancellable: AnyCancellable? - public var metalView: MTKView = .init(frame: .zero) + public var metalView: MTKView - public init() + public init(mtkView: MTKView) { cancellable = nil setNeedsDisplayTrigger = nil + metalView = mtkView } public var setNeedsDisplayTrigger: SetNeedsDisplayTrigger? diff --git a/Sources/UsdView/UsdView.swift b/Sources/UsdView/UsdView.swift index 0bc9fd54c..0a1f4e619 100644 --- a/Sources/UsdView/UsdView.swift +++ b/Sources/UsdView/UsdView.swift @@ -39,10 +39,6 @@ struct UsdView: PixarApp /// the hydra rendering engine. let engine: Hydra.RenderEngine - /// give it a color spectrum... - @State var rgba = (0.1, 0.1, 0.1, 1.0) - @State var hue = 0.0 - public init() { // register all usd plugins & resources. @@ -61,15 +57,7 @@ struct UsdView: PixarApp { WindowGroup("UsdView", id: "usdview") { - VStack - { - Hydra.Viewport(engine: engine, rgba: rgba) - .ignoresSafeArea() - } - .onAppear - { - startColorAnimation() - } + Hydra.Viewport(engine: engine) } } } diff --git a/Sources/UsdView/Utils/ShadingUtils.swift b/Sources/UsdView/Utils/ShadingUtils.swift index c02c4b847..9827f59e2 100644 --- a/Sources/UsdView/Utils/ShadingUtils.swift +++ b/Sources/UsdView/Utils/ShadingUtils.swift @@ -62,34 +62,3 @@ public func matDef(_ stage: UsdStageRefPtr, color: ShadeColor = ShadeColor.white return material } - -#if canImport(SwiftUI) - import SwiftUI - - extension UsdView - { - func startColorAnimation() - { - Timer.scheduledTimer(withTimeInterval: 0.03, repeats: true) - { _ in - hue += 0.01 - if hue > 1.0 { hue = 0.0 } - rgba = hueToRGBA(hue: hue) - } - } - - func hueToRGBA(hue: Double) -> (Double, Double, Double, Double) - { - let color = Color(hue: hue, saturation: 1.0, brightness: 1.0) - var red: Double = 0, green: Double = 0, blue: Double = 0, alpha: Double = 0 - if let components = color.cgColor?.components, components.count >= 3 - { - red = components[0] - green = components[1] - blue = components[2] - alpha = Double(color.cgColor?.alpha ?? 1.0) - } - return (red, green, blue, alpha) - } - } -#endif // canImport(SwiftUI)