using System; using System.Collections.Generic; using Vortice.DXGI; namespace ScreenCapture.NET; /// /// Represents a using the . /// public class DX11ScreenCaptureService : IScreenCaptureService { #region Properties & Fields private readonly IDXGIFactory1 _factory; private readonly Dictionary _screenCaptures = new(); private bool _isDisposed; #endregion #region Constructors /// /// Initializes a new instance of the class. /// public DX11ScreenCaptureService() { DXGI.CreateDXGIFactory1(out _factory!).CheckError(); } ~DX11ScreenCaptureService() => Dispose(); #endregion #region Methods /// public IEnumerable GetGraphicsCards() { if (_isDisposed) throw new ObjectDisposedException(GetType().FullName); int i = 0; while (_factory.EnumAdapters1(i, out IDXGIAdapter1 adapter).Success) { yield return new GraphicsCard(i, adapter.Description1.Description, adapter.Description1.VendorId, adapter.Description1.DeviceId); adapter.Dispose(); i++; } } /// public IEnumerable GetDisplays(GraphicsCard graphicsCard) { if (_isDisposed) throw new ObjectDisposedException(GetType().FullName); using IDXGIAdapter1? adapter = _factory.GetAdapter1(graphicsCard.Index); int i = 0; while (adapter.EnumOutputs(i, out IDXGIOutput output).Success) { int width = output.Description.DesktopCoordinates.Right - output.Description.DesktopCoordinates.Left; int height = output.Description.DesktopCoordinates.Bottom - output.Description.DesktopCoordinates.Top; yield return new Display(i, output.Description.DeviceName, width, height, GetRotation(output.Description.Rotation), graphicsCard); output.Dispose(); i++; } } private static Rotation GetRotation(ModeRotation rotation) => rotation switch { ModeRotation.Rotate90 => Rotation.Rotation90, ModeRotation.Rotate180 => Rotation.Rotation180, ModeRotation.Rotate270 => Rotation.Rotation270, _ => Rotation.None }; /// IScreenCapture IScreenCaptureService.GetScreenCapture(Display display) => GetScreenCapture(display); public DX11ScreenCapture GetScreenCapture(Display display) { if (_isDisposed) throw new ObjectDisposedException(GetType().FullName); if (!_screenCaptures.TryGetValue(display, out DX11ScreenCapture? screenCapture)) _screenCaptures.Add(display, screenCapture = new DX11ScreenCapture(_factory, display)); return screenCapture; } /// public void Dispose() { if (_isDisposed) return; foreach (DX11ScreenCapture screenCapture in _screenCaptures.Values) screenCapture.Dispose(); _screenCaptures.Clear(); try { _factory.Dispose(); } catch { /**/ } GC.SuppressFinalize(this); _isDisposed = true; } #endregion }