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
}