using AcDream.App.Rendering.Gpu.Vk; using Silk.NET.OpenGL; namespace AcDream.App.Composition; /// /// Campaign V slice V6h: the graphics ownership that platform acquisition /// publishes, once per backend. /// /// was already generic over its /// graphics type; only the call sites pinned GL. This class is what they /// pin instead, so one composition pipeline drives both backends and the fork /// lives at the handful of construction sites that genuinely differ rather than /// in a second copy of the startup topology. /// /// It is deliberately NOT a capability abstraction. Nothing dispatches on /// it per frame; phases that still speak raw GL ask for the context by name and /// take their Vulkan arm when it is absent. The GL arm is deleted at slice V11 /// and this class with it. /// internal abstract class GameWindowGraphics : IDisposable { /// Which backend this handle owns. public abstract RenderBackendKind Backend { get; } /// /// The live GL context, or null on any other backend. Phases whose owners /// are still raw GL branch on this; each such branch is a slice of Campaign /// V that has not landed yet, and the null arm names which one. /// public virtual GL? Gl => null; /// The live Vulkan context, or null on any other backend. public virtual VulkanGraphicsContext? Vulkan => null; /// /// The GL context, or a failure naming the caller. Used where the call site /// has already established that the GL arm is running, so a null would be a /// composition bug rather than a backend difference. /// public GL RequireGl(string owner) => Gl ?? throw new InvalidOperationException( $"'{owner}' requires the OpenGL context, but the {Backend} backend is active."); public abstract void Dispose(); } /// OpenGL ownership: the Silk.NET context itself. internal sealed class OpenGlGameWindowGraphics : GameWindowGraphics { public OpenGlGameWindowGraphics(GL gl) => Context = gl ?? throw new ArgumentNullException(nameof(gl)); /// The owned context. is the borrowed view. public GL Context { get; } public override RenderBackendKind Backend => RenderBackendKind.Gl; public override GL? Gl => Context; public override void Dispose() => Context.Dispose(); } /// /// Vulkan ownership: the instance, surface, device, swapchain and RHI device /// that acquired and gated. /// internal sealed class VulkanGameWindowGraphics : GameWindowGraphics { public VulkanGameWindowGraphics(VulkanGraphicsContext context) => Context = context ?? throw new ArgumentNullException(nameof(context)); public VulkanGraphicsContext Context { get; } public override RenderBackendKind Backend => RenderBackendKind.Vulkan; public override VulkanGraphicsContext? Vulkan => Context; public override void Dispose() => Context.Dispose(); }