mirror of
https://github.com/jkocon/g-helper.git
synced 2026-02-23 13:00:52 +01:00
Experimental GPU overclock
This commit is contained in:
200
app/NvAPIWrapper/Display/ColorData.cs
Normal file
200
app/NvAPIWrapper/Display/ColorData.cs
Normal file
@@ -0,0 +1,200 @@
|
||||
using System;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <inheritdoc cref="IColorData" />
|
||||
public class ColorData : IColorData, IEquatable<ColorData>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an instance of <see cref="ColorData" /> to modify the color data
|
||||
/// </summary>
|
||||
/// <param name="colorFormat">The color data color format.</param>
|
||||
/// <param name="colorimetry">The color data color space.</param>
|
||||
/// <param name="dynamicRange">The color data dynamic range.</param>
|
||||
/// <param name="colorDepth">The color data color depth.</param>
|
||||
/// <param name="colorSelectionPolicy">The color data selection policy.</param>
|
||||
/// <param name="desktopColorDepth">The color data desktop color depth.</param>
|
||||
public ColorData(
|
||||
ColorDataFormat colorFormat = ColorDataFormat.Auto,
|
||||
ColorDataColorimetry colorimetry = ColorDataColorimetry.Auto,
|
||||
ColorDataDynamicRange? dynamicRange = null,
|
||||
ColorDataDepth? colorDepth = null,
|
||||
ColorDataSelectionPolicy? colorSelectionPolicy = null,
|
||||
ColorDataDesktopDepth? desktopColorDepth = null
|
||||
)
|
||||
{
|
||||
ColorFormat = colorFormat;
|
||||
Colorimetry = colorimetry;
|
||||
DynamicRange = dynamicRange;
|
||||
ColorDepth = colorDepth;
|
||||
SelectionPolicy = colorSelectionPolicy;
|
||||
DesktopColorDepth = desktopColorDepth;
|
||||
}
|
||||
|
||||
internal ColorData(IColorData colorData)
|
||||
{
|
||||
ColorDepth = colorData.ColorDepth;
|
||||
DynamicRange = colorData.DynamicRange;
|
||||
ColorFormat = colorData.ColorFormat;
|
||||
Colorimetry = colorData.Colorimetry;
|
||||
SelectionPolicy = colorData.SelectionPolicy;
|
||||
DesktopColorDepth = colorData.DesktopColorDepth;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataDepth? ColorDepth { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataFormat ColorFormat { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataColorimetry Colorimetry { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataDesktopDepth? DesktopColorDepth { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataDynamicRange? DynamicRange { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataSelectionPolicy? SelectionPolicy { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(ColorData other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return ColorDepth == other.ColorDepth &&
|
||||
ColorFormat == other.ColorFormat &&
|
||||
Colorimetry == other.Colorimetry &&
|
||||
DesktopColorDepth == other.DesktopColorDepth &&
|
||||
DynamicRange == other.DynamicRange &&
|
||||
SelectionPolicy == other.SelectionPolicy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances of <see cref="ColorData" /> for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns>true if two instances are equal; otherwise false.</returns>
|
||||
public static bool operator ==(ColorData left, ColorData right)
|
||||
{
|
||||
return left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances of <see cref="ColorData" /> for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns>true if two instances are not equal; otherwise false.</returns>
|
||||
public static bool operator !=(ColorData left, ColorData right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((ColorData) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = ColorDepth.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (int) ColorFormat;
|
||||
hashCode = (hashCode * 397) ^ (int) Colorimetry;
|
||||
hashCode = (hashCode * 397) ^ DesktopColorDepth.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ DynamicRange.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ SelectionPolicy.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
internal ColorDataV1 AsColorDataV1(ColorDataCommand command)
|
||||
{
|
||||
return new ColorDataV1(
|
||||
command,
|
||||
ColorFormat,
|
||||
Colorimetry
|
||||
);
|
||||
}
|
||||
|
||||
internal ColorDataV2 AsColorDataV2(ColorDataCommand command)
|
||||
{
|
||||
return new ColorDataV2(
|
||||
command,
|
||||
ColorFormat,
|
||||
Colorimetry,
|
||||
DynamicRange ?? ColorDataDynamicRange.Auto
|
||||
);
|
||||
}
|
||||
|
||||
internal ColorDataV3 AsColorDataV3(ColorDataCommand command)
|
||||
{
|
||||
return new ColorDataV3(
|
||||
command,
|
||||
ColorFormat,
|
||||
Colorimetry,
|
||||
DynamicRange ?? ColorDataDynamicRange.Auto,
|
||||
ColorDepth ?? ColorDataDepth.Default
|
||||
);
|
||||
}
|
||||
|
||||
internal ColorDataV4 AsColorDataV4(ColorDataCommand command)
|
||||
{
|
||||
return new ColorDataV4(
|
||||
command,
|
||||
ColorFormat,
|
||||
Colorimetry,
|
||||
DynamicRange ?? ColorDataDynamicRange.Auto,
|
||||
ColorDepth ?? ColorDataDepth.Default,
|
||||
SelectionPolicy ?? ColorDataSelectionPolicy.Default
|
||||
);
|
||||
}
|
||||
|
||||
internal ColorDataV5 AsColorDataV5(ColorDataCommand command)
|
||||
{
|
||||
return new ColorDataV5(
|
||||
command,
|
||||
ColorFormat,
|
||||
Colorimetry,
|
||||
DynamicRange ?? ColorDataDynamicRange.Auto,
|
||||
ColorDepth ?? ColorDataDepth.Default,
|
||||
SelectionPolicy ?? ColorDataSelectionPolicy.Default,
|
||||
DesktopColorDepth ?? ColorDataDesktopDepth.Default
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
245
app/NvAPIWrapper/Display/CustomResolution.cs
Normal file
245
app/NvAPIWrapper/Display/CustomResolution.cs
Normal file
@@ -0,0 +1,245 @@
|
||||
using System;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Hold information about a custom display resolution
|
||||
/// </summary>
|
||||
public class CustomResolution : IEquatable<CustomResolution>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an instance of <see cref="CustomResolution" />.
|
||||
/// </summary>
|
||||
/// <param name="width">The screen width.</param>
|
||||
/// <param name="height">The screen height.</param>
|
||||
/// <param name="colorFormat">The color format.</param>
|
||||
/// <param name="timing">The resolution timing.</param>
|
||||
/// <param name="xRatio">The horizontal scaling ratio.</param>
|
||||
/// <param name="yRatio">The vertical scaling ratio.</param>
|
||||
public CustomResolution(
|
||||
uint width,
|
||||
uint height,
|
||||
ColorFormat colorFormat,
|
||||
Timing timing,
|
||||
float xRatio = 1,
|
||||
float yRatio = 1
|
||||
)
|
||||
{
|
||||
if (xRatio <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(xRatio));
|
||||
}
|
||||
|
||||
if (yRatio <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(yRatio));
|
||||
}
|
||||
|
||||
Width = width;
|
||||
Height = height;
|
||||
ColorFormat = colorFormat;
|
||||
XRatio = xRatio;
|
||||
YRatio = yRatio;
|
||||
Timing = timing;
|
||||
|
||||
switch (ColorFormat)
|
||||
{
|
||||
case ColorFormat.P8:
|
||||
ColorDepth = 8;
|
||||
|
||||
break;
|
||||
case ColorFormat.R5G6B5:
|
||||
ColorDepth = 16;
|
||||
|
||||
break;
|
||||
case ColorFormat.A8R8G8B8:
|
||||
ColorDepth = 24;
|
||||
|
||||
break;
|
||||
case ColorFormat.A16B16G16R16F:
|
||||
ColorDepth = 32;
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Color format is invalid.", nameof(colorFormat));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of <see cref="CustomResolution" />.
|
||||
/// </summary>
|
||||
/// <param name="width">The screen width.</param>
|
||||
/// <param name="height">The screen height.</param>
|
||||
/// <param name="colorDepth">The color depth.</param>
|
||||
/// <param name="timing">The resolution timing.</param>
|
||||
/// <param name="xRatio">The horizontal scaling ratio.</param>
|
||||
/// <param name="yRatio">The vertical scaling ratio.</param>
|
||||
public CustomResolution(
|
||||
uint width,
|
||||
uint height,
|
||||
uint colorDepth,
|
||||
Timing timing,
|
||||
float xRatio = 1,
|
||||
float yRatio = 1)
|
||||
{
|
||||
if (xRatio <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(xRatio));
|
||||
}
|
||||
|
||||
if (yRatio <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(yRatio));
|
||||
}
|
||||
|
||||
if (colorDepth != 0 && colorDepth != 8 && colorDepth != 16 && colorDepth != 24 && colorDepth != 32)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(colorDepth));
|
||||
}
|
||||
|
||||
Width = width;
|
||||
Height = height;
|
||||
ColorDepth = colorDepth;
|
||||
ColorFormat = ColorFormat.Unknown;
|
||||
XRatio = xRatio;
|
||||
YRatio = yRatio;
|
||||
Timing = timing;
|
||||
}
|
||||
|
||||
internal CustomResolution(CustomDisplay customDisplay)
|
||||
{
|
||||
Width = customDisplay.Width;
|
||||
Height = customDisplay.Height;
|
||||
ColorDepth = customDisplay.Depth;
|
||||
ColorFormat = customDisplay.ColorFormat;
|
||||
Timing = customDisplay.Timing;
|
||||
XRatio = customDisplay.XRatio;
|
||||
YRatio = customDisplay.YRatio;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source surface color depth. "0" means all 8/16/32bpp.
|
||||
/// </summary>
|
||||
public uint ColorDepth { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color format (optional)
|
||||
/// </summary>
|
||||
public ColorFormat ColorFormat { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source surface (source mode) height.
|
||||
/// </summary>
|
||||
public uint Height { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the timing used to program TMDS/DAC/LVDS/HDMI/TVEncoder, etc.
|
||||
/// </summary>
|
||||
public Timing Timing { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source surface (source mode) width.
|
||||
/// </summary>
|
||||
public uint Width { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the horizontal scaling ratio.
|
||||
/// </summary>
|
||||
public float XRatio { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vertical scaling ratio.
|
||||
/// </summary>
|
||||
public float YRatio { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(CustomResolution other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Width == other.Width &&
|
||||
Height == other.Height &&
|
||||
ColorDepth == other.ColorDepth &&
|
||||
Timing.Equals(other.Timing) &&
|
||||
ColorFormat == other.ColorFormat &&
|
||||
XRatio.Equals(other.XRatio) &&
|
||||
YRatio.Equals(other.YRatio);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="CustomResolution" /> for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">An first instance of <see cref="CustomResolution" /> to compare.</param>
|
||||
/// <param name="right">An Second instance of <see cref="CustomResolution" /> to compare.</param>
|
||||
/// <returns>True if both instances are equal, otherwise false.</returns>
|
||||
public static bool operator ==(CustomResolution left, CustomResolution right)
|
||||
{
|
||||
return Equals(left, right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="CustomResolution" /> for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">An first instance of <see cref="CustomResolution" /> to compare.</param>
|
||||
/// <param name="right">An Second instance of <see cref="CustomResolution" /> to compare.</param>
|
||||
/// <returns>True if both instances are not equal, otherwise false.</returns>
|
||||
public static bool operator !=(CustomResolution left, CustomResolution right)
|
||||
{
|
||||
return !Equals(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((CustomResolution) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (int) Width;
|
||||
hashCode = (hashCode * 397) ^ (int) Height;
|
||||
hashCode = (hashCode * 397) ^ (int) ColorDepth;
|
||||
hashCode = (hashCode * 397) ^ Timing.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (int) ColorFormat;
|
||||
hashCode = (hashCode * 397) ^ XRatio.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ YRatio.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
internal CustomDisplay AsCustomDisplay(bool hardwareModeSetOnly)
|
||||
{
|
||||
return new CustomDisplay(Width, Height, ColorDepth, ColorFormat, XRatio, YRatio, Timing,
|
||||
hardwareModeSetOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
325
app/NvAPIWrapper/Display/DVCInformation.cs
Normal file
325
app/NvAPIWrapper/Display/DVCInformation.cs
Normal file
@@ -0,0 +1,325 @@
|
||||
using System;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains and provides a way to modify the Digital Vibrance Control information regarding the
|
||||
/// saturation level of the display or the output
|
||||
/// </summary>
|
||||
public class DVCInformation : IDisplayDVCInfo
|
||||
{
|
||||
private readonly DisplayHandle _displayHandle = DisplayHandle.DefaultHandle;
|
||||
private readonly OutputId _outputId = OutputId.Invalid;
|
||||
private bool? _isLegacy;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the class using a DisplayHandle
|
||||
/// </summary>
|
||||
/// <param name="displayHandle">The handle of the display.</param>
|
||||
public DVCInformation(DisplayHandle displayHandle)
|
||||
{
|
||||
_displayHandle = displayHandle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of this class using a OutputId
|
||||
/// </summary>
|
||||
/// <param name="outputId">The output identification of a display or an output</param>
|
||||
public DVCInformation(OutputId outputId)
|
||||
{
|
||||
_outputId = outputId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the normalized saturation level in the [-1,1] inclusive range.
|
||||
/// a -1 value corresponds to the minimum saturation level and maximum under-saturation and the
|
||||
/// a 1 value corresponds to the maximum saturation level and maximum over-saturation.
|
||||
/// The value of 0 indicates the default saturation level.
|
||||
/// </summary>
|
||||
public double NormalizedLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
var info = GetInfo();
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
return double.NaN;
|
||||
}
|
||||
|
||||
var deviance = info.CurrentLevel - info.DefaultLevel;
|
||||
var range = deviance >= 0
|
||||
? info.MaximumLevel - info.DefaultLevel
|
||||
: info.DefaultLevel - info.MinimumLevel;
|
||||
|
||||
if (deviance == 0 || range == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.Max(Math.Min((double) deviance / range, 1), -1);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (double.IsNaN(value) || double.IsInfinity(value))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(value));
|
||||
}
|
||||
|
||||
var info = GetInfo();
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var range = value >= 0 ? info.MaximumLevel - info.DefaultLevel : info.DefaultLevel - info.MinimumLevel;
|
||||
var level = Math.Max(Math.Min((int) (value * range) + info.DefaultLevel, info.MaximumLevel), info.MinimumLevel);
|
||||
|
||||
if (level == info.CurrentLevel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetLevel(level);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the current saturation level
|
||||
/// </summary>
|
||||
public int CurrentLevel
|
||||
{
|
||||
get => GetInfo()?.CurrentLevel ?? 0;
|
||||
set
|
||||
{
|
||||
var info = GetInfo();
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
value = Math.Max(Math.Min(value, info.MaximumLevel), info.MinimumLevel);
|
||||
|
||||
if (info.CurrentLevel == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetLevel(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int DefaultLevel
|
||||
{
|
||||
get => GetInfo()?.DefaultLevel ?? 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int MaximumLevel
|
||||
{
|
||||
get => GetInfo()?.MaximumLevel ?? 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int MinimumLevel
|
||||
{
|
||||
get => GetInfo()?.MinimumLevel ?? 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return
|
||||
$"{CurrentLevel:D} @ [{MinimumLevel:D} <= {DefaultLevel:D} <= {MaximumLevel:D}] = {NormalizedLevel:F2}";
|
||||
}
|
||||
|
||||
private IDisplayDVCInfo GetInfo()
|
||||
{
|
||||
if (_isLegacy == true)
|
||||
{
|
||||
return GetLegacyInfo();
|
||||
}
|
||||
|
||||
if (_isLegacy == false)
|
||||
{
|
||||
return GetModernInfo();
|
||||
}
|
||||
|
||||
var info = GetModernInfo() ?? GetLegacyInfo();
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
// exception occured on both, force a mode
|
||||
_isLegacy = false;
|
||||
|
||||
return GetInfo();
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
private IDisplayDVCInfo GetLegacyInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
var info = _outputId == OutputId.Invalid
|
||||
? DisplayApi.GetDVCInfo(_displayHandle)
|
||||
: DisplayApi.GetDVCInfo(_outputId);
|
||||
|
||||
if (info.MaximumLevel == 0 && info.MinimumLevel == 0 && info.CurrentLevel == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!_isLegacy.HasValue)
|
||||
{
|
||||
_isLegacy = true;
|
||||
}
|
||||
|
||||
|
||||
return info;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (_isLegacy == true)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
// ignore
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private IDisplayDVCInfo GetModernInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
var info = _outputId == OutputId.Invalid
|
||||
? DisplayApi.GetDVCInfoEx(_displayHandle)
|
||||
: DisplayApi.GetDVCInfoEx(_outputId);
|
||||
|
||||
if (info.MaximumLevel == 0 && info.MinimumLevel == 0 && info.CurrentLevel == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!_isLegacy.HasValue)
|
||||
{
|
||||
_isLegacy = false;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (_isLegacy == false)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
// ignore
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool SetLegacyLevel(int level)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_outputId == OutputId.Invalid)
|
||||
{
|
||||
DisplayApi.SetDVCLevel(_displayHandle, level);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayApi.SetDVCLevel(_outputId, level);
|
||||
}
|
||||
|
||||
if (!_isLegacy.HasValue)
|
||||
{
|
||||
_isLegacy = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (_isLegacy == true)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
// ignore
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void SetLevel(int level)
|
||||
{
|
||||
if (_isLegacy == true)
|
||||
{
|
||||
SetLegacyLevel(level);
|
||||
}
|
||||
else if (_isLegacy == false)
|
||||
{
|
||||
SetModernLevel(level);
|
||||
}
|
||||
else
|
||||
{
|
||||
var success = SetModernLevel(level) || SetLegacyLevel(level);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
// exception occured on both, force a mode
|
||||
_isLegacy = false;
|
||||
|
||||
SetLevel(level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool SetModernLevel(int level)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_outputId == OutputId.Invalid)
|
||||
{
|
||||
DisplayApi.SetDVCLevelEx(_displayHandle, level);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayApi.SetDVCLevelEx(_outputId, level);
|
||||
}
|
||||
|
||||
if (!_isLegacy.HasValue)
|
||||
{
|
||||
_isLegacy = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (_isLegacy == false)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
// ignore
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
232
app/NvAPIWrapper/Display/Display.cs
Normal file
232
app/NvAPIWrapper/Display/Display.cs
Normal file
@@ -0,0 +1,232 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.GPU;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an attached display
|
||||
/// </summary>
|
||||
public class Display : IEquatable<Display>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new Display
|
||||
/// </summary>
|
||||
/// <param name="handle">Handle of the display device</param>
|
||||
public Display(DisplayHandle handle)
|
||||
{
|
||||
Handle = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Display
|
||||
/// </summary>
|
||||
/// <param name="displayName">Name of the display device</param>
|
||||
public Display(string displayName)
|
||||
{
|
||||
Handle = DisplayApi.GetAssociatedNvidiaDisplayHandle(displayName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding Digital Vibrance Control information
|
||||
/// </summary>
|
||||
public DVCInformation DigitalVibranceControl
|
||||
{
|
||||
get => new DVCInformation(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets corresponding DisplayDevice based on display name
|
||||
/// </summary>
|
||||
public DisplayDevice DisplayDevice
|
||||
{
|
||||
get => new DisplayDevice(Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets display driver build title
|
||||
/// </summary>
|
||||
public string DriverBuildTitle
|
||||
{
|
||||
get => DisplayApi.GetDisplayDriverBuildTitle(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets display handle
|
||||
/// </summary>
|
||||
public DisplayHandle Handle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display HDMI support information
|
||||
/// </summary>
|
||||
public IHDMISupportInfo HDMISupportInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
var outputId = OutputId.Invalid;
|
||||
try
|
||||
{
|
||||
outputId = DisplayApi.GetAssociatedDisplayOutputId(Handle);
|
||||
}
|
||||
catch (NVIDIAApiException)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
return DisplayApi.GetHDMISupportInfo(Handle, outputId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the corresponding HUE information
|
||||
/// </summary>
|
||||
public HUEInformation HUEControl
|
||||
{
|
||||
get => new HUEInformation(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the driving logical GPU
|
||||
/// </summary>
|
||||
public LogicalGPU LogicalGPU
|
||||
{
|
||||
get => new LogicalGPU(GPUApi.GetLogicalGPUFromDisplay(Handle));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets display name
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get => DisplayApi.GetAssociatedNvidiaDisplayName(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the connected GPU output
|
||||
/// </summary>
|
||||
public GPUOutput Output
|
||||
{
|
||||
get => new GPUOutput(DisplayApi.GetAssociatedDisplayOutputId(Handle), PhysicalGPUs.FirstOrDefault());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of all physical GPUs responsible for this display, with the first GPU returned as the one with the
|
||||
/// attached active output.
|
||||
/// </summary>
|
||||
public PhysicalGPU[] PhysicalGPUs
|
||||
{
|
||||
get => GPUApi.GetPhysicalGPUsFromDisplay(Handle).Select(handle => new PhysicalGPU(handle)).ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(Display other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Handle.Equals(other.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function returns all NVIDIA displays
|
||||
/// Note: Display handles can get invalidated on a modeset.
|
||||
/// </summary>
|
||||
/// <returns>An array of Display objects</returns>
|
||||
public static Display[] GetDisplays()
|
||||
{
|
||||
return DisplayApi.EnumNvidiaDisplayHandle().Select(handle => new Display(handle)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(Display left, Display right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(Display left, Display right)
|
||||
{
|
||||
return !(right == left);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((Display) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Handle.GetHashCode();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all the supported NVIDIA display views (nView and Dualview modes) for this display.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TargetViewMode[] GetSupportedViews()
|
||||
{
|
||||
return DisplayApi.GetSupportedViews(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the refresh rate on this display.
|
||||
/// The new refresh rate can be applied right away or deferred to be applied with the next OS
|
||||
/// mode-set.
|
||||
/// The override is good for only one mode-set (regardless whether it's deferred or immediate).
|
||||
/// </summary>
|
||||
/// <param name="refreshRate">The refresh rate to be applied.</param>
|
||||
/// <param name="isDeferred">
|
||||
/// A boolean value indicating if the refresh rate override should be deferred to the next OS
|
||||
/// mode-set.
|
||||
/// </param>
|
||||
public void OverrideRefreshRate(float refreshRate, bool isDeferred = false)
|
||||
{
|
||||
DisplayApi.SetRefreshRateOverride(Handle, refreshRate, isDeferred);
|
||||
}
|
||||
}
|
||||
}
|
||||
893
app/NvAPIWrapper/Display/DisplayDevice.cs
Normal file
893
app/NvAPIWrapper/Display/DisplayDevice.cs
Normal file
@@ -0,0 +1,893 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.GPU;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.General;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.GPU.Structures;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
using NvAPIWrapper.Native.Interfaces.GPU;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an NVIDIA display device
|
||||
/// </summary>
|
||||
public class DisplayDevice : IEquatable<DisplayDevice>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new DisplayDevice
|
||||
/// </summary>
|
||||
/// <param name="displayId">Display identification of the device</param>
|
||||
public DisplayDevice(uint displayId)
|
||||
{
|
||||
DisplayId = displayId;
|
||||
var extraInformation = PhysicalGPU.GetDisplayDevices().FirstOrDefault(ids => ids.DisplayId == DisplayId);
|
||||
|
||||
if (extraInformation != null)
|
||||
{
|
||||
IsAvailable = true;
|
||||
ScanOutInformation = new ScanOutInformation(this);
|
||||
ConnectionType = extraInformation.ConnectionType;
|
||||
IsDynamic = extraInformation.IsDynamic;
|
||||
IsMultiStreamRootNode = extraInformation.IsMultiStreamRootNode;
|
||||
IsActive = extraInformation.IsActive;
|
||||
IsCluster = extraInformation.IsCluster;
|
||||
IsOSVisible = extraInformation.IsOSVisible;
|
||||
IsWFD = extraInformation.IsWFD;
|
||||
IsConnected = extraInformation.IsConnected;
|
||||
IsPhysicallyConnected = extraInformation.IsPhysicallyConnected;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new DisplayDevice
|
||||
/// </summary>
|
||||
/// <param name="displayIds">Display identification and attributes of the display device</param>
|
||||
public DisplayDevice(IDisplayIds displayIds)
|
||||
{
|
||||
IsAvailable = true;
|
||||
DisplayId = displayIds.DisplayId;
|
||||
ScanOutInformation = new ScanOutInformation(this);
|
||||
ConnectionType = displayIds.ConnectionType;
|
||||
IsDynamic = displayIds.IsDynamic;
|
||||
IsMultiStreamRootNode = displayIds.IsMultiStreamRootNode;
|
||||
IsActive = displayIds.IsActive;
|
||||
IsCluster = displayIds.IsCluster;
|
||||
IsOSVisible = displayIds.IsOSVisible;
|
||||
IsWFD = displayIds.IsWFD;
|
||||
IsConnected = displayIds.IsConnected;
|
||||
IsPhysicallyConnected = displayIds.IsPhysicallyConnected;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new DisplayDevice
|
||||
/// </summary>
|
||||
/// <param name="displayName">Display name of the display device</param>
|
||||
public DisplayDevice(string displayName) : this(DisplayApi.GetDisplayIdByDisplayName(displayName))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display device connection type
|
||||
/// </summary>
|
||||
public MonitorConnectionType ConnectionType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current display color data
|
||||
/// </summary>
|
||||
public ColorData CurrentColorData
|
||||
{
|
||||
get
|
||||
{
|
||||
var instances = new IColorData[]
|
||||
{
|
||||
new ColorDataV5(ColorDataCommand.Get),
|
||||
new ColorDataV4(ColorDataCommand.Get),
|
||||
new ColorDataV3(ColorDataCommand.Get),
|
||||
new ColorDataV2(ColorDataCommand.Get),
|
||||
new ColorDataV1(ColorDataCommand.Get)
|
||||
};
|
||||
|
||||
var instance = DisplayApi.ColorControl(DisplayId, instances);
|
||||
|
||||
return new ColorData(instance);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current display device timing
|
||||
/// </summary>
|
||||
public Timing CurrentTiming
|
||||
{
|
||||
get => DisplayApi.GetTiming(DisplayId, new TimingInput(TimingOverride.Current));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default display color data
|
||||
/// </summary>
|
||||
public ColorData DefaultColorData
|
||||
{
|
||||
get
|
||||
{
|
||||
var instances = new IColorData[]
|
||||
{
|
||||
new ColorDataV5(ColorDataCommand.GetDefault),
|
||||
new ColorDataV4(ColorDataCommand.GetDefault),
|
||||
new ColorDataV3(ColorDataCommand.GetDefault),
|
||||
new ColorDataV2(ColorDataCommand.GetDefault),
|
||||
new ColorDataV1(ColorDataCommand.GetDefault)
|
||||
};
|
||||
|
||||
var instance = DisplayApi.ColorControl(DisplayId, instances);
|
||||
|
||||
return new ColorData(instance);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the NVIDIA display identification
|
||||
/// </summary>
|
||||
public uint DisplayId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the monitor Display port capabilities
|
||||
/// </summary>
|
||||
public MonitorColorData[] DisplayPortColorCapabilities
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ConnectionType != MonitorConnectionType.DisplayPort)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return DisplayApi.GetMonitorColorCapabilities(DisplayId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display driver EDID specified HDR capabilities
|
||||
/// </summary>
|
||||
public HDRCapabilitiesV1 DriverHDRCapabilities
|
||||
{
|
||||
get => DisplayApi.GetHDRCapabilities(DisplayId, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display currently effective HDR capabilities
|
||||
/// </summary>
|
||||
public HDRCapabilitiesV1 EffectiveHDRCapabilities
|
||||
{
|
||||
get => DisplayApi.GetHDRCapabilities(DisplayId, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI audio info-frame current information
|
||||
/// </summary>
|
||||
public InfoFrameAudio? HDMIAudioFrameCurrentInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.Get, InfoFrameDataType.AudioInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.AudioInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI audio info-frame default information
|
||||
/// </summary>
|
||||
public InfoFrameAudio? HDMIAudioFrameDefaultInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.GetDefault, InfoFrameDataType.AudioInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.AudioInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI audio info-frame override information
|
||||
/// </summary>
|
||||
public InfoFrameAudio? HDMIAudioFrameOverrideInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.GetOverride, InfoFrameDataType.AudioInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.AudioInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI audio info-frame property information
|
||||
/// </summary>
|
||||
public InfoFrameProperty? HDMIAudioFramePropertyInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.GetProperty, InfoFrameDataType.AudioInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.PropertyInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the device HDMI support information
|
||||
/// </summary>
|
||||
public IHDMISupportInfo HDMISupportInfo
|
||||
{
|
||||
get => DisplayApi.GetHDMISupportInfo(DisplayId);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI auxiliary video info-frame current information
|
||||
/// </summary>
|
||||
public InfoFrameVideo? HDMIVideoFrameCurrentInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame =
|
||||
new InfoFrameData(InfoFrameCommand.Get, InfoFrameDataType.AuxiliaryVideoInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.AuxiliaryVideoInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI auxiliary video info-frame default information
|
||||
/// </summary>
|
||||
public InfoFrameVideo? HDMIVideoFrameDefaultInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.GetDefault,
|
||||
InfoFrameDataType.AuxiliaryVideoInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.AuxiliaryVideoInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI auxiliary video info-frame override information
|
||||
/// </summary>
|
||||
public InfoFrameVideo? HDMIVideoFrameOverrideInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.GetOverride,
|
||||
InfoFrameDataType.AuxiliaryVideoInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.AuxiliaryVideoInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDMI auxiliary video info-frame property information
|
||||
/// </summary>
|
||||
public InfoFrameProperty? HDMIVideoFramePropertyInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var infoFrame = new InfoFrameData(InfoFrameCommand.GetProperty,
|
||||
InfoFrameDataType.AuxiliaryVideoInformation);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
|
||||
return infoFrame.PropertyInformation;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HDR color data, or null if the HDR is disabled or unavailable
|
||||
/// </summary>
|
||||
public HDRColorData HDRColorData
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var instances = new IHDRColorData[]
|
||||
{
|
||||
new HDRColorDataV2(ColorDataHDRCommand.Get),
|
||||
new HDRColorDataV1(ColorDataHDRCommand.Get)
|
||||
};
|
||||
|
||||
var instance = DisplayApi.HDRColorControl(DisplayId, instances);
|
||||
|
||||
if (instance.HDRMode == ColorDataHDRMode.Off)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new HDRColorData(instance);
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is being actively driven
|
||||
/// </summary>
|
||||
public bool IsActive { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display device is currently available
|
||||
/// </summary>
|
||||
public bool IsAvailable { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is the representative display
|
||||
/// </summary>
|
||||
public bool IsCluster { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is connected
|
||||
/// </summary>
|
||||
public bool IsConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is part of MST topology and it's a dynamic
|
||||
/// </summary>
|
||||
public bool IsDynamic { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display identification belongs to a multi stream enabled connector (root node). Note that when
|
||||
/// multi stream is enabled and a single multi stream capable monitor is connected to it, the monitor will share the
|
||||
/// display id with the RootNode.
|
||||
/// When there is more than one monitor connected in a multi stream topology, then the root node will have a separate
|
||||
/// displayId.
|
||||
/// </summary>
|
||||
public bool IsMultiStreamRootNode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is reported to the OS
|
||||
/// </summary>
|
||||
public bool IsOSVisible { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is a physically connected display; Valid only when IsConnected is true
|
||||
/// </summary>
|
||||
public bool IsPhysicallyConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the display is wireless
|
||||
/// </summary>
|
||||
public bool IsWFD { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the connected GPU output
|
||||
/// </summary>
|
||||
public GPUOutput Output
|
||||
{
|
||||
get
|
||||
{
|
||||
PhysicalGPUHandle handle;
|
||||
var outputId = GPUApi.GetGPUAndOutputIdFromDisplayId(DisplayId, out handle);
|
||||
|
||||
return new GPUOutput(outputId, new PhysicalGPU(handle));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the connected physical GPU
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var gpuHandle = GPUApi.GetPhysicalGPUFromDisplayId(DisplayId);
|
||||
|
||||
return new PhysicalGPU(gpuHandle);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return Output.PhysicalGPU;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets information regarding the scan-out settings of this display device
|
||||
/// </summary>
|
||||
public ScanOutInformation ScanOutInformation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets monitor capabilities from the Video Capability Data Block if available, otherwise null
|
||||
/// </summary>
|
||||
public MonitorVCDBCapabilities? VCDBMonitorCapabilities
|
||||
{
|
||||
get => DisplayApi.GetMonitorCapabilities(DisplayId, MonitorCapabilitiesType.VCDB)?.VCDBCapabilities;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets monitor capabilities from the Vendor Specific Data Block if available, otherwise null
|
||||
/// </summary>
|
||||
public MonitorVSDBCapabilities? VSDBMonitorCapabilities
|
||||
{
|
||||
get => DisplayApi.GetMonitorCapabilities(DisplayId, MonitorCapabilitiesType.VSDB)?.VSDBCapabilities;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(DisplayDevice other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return DisplayId == other.DisplayId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a custom resolution.
|
||||
/// </summary>
|
||||
/// <param name="customResolution">The custom resolution to delete.</param>
|
||||
/// <param name="displayIds">A list of display ids to remove the custom resolution from.</param>
|
||||
public static void DeleteCustomResolution(CustomResolution customResolution, uint[] displayIds)
|
||||
{
|
||||
var customDisplay = customResolution.AsCustomDisplay(false);
|
||||
DisplayApi.DeleteCustomDisplay(displayIds, customDisplay);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an instance of <see cref="DisplayDevice" /> representing the primary GDI display device.
|
||||
/// </summary>
|
||||
/// <returns>An instance of <see cref="DisplayDevice" />.</returns>
|
||||
public static DisplayDevice GetGDIPrimaryDisplayDevice()
|
||||
{
|
||||
var displayId = DisplayApi.GetGDIPrimaryDisplayId();
|
||||
|
||||
if (displayId == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new DisplayDevice(displayId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(DisplayDevice left, DisplayDevice right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(DisplayDevice left, DisplayDevice right)
|
||||
{
|
||||
return !(right == left);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverts the custom resolution currently on trial.
|
||||
/// </summary>
|
||||
/// <param name="displayIds">A list of display ids to revert the custom resolution from.</param>
|
||||
public static void RevertCustomResolution(uint[] displayIds)
|
||||
{
|
||||
DisplayApi.RevertCustomDisplayTrial(displayIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the custom resolution currently on trial.
|
||||
/// </summary>
|
||||
/// <param name="displayIds">A list of display ids to save the custom resolution for.</param>
|
||||
/// <param name="isThisOutputIdOnly">
|
||||
/// If set, the saved custom display will only be applied on the monitor with the same
|
||||
/// outputId.
|
||||
/// </param>
|
||||
/// <param name="isThisMonitorOnly">
|
||||
/// If set, the saved custom display will only be applied on the monitor with the same EDID
|
||||
/// ID or the same TV connector in case of analog TV.
|
||||
/// </param>
|
||||
public static void SaveCustomResolution(uint[] displayIds, bool isThisOutputIdOnly, bool isThisMonitorOnly)
|
||||
{
|
||||
DisplayApi.SaveCustomDisplay(displayIds, isThisOutputIdOnly, isThisMonitorOnly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a custom resolution into trial
|
||||
/// </summary>
|
||||
/// <param name="customResolution">The custom resolution to apply.</param>
|
||||
/// <param name="displayIds">A list of display ids to apply the custom resolution on.</param>
|
||||
/// <param name="hardwareModeSetOnly">
|
||||
/// A boolean value indicating that a hardware mode-set without OS update should be
|
||||
/// performed.
|
||||
/// </param>
|
||||
public static void TrialCustomResolution(
|
||||
CustomResolution customResolution,
|
||||
uint[] displayIds,
|
||||
bool hardwareModeSetOnly = true)
|
||||
{
|
||||
var customDisplay = customResolution.AsCustomDisplay(hardwareModeSetOnly);
|
||||
DisplayApi.TryCustomDisplay(displayIds.ToDictionary(u => u, u => customDisplay));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((DisplayDevice) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (int) DisplayId;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Display #{DisplayId}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates a valid timing based on the argument passed
|
||||
/// </summary>
|
||||
/// <param name="width">The preferred width.</param>
|
||||
/// <param name="height">The preferred height.</param>
|
||||
/// <param name="refreshRate">The preferred refresh rate.</param>
|
||||
/// <param name="isInterlaced">The boolean value indicating if the preferred resolution is an interlaced resolution.</param>
|
||||
/// <returns>Returns a valid instance of <see cref="Timing" />.</returns>
|
||||
public Timing CalculateTiming(uint width, uint height, float refreshRate, bool isInterlaced)
|
||||
{
|
||||
return DisplayApi.GetTiming(
|
||||
DisplayId,
|
||||
new TimingInput(width, height, refreshRate, TimingOverride.Auto, isInterlaced)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a custom resolution.
|
||||
/// </summary>
|
||||
/// <param name="customResolution">The custom resolution to delete.</param>
|
||||
public void DeleteCustomResolution(CustomResolution customResolution)
|
||||
{
|
||||
DeleteCustomResolution(customResolution, new[] {DisplayId});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the list of custom resolutions saved for this display device
|
||||
/// </summary>
|
||||
/// <returns>A list of <see cref="CustomResolution" /> instances.</returns>
|
||||
public IEnumerable<CustomResolution> GetCustomResolutions()
|
||||
{
|
||||
return DisplayApi.EnumCustomDisplays(DisplayId).Select(custom => new CustomResolution(custom));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a color data is supported on this display
|
||||
/// </summary>
|
||||
/// <param name="colorData">The color data to be checked.</param>
|
||||
/// <returns>true if the color data passed is supported; otherwise false</returns>
|
||||
public bool IsColorDataSupported(ColorData colorData)
|
||||
{
|
||||
var instances = new IColorData[]
|
||||
{
|
||||
colorData.AsColorDataV5(ColorDataCommand.IsSupportedColor),
|
||||
colorData.AsColorDataV4(ColorDataCommand.IsSupportedColor),
|
||||
colorData.AsColorDataV3(ColorDataCommand.IsSupportedColor),
|
||||
colorData.AsColorDataV2(ColorDataCommand.IsSupportedColor),
|
||||
colorData.AsColorDataV1(ColorDataCommand.IsSupportedColor)
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
DisplayApi.ColorControl(DisplayId, instances);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (NVIDIAApiException e)
|
||||
{
|
||||
if (e.Status == Status.NotSupported)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the HDMI audio info-frame information to default
|
||||
/// </summary>
|
||||
public void ResetHDMIAudioFrameInformation()
|
||||
{
|
||||
var infoFrame = new InfoFrameData(
|
||||
InfoFrameCommand.Reset,
|
||||
InfoFrameDataType.AudioInformation
|
||||
);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the HDMI auxiliary video info-frame information to default
|
||||
/// </summary>
|
||||
public void ResetHDMIVideoFrameInformation()
|
||||
{
|
||||
var infoFrame = new InfoFrameData(
|
||||
InfoFrameCommand.Reset,
|
||||
InfoFrameDataType.AuxiliaryVideoInformation
|
||||
);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverts the custom resolution currently on trial.
|
||||
/// </summary>
|
||||
public void RevertCustomResolution()
|
||||
{
|
||||
RevertCustomResolution(new[] {DisplayId});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the custom resolution currently on trial.
|
||||
/// </summary>
|
||||
/// <param name="isThisOutputIdOnly">
|
||||
/// If set, the saved custom display will only be applied on the monitor with the same
|
||||
/// outputId.
|
||||
/// </param>
|
||||
/// <param name="isThisMonitorOnly">
|
||||
/// If set, the saved custom display will only be applied on the monitor with the same EDID
|
||||
/// ID or the same TV connector in case of analog TV.
|
||||
/// </param>
|
||||
public void SaveCustomResolution(bool isThisOutputIdOnly = true, bool isThisMonitorOnly = true)
|
||||
{
|
||||
SaveCustomResolution(new[] {DisplayId}, isThisOutputIdOnly, isThisMonitorOnly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the display current color data configuration
|
||||
/// </summary>
|
||||
/// <param name="colorData">The color data to be set.</param>
|
||||
public void SetColorData(ColorData colorData)
|
||||
{
|
||||
var instances = new IColorData[]
|
||||
{
|
||||
colorData.AsColorDataV5(ColorDataCommand.Set),
|
||||
colorData.AsColorDataV4(ColorDataCommand.Set),
|
||||
colorData.AsColorDataV3(ColorDataCommand.Set),
|
||||
colorData.AsColorDataV2(ColorDataCommand.Set),
|
||||
colorData.AsColorDataV1(ColorDataCommand.Set)
|
||||
};
|
||||
|
||||
DisplayApi.ColorControl(DisplayId, instances);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the HDMI video info-frame current or override information
|
||||
/// </summary>
|
||||
/// <param name="audio">The new information.</param>
|
||||
/// <param name="isOverride">A boolean value indicating if the changes should persist mode-set and OS restart.</param>
|
||||
public void SetHDMIAudioFrameInformation(InfoFrameAudio audio, bool isOverride = false)
|
||||
{
|
||||
var infoFrame = new InfoFrameData(
|
||||
isOverride ? InfoFrameCommand.SetOverride : InfoFrameCommand.Set,
|
||||
audio
|
||||
);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the HDMI audio info-frame property information
|
||||
/// </summary>
|
||||
/// <param name="property">The new property information.</param>
|
||||
public void SetHDMIAudioFramePropertyInformation(InfoFrameProperty property)
|
||||
{
|
||||
var infoFrame = new InfoFrameData(
|
||||
InfoFrameCommand.SetProperty,
|
||||
InfoFrameDataType.AudioInformation,
|
||||
property
|
||||
);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the HDMI auxiliary video info-frame current or override information
|
||||
/// </summary>
|
||||
/// <param name="video">The new information.</param>
|
||||
/// <param name="isOverride">A boolean value indicating if the changes should persist mode-set and OS restart.</param>
|
||||
public void SetHDMIVideoFrameInformation(InfoFrameVideo video, bool isOverride = false)
|
||||
{
|
||||
var infoFrame = new InfoFrameData(
|
||||
isOverride ? InfoFrameCommand.SetOverride : InfoFrameCommand.Set,
|
||||
video
|
||||
);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the HDMI auxiliary video info-frame property information
|
||||
/// </summary>
|
||||
/// <param name="property">The new property information.</param>
|
||||
public void SetHDMIVideoFramePropertyInformation(InfoFrameProperty property)
|
||||
{
|
||||
var infoFrame = new InfoFrameData(
|
||||
InfoFrameCommand.SetProperty,
|
||||
InfoFrameDataType.AuxiliaryVideoInformation,
|
||||
property
|
||||
);
|
||||
DisplayApi.InfoFrameControl(DisplayId, ref infoFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the display HDR color data configuration
|
||||
/// </summary>
|
||||
/// <param name="colorData">The color data to be set.</param>
|
||||
public void SetHDRColorData(HDRColorData colorData)
|
||||
{
|
||||
var instances = new IHDRColorData[]
|
||||
{
|
||||
colorData.AsHDRColorDataV2(ColorDataHDRCommand.Set),
|
||||
colorData.AsHDRColorDataV1(ColorDataHDRCommand.Set)
|
||||
};
|
||||
|
||||
DisplayApi.HDRColorControl(DisplayId, instances);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a custom resolution into trial.
|
||||
/// </summary>
|
||||
/// <param name="customResolution">The custom resolution to apply.</param>
|
||||
/// <param name="hardwareModeSetOnly">
|
||||
/// A boolean value indicating that a hardware mode-set without OS update should be
|
||||
/// performed.
|
||||
/// </param>
|
||||
public void TrialCustomResolution(CustomResolution customResolution, bool hardwareModeSetOnly = true)
|
||||
{
|
||||
TrialCustomResolution(customResolution, new[] {DisplayId}, hardwareModeSetOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
183
app/NvAPIWrapper/Display/FloatTexture.cs
Normal file
183
app/NvAPIWrapper/Display/FloatTexture.cs
Normal file
@@ -0,0 +1,183 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a texture of float values
|
||||
/// </summary>
|
||||
public class FloatTexture : IEquatable<FloatTexture>
|
||||
{
|
||||
/// <summary>
|
||||
/// Underlying float array containing the values of all channels in all pixels
|
||||
/// </summary>
|
||||
protected readonly float[] UnderlyingArray;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="FloatTexture" />.
|
||||
/// </summary>
|
||||
/// <param name="width">The texture width.</param>
|
||||
/// <param name="height">The texture height.</param>
|
||||
/// <param name="channels">The number of texture channels.</param>
|
||||
public FloatTexture(int width, int height, int channels) : this(width, height, channels, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="FloatTexture" />.
|
||||
/// </summary>
|
||||
/// <param name="width">The texture width.</param>
|
||||
/// <param name="height">The texture height.</param>
|
||||
/// <param name="channels">The number of texture channels.</param>
|
||||
/// <param name="array">The underlying array containing all float values.</param>
|
||||
// ReSharper disable once TooManyDependencies
|
||||
protected FloatTexture(int width, int height, int channels, float[] array)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
Channels = channels;
|
||||
UnderlyingArray = array ?? new float[width * height * channels];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of texture channels
|
||||
/// </summary>
|
||||
public int Channels { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the texture height in pixel
|
||||
/// </summary>
|
||||
public int Height { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the texture width in pixels
|
||||
/// </summary>
|
||||
public int Width { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(FloatTexture other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (other.UnderlyingArray.Length != UnderlyingArray.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (other.Width != Width || other.Height != Height || other.Channels != Channels)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !UnderlyingArray.Where((t, i) => Math.Abs(other.UnderlyingArray[i] - t) > 0.0001).Any();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new instance of FloatTexture from the passed array of float values.
|
||||
/// </summary>
|
||||
/// <param name="width">The texture width.</param>
|
||||
/// <param name="height">The texture height.</param>
|
||||
/// <param name="channels">The texture channels.</param>
|
||||
/// <param name="floats">The array of float values.</param>
|
||||
/// <returns>A new instance of <see cref="FloatTexture" />.</returns>
|
||||
// ReSharper disable once TooManyArguments
|
||||
public static FloatTexture FromFloatArray(int width, int height, int channels, float[] floats)
|
||||
{
|
||||
if (floats.Length != width * height * channels)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(floats));
|
||||
}
|
||||
|
||||
return new FloatTexture(width, height, channels, floats.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="FloatTexture" /> for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns><see langword="true" /> if both instances are equal, otherwise <see langword="false" /></returns>
|
||||
public static bool operator ==(FloatTexture left, FloatTexture right)
|
||||
{
|
||||
return Equals(left, right) || left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="FloatTexture" /> for in-equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns><see langword="true" /> if both instances are not equal, otherwise <see langword="false" /></returns>
|
||||
public static bool operator !=(FloatTexture left, FloatTexture right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Equals(obj as FloatTexture);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return UnderlyingArray.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values of each channel at a specific location
|
||||
/// </summary>
|
||||
/// <param name="x">The horizontal location.</param>
|
||||
/// <param name="y">The vertical location.</param>
|
||||
/// <returns>An array of float values each representing a channel value.</returns>
|
||||
public float[] GetValues(int x, int y)
|
||||
{
|
||||
return UnderlyingArray.Skip(y * Width + x).Take(Channels).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of each channel at a specific location
|
||||
/// </summary>
|
||||
/// <param name="x">The horizontal location.</param>
|
||||
/// <param name="y">The vertical location.</param>
|
||||
/// <param name="floats">An array of float values each representing a channel value.</param>
|
||||
public void SetValues(int x, int y, params float[] floats)
|
||||
{
|
||||
var index = y * Width + x;
|
||||
|
||||
for (var i = 0; i < Math.Min(Channels, floats.Length); i++)
|
||||
{
|
||||
UnderlyingArray[index + i] = floats[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this instance of <see cref="FloatTexture" /> as an array of float values.
|
||||
/// </summary>
|
||||
/// <returns>An array of float values representing this instance of <see cref="FloatTexture" />.</returns>
|
||||
public float[] ToFloatArray()
|
||||
{
|
||||
// Returns a copy of the underlying array
|
||||
return UnderlyingArray.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
157
app/NvAPIWrapper/Display/HDRColorData.cs
Normal file
157
app/NvAPIWrapper/Display/HDRColorData.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <inheritdoc cref="IHDRColorData" />
|
||||
public class HDRColorData : IHDRColorData, IEquatable<HDRColorData>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an instance of <see cref="HDRColorData" />.
|
||||
/// </summary>
|
||||
/// <param name="hdrMode">The hdr mode.</param>
|
||||
/// <param name="masteringDisplayData">The display color space configurations.</param>
|
||||
/// <param name="colorFormat">The color data color format.</param>
|
||||
/// <param name="dynamicRange">The color data dynamic range.</param>
|
||||
/// <param name="colorDepth">The color data color depth.</param>
|
||||
public HDRColorData(
|
||||
ColorDataHDRMode hdrMode,
|
||||
MasteringDisplayColorData masteringDisplayData,
|
||||
ColorDataFormat? colorFormat = null,
|
||||
ColorDataDynamicRange? dynamicRange = null,
|
||||
ColorDataDepth? colorDepth = null
|
||||
)
|
||||
{
|
||||
HDRMode = hdrMode;
|
||||
MasteringDisplayData = masteringDisplayData;
|
||||
ColorFormat = colorFormat;
|
||||
DynamicRange = dynamicRange;
|
||||
ColorDepth = colorDepth;
|
||||
}
|
||||
|
||||
internal HDRColorData(IHDRColorData colorData)
|
||||
{
|
||||
HDRMode = colorData.HDRMode;
|
||||
MasteringDisplayData = colorData.MasteringDisplayData;
|
||||
ColorDepth = colorData.ColorDepth;
|
||||
ColorFormat = colorData.ColorFormat;
|
||||
DynamicRange = colorData.DynamicRange;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(HDRColorData other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return ColorDepth == other.ColorDepth &&
|
||||
ColorFormat == other.ColorFormat &&
|
||||
DynamicRange == other.DynamicRange &&
|
||||
HDRMode == other.HDRMode &&
|
||||
MasteringDisplayData.Equals(other.MasteringDisplayData);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataDepth? ColorDepth { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataFormat? ColorFormat { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataDynamicRange? DynamicRange { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ColorDataHDRMode HDRMode { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public MasteringDisplayColorData MasteringDisplayData { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances of <see cref="HDRColorData" /> for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns>true if two instances are equal; otherwise false.</returns>
|
||||
public static bool operator ==(HDRColorData left, HDRColorData right)
|
||||
{
|
||||
return left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances of <see cref="HDRColorData" /> for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns>true if two instances are not equal; otherwise false.</returns>
|
||||
public static bool operator !=(HDRColorData left, HDRColorData right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((HDRColorData) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = ColorDepth.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ ColorFormat.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ DynamicRange.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (int) HDRMode;
|
||||
hashCode = (hashCode * 397) ^ MasteringDisplayData.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
internal HDRColorDataV1 AsHDRColorDataV1(ColorDataHDRCommand command)
|
||||
{
|
||||
return new HDRColorDataV1(
|
||||
command,
|
||||
HDRMode,
|
||||
MasteringDisplayData
|
||||
);
|
||||
}
|
||||
|
||||
internal HDRColorDataV2 AsHDRColorDataV2(ColorDataHDRCommand command)
|
||||
{
|
||||
return new HDRColorDataV2(
|
||||
command,
|
||||
HDRMode,
|
||||
MasteringDisplayData,
|
||||
ColorFormat ?? ColorDataFormat.Auto,
|
||||
DynamicRange ?? ColorDataDynamicRange.Auto,
|
||||
ColorDepth ?? ColorDataDepth.Default
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
97
app/NvAPIWrapper/Display/HUEInformation.cs
Normal file
97
app/NvAPIWrapper/Display/HUEInformation.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains and provides a way to modify the HUE angle
|
||||
/// </summary>
|
||||
public class HUEInformation
|
||||
{
|
||||
private readonly DisplayHandle _displayHandle = DisplayHandle.DefaultHandle;
|
||||
private readonly OutputId _outputId = OutputId.Invalid;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the class using a DisplayHandle
|
||||
/// </summary>
|
||||
/// <param name="displayHandle">The handle of the display.</param>
|
||||
public HUEInformation(DisplayHandle displayHandle)
|
||||
{
|
||||
_displayHandle = displayHandle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of this class using a OutputId
|
||||
/// </summary>
|
||||
/// <param name="outputId">The output identification of a display or an output</param>
|
||||
public HUEInformation(OutputId outputId)
|
||||
{
|
||||
_outputId = outputId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current HUE offset angle [0-359]
|
||||
/// </summary>
|
||||
public int CurrentAngle
|
||||
{
|
||||
get
|
||||
{
|
||||
PrivateDisplayHUEInfo? hueInfo = null;
|
||||
|
||||
if (_displayHandle != DisplayHandle.DefaultHandle)
|
||||
{
|
||||
hueInfo = DisplayApi.GetHUEInfo(_displayHandle);
|
||||
}
|
||||
else if (_outputId != OutputId.Invalid)
|
||||
{
|
||||
hueInfo = DisplayApi.GetHUEInfo(_outputId);
|
||||
}
|
||||
|
||||
return hueInfo?.CurrentAngle ?? 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
value %= 360;
|
||||
|
||||
if (_displayHandle != DisplayHandle.DefaultHandle)
|
||||
{
|
||||
DisplayApi.SetHUEAngle(_displayHandle, value);
|
||||
}
|
||||
else if (_outputId != OutputId.Invalid)
|
||||
{
|
||||
DisplayApi.SetHUEAngle(_outputId, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default HUE offset angle [0-359]
|
||||
/// </summary>
|
||||
public int DefaultAngle
|
||||
{
|
||||
get
|
||||
{
|
||||
PrivateDisplayHUEInfo? hueInfo = null;
|
||||
|
||||
if (_displayHandle != DisplayHandle.DefaultHandle)
|
||||
{
|
||||
hueInfo = DisplayApi.GetHUEInfo(_displayHandle);
|
||||
}
|
||||
else if (_outputId != OutputId.Invalid)
|
||||
{
|
||||
hueInfo = DisplayApi.GetHUEInfo(_outputId);
|
||||
}
|
||||
|
||||
return hueInfo?.DefaultAngle ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{CurrentAngle:D}º [{DefaultAngle:D}º]";
|
||||
}
|
||||
}
|
||||
}
|
||||
70
app/NvAPIWrapper/Display/IntensityTexture.cs
Normal file
70
app/NvAPIWrapper/Display/IntensityTexture.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a texture of intensity values
|
||||
/// </summary>
|
||||
public class IntensityTexture : FloatTexture
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="IntensityTexture" />.
|
||||
/// </summary>
|
||||
/// <param name="width">The texture width.</param>
|
||||
/// <param name="height">The texture height.</param>
|
||||
public IntensityTexture(int width, int height) : base(width, height, 3)
|
||||
{
|
||||
}
|
||||
|
||||
private IntensityTexture(int width, int height, float[] floats) : base(width, height, 3, floats)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new instance of FloatTexture from the passed array of float values.
|
||||
/// </summary>
|
||||
/// <param name="width">The texture width.</param>
|
||||
/// <param name="height">The texture height.</param>
|
||||
/// <param name="floats">The array of float values.</param>
|
||||
/// <returns>A new instance of <see cref="FloatTexture" />.</returns>
|
||||
// ReSharper disable once TooManyArguments
|
||||
public static IntensityTexture FromFloatArray(int width, int height, float[] floats)
|
||||
{
|
||||
if (floats.Length != width * height * 3)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(floats));
|
||||
}
|
||||
|
||||
return new IntensityTexture(width, height, floats.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of intensity pixel at a specific location.
|
||||
/// </summary>
|
||||
/// <param name="x">The horizontal location.</param>
|
||||
/// <param name="y">The vertical location.</param>
|
||||
/// <returns>An instance of <see cref="IntensityTexturePixel" />.</returns>
|
||||
public IntensityTexturePixel GetPixel(int x, int y)
|
||||
{
|
||||
return IntensityTexturePixel.FromFloatArray(UnderlyingArray, y * Width + x);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of intensity pixel at a specific location
|
||||
/// </summary>
|
||||
/// <param name="x">The horizontal location.</param>
|
||||
/// <param name="y">The vertical location.</param>
|
||||
/// <param name="pixel">An instance of <see cref="IntensityTexturePixel" />.</param>
|
||||
public void SetPixel(int x, int y, IntensityTexturePixel pixel)
|
||||
{
|
||||
var index = y * Width + x;
|
||||
var floats = pixel.ToFloatArray();
|
||||
|
||||
for (var i = 0; i < Math.Min(Channels, floats.Length); i++)
|
||||
{
|
||||
UnderlyingArray[index + i] = floats[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
app/NvAPIWrapper/Display/IntensityTexturePixel.cs
Normal file
117
app/NvAPIWrapper/Display/IntensityTexturePixel.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a RGB intensity texture pixel
|
||||
/// </summary>
|
||||
public class IntensityTexturePixel : IEquatable<IntensityTexturePixel>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="IntensityTexturePixel" />.
|
||||
/// </summary>
|
||||
/// <param name="redIntensity">The intensity of the red light (0-1)</param>
|
||||
/// <param name="greenIntensity">The intensity of the green light (0-1)</param>
|
||||
/// <param name="blueIntensity">The intensity of the blue light (0-1)</param>
|
||||
public IntensityTexturePixel(float redIntensity, float greenIntensity, float blueIntensity)
|
||||
{
|
||||
RedIntensity = Math.Max(Math.Min(redIntensity, 1), 0);
|
||||
GreenIntensity = Math.Max(Math.Min(greenIntensity, 1), 0);
|
||||
BlueIntensity = Math.Max(Math.Min(blueIntensity, 1), 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the intensity of the blue light (0-1)
|
||||
/// </summary>
|
||||
public float BlueIntensity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the intensity of the green light (0-1)
|
||||
/// </summary>
|
||||
public float GreenIntensity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the intensity of the red light (0-1)
|
||||
/// </summary>
|
||||
public float RedIntensity { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(IntensityTexturePixel other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Math.Abs(RedIntensity - other.RedIntensity) < 0.0001 &&
|
||||
Math.Abs(GreenIntensity - other.GreenIntensity) < 0.0001 &&
|
||||
Math.Abs(BlueIntensity - other.BlueIntensity) < 0.0001;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="IntensityTexturePixel" /> for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns><see langword="true" /> if both instances are equal, otherwise <see langword="false" /></returns>
|
||||
public static bool operator ==(IntensityTexturePixel left, IntensityTexturePixel right)
|
||||
{
|
||||
return Equals(left, right) || left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="IntensityTexturePixel" /> for in-equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns><see langword="true" /> if both instances are not equal, otherwise <see langword="false" /></returns>
|
||||
public static bool operator !=(IntensityTexturePixel left, IntensityTexturePixel right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
internal static IntensityTexturePixel FromFloatArray(float[] floats, int index)
|
||||
{
|
||||
return new IntensityTexturePixel(floats[index], floats[index + 1], floats[index + 2]);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Equals(obj as IntensityTexturePixel);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = RedIntensity.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ GreenIntensity.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ BlueIntensity.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
internal float[] ToFloatArray()
|
||||
{
|
||||
return new[] {RedIntensity, GreenIntensity, BlueIntensity};
|
||||
}
|
||||
}
|
||||
}
|
||||
288
app/NvAPIWrapper/Display/PathInfo.cs
Normal file
288
app/NvAPIWrapper/Display/PathInfo.cs
Normal file
@@ -0,0 +1,288 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.General;
|
||||
using NvAPIWrapper.Native.Helpers;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a configuration path
|
||||
/// </summary>
|
||||
public class PathInfo : IEquatable<PathInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new PathInfo
|
||||
/// </summary>
|
||||
/// <param name="resolution">Display resolution</param>
|
||||
/// <param name="colorFormat">Display color format</param>
|
||||
/// <param name="targetInfos">Target configuration informations</param>
|
||||
public PathInfo(Resolution resolution, ColorFormat colorFormat, PathTargetInfo[] targetInfos)
|
||||
{
|
||||
Resolution = resolution;
|
||||
ColorFormat = colorFormat;
|
||||
TargetsInfo = targetInfos;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new PathInfo
|
||||
/// </summary>
|
||||
/// <param name="info">IPathInfo implamented object</param>
|
||||
public PathInfo(IPathInfo info)
|
||||
{
|
||||
SourceId = info.SourceId;
|
||||
Resolution = info.SourceModeInfo.Resolution;
|
||||
ColorFormat = info.SourceModeInfo.ColorFormat;
|
||||
Position = info.SourceModeInfo.Position;
|
||||
SpanningOrientation = info.SourceModeInfo.SpanningOrientation;
|
||||
IsGDIPrimary = info.SourceModeInfo.IsGDIPrimary;
|
||||
IsSLIFocus = info.SourceModeInfo.IsSLIFocus;
|
||||
TargetsInfo =
|
||||
info.TargetsInfo.Select(targetInfo => new PathTargetInfo(targetInfo)).ToArray();
|
||||
|
||||
if (info is PathInfoV2)
|
||||
{
|
||||
OSAdapterLUID = ((PathInfoV2) info).OSAdapterLUID;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display color format
|
||||
/// </summary>
|
||||
public ColorFormat ColorFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean value indicating if the this is the primary GDI display
|
||||
/// </summary>
|
||||
public bool IsGDIPrimary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean value indicating if the this is the SLI focus display
|
||||
/// </summary>
|
||||
public bool IsSLIFocus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets OS Adapter of LUID for Non-NVIDIA adapters
|
||||
/// </summary>
|
||||
public LUID? OSAdapterLUID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display position
|
||||
/// </summary>
|
||||
public Position Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display resolution
|
||||
/// </summary>
|
||||
public Resolution Resolution { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Windows CCD display source identification. This can be optionally set.
|
||||
/// </summary>
|
||||
public uint SourceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display spanning orientation, valid for XP only
|
||||
/// </summary>
|
||||
public SpanningOrientation SpanningOrientation { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets information about path targets
|
||||
/// </summary>
|
||||
public PathTargetInfo[] TargetsInfo { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality with a PathInfo instance
|
||||
/// </summary>
|
||||
/// <param name="other">The PathInfo object to check with</param>
|
||||
/// <returns>true if both objects are equal, otherwise false</returns>
|
||||
public bool Equals(PathInfo other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Resolution.Equals(other.Resolution) &&
|
||||
ColorFormat == other.ColorFormat &&
|
||||
Position.Equals(other.Position) &&
|
||||
SpanningOrientation == other.SpanningOrientation &&
|
||||
IsGDIPrimary == other.IsGDIPrimary &&
|
||||
IsSLIFocus == other.IsSLIFocus &&
|
||||
TargetsInfo.SequenceEqual(other.TargetsInfo);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a PathInfo object
|
||||
/// </summary>
|
||||
/// <returns>The newly created PathInfo object</returns>
|
||||
public static PathInfo[] GetDisplaysConfig()
|
||||
{
|
||||
var configs = DisplayApi.GetDisplayConfig();
|
||||
var logicalDisplays = configs.Select(info => new PathInfo(info)).ToArray();
|
||||
configs.DisposeAll();
|
||||
|
||||
return logicalDisplays;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(PathInfo left, PathInfo right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(PathInfo left, PathInfo right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies one or more path information configurations
|
||||
/// </summary>
|
||||
/// <param name="pathInfos">An array of path information configuration</param>
|
||||
/// <param name="flags">DisplayConfigFlags flags</param>
|
||||
public static void SetDisplaysConfig(PathInfo[] pathInfos, DisplayConfigFlags flags)
|
||||
{
|
||||
try
|
||||
{
|
||||
var configsV2 = pathInfos.Select(config => config.GetPathInfoV2()).Cast<IPathInfo>().ToArray();
|
||||
DisplayApi.SetDisplayConfig(configsV2, flags);
|
||||
configsV2.DisposeAll();
|
||||
}
|
||||
catch (NVIDIAApiException ex)
|
||||
{
|
||||
if (ex.Status != Status.IncompatibleStructureVersion)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (NVIDIANotSupportedException)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
var configsV1 = pathInfos.Select(config => config.GetPathInfoV1()).Cast<IPathInfo>().ToArray();
|
||||
DisplayApi.SetDisplayConfig(configsV1, flags);
|
||||
configsV1.DisposeAll();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((PathInfo) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = Resolution.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (int) ColorFormat;
|
||||
hashCode = (hashCode * 397) ^ Position.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (int) SpanningOrientation;
|
||||
hashCode = (hashCode * 397) ^ IsGDIPrimary.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ IsSLIFocus.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ (TargetsInfo?.GetHashCode() ?? 0);
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Resolution} @ {Position} [{TargetsInfo.Length}]";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a GetPathInfoV1 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created GetPathInfoV1 object</returns>
|
||||
public PathInfoV1 GetPathInfoV1()
|
||||
{
|
||||
var sourceModeInfo = GetSourceModeInfo();
|
||||
var pathTargetInfoV1 = GetPathTargetInfoV1Array();
|
||||
|
||||
return new PathInfoV1(pathTargetInfoV1, sourceModeInfo, SourceId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a GetPathInfoV2 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created GetPathInfoV2 object</returns>
|
||||
public PathInfoV2 GetPathInfoV2()
|
||||
{
|
||||
var sourceModeInfo = GetSourceModeInfo();
|
||||
var pathTargetInfoV2 = GetPathTargetInfoV2Array();
|
||||
|
||||
return new PathInfoV2(pathTargetInfoV2, sourceModeInfo, SourceId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills an array of GetPathTargetInfoV1 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created array of GetPathTargetInfoV1 objects</returns>
|
||||
public PathTargetInfoV1[] GetPathTargetInfoV1Array()
|
||||
{
|
||||
return TargetsInfo.Select(config => config.GetPathTargetInfoV1()).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills an array of GetPathTargetInfoV2 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created array of GetPathTargetInfoV2 objects</returns>
|
||||
public PathTargetInfoV2[] GetPathTargetInfoV2Array()
|
||||
{
|
||||
return TargetsInfo.Select(config => config.GetPathTargetInfoV2()).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a SourceModeInfo object
|
||||
/// </summary>
|
||||
/// <returns>The newly created SourceModeInfo object</returns>
|
||||
public SourceModeInfo GetSourceModeInfo()
|
||||
{
|
||||
return new SourceModeInfo(Resolution, ColorFormat, Position, SpanningOrientation, IsGDIPrimary, IsSLIFocus);
|
||||
}
|
||||
}
|
||||
}
|
||||
304
app/NvAPIWrapper/Display/PathTargetInfo.cs
Normal file
304
app/NvAPIWrapper/Display/PathTargetInfo.cs
Normal file
@@ -0,0 +1,304 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a display configuration on a path
|
||||
/// </summary>
|
||||
public class PathTargetInfo : IEquatable<PathTargetInfo>
|
||||
{
|
||||
private TimingOverride _timingOverride;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new PathTargetInfo
|
||||
/// </summary>
|
||||
/// <param name="info">IPathTargetInfo implamented object</param>
|
||||
public PathTargetInfo(IPathTargetInfo info)
|
||||
{
|
||||
DisplayDevice = new DisplayDevice(info.DisplayId);
|
||||
|
||||
if (info.Details.HasValue)
|
||||
{
|
||||
Rotation = info.Details.Value.Rotation;
|
||||
Scaling = info.Details.Value.Scaling;
|
||||
TVConnectorType = info.Details.Value.ConnectorType;
|
||||
TVFormat = info.Details.Value.TVFormat;
|
||||
RefreshRateInMillihertz = info.Details.Value.RefreshRateInMillihertz;
|
||||
TimingOverride = info.Details.Value.TimingOverride;
|
||||
IsInterlaced = info.Details.Value.IsInterlaced;
|
||||
IsClonePrimary = info.Details.Value.IsClonePrimary;
|
||||
IsClonePanAndScanTarget = info.Details.Value.IsClonePanAndScanTarget;
|
||||
DisableVirtualModeSupport = info.Details.Value.DisableVirtualModeSupport;
|
||||
IsPreferredUnscaledTarget = info.Details.Value.IsPreferredUnscaledTarget;
|
||||
}
|
||||
|
||||
if (info is PathTargetInfoV2)
|
||||
{
|
||||
WindowsCCDTargetId = ((PathTargetInfoV2) info).WindowsCCDTargetId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new PathTargetInfo
|
||||
/// </summary>
|
||||
/// <param name="device">DisplayDevice object</param>
|
||||
public PathTargetInfo(DisplayDevice device)
|
||||
{
|
||||
DisplayDevice = device;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the virtual mode support
|
||||
/// </summary>
|
||||
public bool DisableVirtualModeSupport { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets corresponding DisplayDevice
|
||||
/// </summary>
|
||||
public DisplayDevice DisplayDevice { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pan and scan is availability. Valid only when the target is part of clone
|
||||
/// topology.
|
||||
/// </summary>
|
||||
public bool IsClonePanAndScanTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the primary display in clone configuration. This is *NOT* GDI Primary.
|
||||
/// Only one target can be primary per source. If no primary is specified, the first target will automatically be
|
||||
/// primary.
|
||||
/// </summary>
|
||||
public bool IsClonePrimary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the interlaced mode flag, ignored if refreshRate == 0
|
||||
/// </summary>
|
||||
public bool IsInterlaced { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the preferred unscaled mode of target
|
||||
/// </summary>
|
||||
public bool IsPreferredUnscaledTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the non-interlaced Refresh Rate of the mode, multiplied by 1000, 0 = ignored
|
||||
/// This is the value which driver reports to the OS.
|
||||
/// </summary>
|
||||
public uint RefreshRateInMillihertz { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the rotation setting
|
||||
/// </summary>
|
||||
public Rotate Rotation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the scaling setting
|
||||
/// </summary>
|
||||
public Scaling Scaling { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the custom timing of display
|
||||
/// Ignored if TimingOverride == TimingOverride.Current
|
||||
/// </summary>
|
||||
public TimingOverride TimingOverride
|
||||
{
|
||||
get => _timingOverride;
|
||||
set
|
||||
{
|
||||
if (value == TimingOverride.Custom)
|
||||
{
|
||||
throw new NVIDIANotSupportedException("Custom timing is not supported yet.");
|
||||
}
|
||||
|
||||
_timingOverride = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the connector type. For TV only, ignored if TVFormat == TVFormat.None.
|
||||
/// </summary>
|
||||
public ConnectorType TVConnectorType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the TV format. For TV only, otherwise set to TVFormat.None
|
||||
/// </summary>
|
||||
public TVFormat TVFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Windows CCD target ID. Must be present only for non-NVIDIA adapter, for NVIDIA adapter this parameter is
|
||||
/// ignored.
|
||||
/// </summary>
|
||||
public uint WindowsCCDTargetId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality with a PathTargetInfo instance
|
||||
/// </summary>
|
||||
/// <param name="other">The PathTargetInfo object to check with</param>
|
||||
/// <returns>true if both objects are equal, otherwise false</returns>
|
||||
public bool Equals(PathTargetInfo other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return _timingOverride == other._timingOverride &&
|
||||
Rotation == other.Rotation &&
|
||||
Scaling == other.Scaling &&
|
||||
RefreshRateInMillihertz == other.RefreshRateInMillihertz &&
|
||||
(TVFormat == TVFormat.None || TVConnectorType == other.TVConnectorType) &&
|
||||
TVFormat == other.TVFormat &&
|
||||
DisplayDevice.Equals(other.DisplayDevice) &&
|
||||
IsInterlaced == other.IsInterlaced &&
|
||||
IsClonePrimary == other.IsClonePrimary &&
|
||||
IsClonePanAndScanTarget == other.IsClonePanAndScanTarget &&
|
||||
DisableVirtualModeSupport == other.DisableVirtualModeSupport &&
|
||||
IsPreferredUnscaledTarget == other.IsPreferredUnscaledTarget;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(PathTargetInfo left, PathTargetInfo right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(PathTargetInfo left, PathTargetInfo right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((PathTargetInfo) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (int) _timingOverride;
|
||||
hashCode = (hashCode * 397) ^ (int) Rotation;
|
||||
hashCode = (hashCode * 397) ^ (int) Scaling;
|
||||
hashCode = (hashCode * 397) ^ (int) RefreshRateInMillihertz;
|
||||
hashCode = (hashCode * 397) ^ (int) TVFormat;
|
||||
hashCode = (hashCode * 397) ^ (TVFormat != TVFormat.None ? (int) TVConnectorType : 0);
|
||||
hashCode = (hashCode * 397) ^ (DisplayDevice?.GetHashCode() ?? 0);
|
||||
hashCode = (hashCode * 397) ^ IsInterlaced.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ IsClonePrimary.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ IsClonePanAndScanTarget.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ DisableVirtualModeSupport.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ IsPreferredUnscaledTarget.GetHashCode();
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
var strs = new List<string>
|
||||
{
|
||||
DisplayDevice.ToString()
|
||||
};
|
||||
|
||||
if (RefreshRateInMillihertz > 0)
|
||||
{
|
||||
strs.Add($"@ {RefreshRateInMillihertz / 1000}hz");
|
||||
}
|
||||
|
||||
if (TVFormat != TVFormat.None)
|
||||
{
|
||||
strs.Add($"- TV {TVFormat}");
|
||||
}
|
||||
|
||||
strs.Add(IsInterlaced ? "Interlaced" : "Progressive");
|
||||
|
||||
if (Rotation != Rotate.Degree0)
|
||||
{
|
||||
strs.Add($"- Rotation: {Rotation}");
|
||||
}
|
||||
|
||||
return string.Join(" ", strs);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a PathAdvancedTargetInfo object
|
||||
/// </summary>
|
||||
/// <returns>The newly created PathAdvancedTargetInfo object</returns>
|
||||
public PathAdvancedTargetInfo GetPathAdvancedTargetInfo()
|
||||
{
|
||||
if (TVFormat == TVFormat.None)
|
||||
{
|
||||
return new PathAdvancedTargetInfo(Rotation, Scaling, RefreshRateInMillihertz, TimingOverride,
|
||||
IsInterlaced, IsClonePrimary, IsClonePanAndScanTarget, DisableVirtualModeSupport,
|
||||
IsPreferredUnscaledTarget);
|
||||
}
|
||||
|
||||
return new PathAdvancedTargetInfo(Rotation, Scaling, TVFormat, TVConnectorType, RefreshRateInMillihertz,
|
||||
TimingOverride, IsInterlaced, IsClonePrimary, IsClonePanAndScanTarget, DisableVirtualModeSupport,
|
||||
IsPreferredUnscaledTarget);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a PathTargetInfoV1 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created PathTargetInfoV1 object</returns>
|
||||
public PathTargetInfoV1 GetPathTargetInfoV1()
|
||||
{
|
||||
var pathAdvancedTargetInfo = GetPathAdvancedTargetInfo();
|
||||
|
||||
return new PathTargetInfoV1(DisplayDevice.DisplayId, pathAdvancedTargetInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and fills a PathTargetInfoV2 object
|
||||
/// </summary>
|
||||
/// <returns>The newly created PathTargetInfoV2 object</returns>
|
||||
public PathTargetInfoV2 GetPathTargetInfoV2()
|
||||
{
|
||||
var pathAdvancedTargetInfo = GetPathAdvancedTargetInfo();
|
||||
|
||||
return new PathTargetInfoV2(DisplayDevice.DisplayId, WindowsCCDTargetId, pathAdvancedTargetInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
218
app/NvAPIWrapper/Display/ScanOutInformation.cs
Normal file
218
app/NvAPIWrapper/Display/ScanOutInformation.cs
Normal file
@@ -0,0 +1,218 @@
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.General.Structures;
|
||||
using Rectangle = NvAPIWrapper.Native.General.Structures.Rectangle;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information regarding the scan-out buffer settings of a display device
|
||||
/// </summary>
|
||||
public class ScanOutInformation
|
||||
{
|
||||
internal ScanOutInformation(DisplayDevice displayDevice)
|
||||
{
|
||||
DisplayDevice = displayDevice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the clone importance assigned to the target if the target is a cloned view of the SourceDesktopRectangle
|
||||
/// (0:primary,1 secondary,...).
|
||||
/// </summary>
|
||||
public uint CloneImportance
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).CloneImportance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display device that this instance describes
|
||||
/// </summary>
|
||||
public DisplayDevice DisplayDevice { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if the display device scan out output is warped
|
||||
/// </summary>
|
||||
public bool IsDisplayWarped
|
||||
{
|
||||
get => DisplayApi.GetScanOutWarpingState(DisplayDevice.DisplayId).IsEnabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value indicating if the display device intensity is modified
|
||||
/// </summary>
|
||||
public bool IsIntensityModified
|
||||
{
|
||||
get => DisplayApi.GetScanOutIntensityState(DisplayDevice.DisplayId).IsEnabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the operating system display device rectangle in desktop coordinates displayId is scanning out from.
|
||||
/// </summary>
|
||||
public Rectangle SourceDesktopRectangle
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).SourceDesktopRectangle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rotation performed between the SourceViewPortRectangle and the TargetViewPortRectangle.
|
||||
/// </summary>
|
||||
public Rotate SourceToTargetRotation
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).SourceToTargetRotation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the area inside the SourceDesktopRectangle which is scanned out to the display.
|
||||
/// </summary>
|
||||
public Rectangle SourceViewPortRectangle
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).SourceViewPortRectangle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vertical size of the active resolution scanned out to the display.
|
||||
/// </summary>
|
||||
public uint TargetDisplayHeight
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).TargetDisplayHeight;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the horizontal size of the active resolution scanned out to the display.
|
||||
/// </summary>
|
||||
public uint TargetDisplayWidth
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).TargetDisplayWidth;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the area inside the rectangle described by targetDisplayWidth/Height SourceViewPortRectangle is scanned out
|
||||
/// to.
|
||||
/// </summary>
|
||||
public Rectangle TargetViewPortRectangle
|
||||
{
|
||||
get => DisplayApi.GetScanOutConfiguration(DisplayDevice.DisplayId).TargetViewPortRectangle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables the intensity modification on the display device scan-out buffer.
|
||||
/// </summary>
|
||||
/// <param name="isSticky">A boolean value that indicates whether the settings will be kept over a reboot.</param>
|
||||
public void DisableIntensityModifications(out bool isSticky)
|
||||
{
|
||||
DisplayApi.SetScanOutIntensity(DisplayDevice.DisplayId, null, out isSticky);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables the warping of display device scan-out buffer.
|
||||
/// </summary>
|
||||
/// <param name="isSticky">A boolean value that indicates whether the settings will be kept over a reboot.</param>
|
||||
public void DisableWarping(out bool isSticky)
|
||||
{
|
||||
var vorticesCount = 0;
|
||||
DisplayApi.SetScanOutWarping(DisplayDevice.DisplayId, null, ref vorticesCount, out isSticky);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the intensity modification on the display device scan-out buffer.
|
||||
/// </summary>
|
||||
/// <param name="intensityTexture">The intensity texture to apply to the scan-out buffer.</param>
|
||||
/// <param name="isSticky">A boolean value that indicates whether the settings will be kept over a reboot.</param>
|
||||
public void EnableIntensityModifications(IntensityTexture intensityTexture, out bool isSticky)
|
||||
{
|
||||
using (
|
||||
var intensity = new ScanOutIntensityV1(
|
||||
(uint) intensityTexture.Width,
|
||||
(uint) intensityTexture.Height,
|
||||
intensityTexture.ToFloatArray()
|
||||
)
|
||||
)
|
||||
{
|
||||
DisplayApi.SetScanOutIntensity(DisplayDevice.DisplayId, intensity, out isSticky);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the intensity modification on the display device scan-out buffer.
|
||||
/// </summary>
|
||||
/// <param name="intensityTexture">The intensity texture to apply to the scan-out buffer.</param>
|
||||
/// <param name="offsetTexture">The offset texture to apply to the scan-out buffer.</param>
|
||||
/// <param name="isSticky">A boolean value that indicates whether the settings will be kept over a reboot.</param>
|
||||
public void EnableIntensityModifications(
|
||||
IntensityTexture intensityTexture,
|
||||
FloatTexture offsetTexture,
|
||||
out bool isSticky)
|
||||
{
|
||||
using (
|
||||
var intensity = new ScanOutIntensityV2(
|
||||
(uint) intensityTexture.Width,
|
||||
(uint) intensityTexture.Height,
|
||||
intensityTexture.ToFloatArray(),
|
||||
(uint) offsetTexture.Channels,
|
||||
offsetTexture.ToFloatArray()
|
||||
)
|
||||
)
|
||||
{
|
||||
DisplayApi.SetScanOutIntensity(DisplayDevice.DisplayId, intensity, out isSticky);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the warping of display device scan-out buffer
|
||||
/// </summary>
|
||||
/// <param name="warpingVerticeFormat">The type of warping vortexes.</param>
|
||||
/// <param name="vortices">An array of warping vortexes.</param>
|
||||
/// <param name="textureRectangle">The rectangle in desktop coordinates describing the source area for the warping.</param>
|
||||
/// <param name="isSticky">A boolean value that indicates whether the settings will be kept over a reboot.</param>
|
||||
// ReSharper disable once TooManyArguments
|
||||
public void EnableWarping(
|
||||
WarpingVerticeFormat warpingVerticeFormat,
|
||||
XYUVRQVortex[] vortices,
|
||||
Rectangle textureRectangle,
|
||||
out bool isSticky)
|
||||
{
|
||||
using (
|
||||
var warping = new ScanOutWarpingV1(
|
||||
warpingVerticeFormat,
|
||||
vortices.SelectMany(vortex => vortex.AsFloatArray()).ToArray(),
|
||||
textureRectangle
|
||||
)
|
||||
)
|
||||
{
|
||||
var vorticesCount = vortices.Length;
|
||||
DisplayApi.SetScanOutWarping(DisplayDevice.DisplayId, warping, ref vorticesCount, out isSticky);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries the current state of one of the various scan-out composition parameters.
|
||||
/// </summary>
|
||||
/// <param name="parameter">The scan-out composition parameter.</param>
|
||||
/// <param name="additionalValue">The additional value included with the parameter value.</param>
|
||||
/// <returns>The scan-out composition parameter value.</returns>
|
||||
public ScanOutCompositionParameterValue GetCompositionParameterValue(
|
||||
ScanOutCompositionParameter parameter,
|
||||
out float additionalValue)
|
||||
{
|
||||
return DisplayApi.GetScanOutCompositionParameter(DisplayDevice.DisplayId, parameter, out additionalValue);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current state of one of the various scan-out composition parameters.
|
||||
/// </summary>
|
||||
/// <param name="parameter">The scan-out composition parameter.</param>
|
||||
/// <param name="parameterValue">The scan-out composition parameter value.</param>
|
||||
/// <param name="additionalValue">The additional value included with the parameter value.</param>
|
||||
public void SetCompositionParameterValue(
|
||||
ScanOutCompositionParameter parameter,
|
||||
ScanOutCompositionParameterValue parameterValue,
|
||||
float additionalValue)
|
||||
{
|
||||
DisplayApi.SetScanOutCompositionParameter(DisplayDevice.DisplayId, parameter, parameterValue,
|
||||
ref additionalValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
150
app/NvAPIWrapper/Display/UnAttachedDisplay.cs
Normal file
150
app/NvAPIWrapper/Display/UnAttachedDisplay.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.GPU;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an unattached display
|
||||
/// </summary>
|
||||
public class UnAttachedDisplay : IEquatable<UnAttachedDisplay>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new UnAttachedDisplay
|
||||
/// </summary>
|
||||
/// <param name="handle">Handle of the unattached display device</param>
|
||||
public UnAttachedDisplay(UnAttachedDisplayHandle handle)
|
||||
{
|
||||
Handle = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new UnAttachedDisplay
|
||||
/// </summary>
|
||||
/// <param name="displayName">Name of the unattached display device</param>
|
||||
public UnAttachedDisplay(string displayName)
|
||||
{
|
||||
Handle = DisplayApi.GetAssociatedUnAttachedNvidiaDisplayHandle(displayName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets display handle
|
||||
/// </summary>
|
||||
public UnAttachedDisplayHandle Handle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets display name
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get => DisplayApi.GetUnAttachedAssociatedDisplayName(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets corresponding physical GPU
|
||||
/// </summary>
|
||||
public PhysicalGPU PhysicalGPU
|
||||
{
|
||||
get => new PhysicalGPU(GPUApi.GetPhysicalGPUFromUnAttachedDisplay(Handle));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality with a UnAttachedDisplay instance
|
||||
/// </summary>
|
||||
/// <param name="other">The Display object to check with</param>
|
||||
/// <returns>true if both objects are equal, otherwise false</returns>
|
||||
public bool Equals(UnAttachedDisplay other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Handle.Equals(other.Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function returns all unattached NVIDIA displays
|
||||
/// Note: Display handles can get invalidated on a modeset.
|
||||
/// </summary>
|
||||
/// <returns>An array of Display objects</returns>
|
||||
public static UnAttachedDisplay[] GetUnAttachedDisplays()
|
||||
{
|
||||
return
|
||||
DisplayApi.EnumNvidiaUnAttachedDisplayHandle().Select(handle => new UnAttachedDisplay(handle))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for equality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are equal, otherwise false</returns>
|
||||
public static bool operator ==(UnAttachedDisplay left, UnAttachedDisplay right)
|
||||
{
|
||||
return right?.Equals(left) ?? ReferenceEquals(left, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks for inequality between two objects of same type
|
||||
/// </summary>
|
||||
/// <param name="left">The first object</param>
|
||||
/// <param name="right">The second object</param>
|
||||
/// <returns>true, if both objects are not equal, otherwise false</returns>
|
||||
public static bool operator !=(UnAttachedDisplay left, UnAttachedDisplay right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((UnAttachedDisplay) obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Handle.GetHashCode();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new active attached display from this unattached display
|
||||
/// At least one GPU must be present in the system and running an NVIDIA display driver.
|
||||
/// </summary>
|
||||
/// <returns>An active attached display</returns>
|
||||
public Display CreateDisplay()
|
||||
{
|
||||
return new Display(DisplayApi.CreateDisplayFromUnAttachedDisplay(Handle));
|
||||
}
|
||||
}
|
||||
}
|
||||
165
app/NvAPIWrapper/Display/XYUVRQVortex.cs
Normal file
165
app/NvAPIWrapper/Display/XYUVRQVortex.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a XYUVRQ scan-out warping vortex
|
||||
/// </summary>
|
||||
public class XYUVRQVortex : IEquatable<XYUVRQVortex>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="XYUVRQVortex" />.
|
||||
/// </summary>
|
||||
/// <param name="x">The target view port mesh horizontal coordinate</param>
|
||||
/// <param name="y">The target view port mesh vertical coordinate</param>
|
||||
/// <param name="u">The desktop view port texture horizontal coordinate</param>
|
||||
/// <param name="v">The desktop view port texture vertical coordinate</param>
|
||||
/// <param name="r">The 3D warp perspective R factor</param>
|
||||
/// <param name="q">The 3D warp perspective Q factor</param>
|
||||
// ReSharper disable once TooManyDependencies
|
||||
public XYUVRQVortex(int x, int y, int u, int v, float r, float q)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
U = u;
|
||||
V = v;
|
||||
R = r;
|
||||
Q = q;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 3D warp perspective Q factor
|
||||
/// </summary>
|
||||
public float Q { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 3D warp perspective R factor
|
||||
/// </summary>
|
||||
public float R { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Desktop view port texture horizontal coordinate
|
||||
/// </summary>
|
||||
public int U { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Desktop view port texture vertical coordinate
|
||||
/// </summary>
|
||||
public int V { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Target view port mesh horizontal coordinate
|
||||
/// </summary>
|
||||
public int X { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Target view port mesh vertical coordinate
|
||||
/// </summary>
|
||||
public int Y { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(XYUVRQVortex other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Math.Abs(Q - other.Q) < 0.0001 &&
|
||||
Math.Abs(R - other.R) < 0.0001 &&
|
||||
U == other.U &&
|
||||
V == other.V &&
|
||||
X == other.X &&
|
||||
Y == other.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses an array of floats and returns the corresponding <see cref="XYUVRQVortex" />s.
|
||||
/// </summary>
|
||||
/// <param name="floats">The array of float representing one or more <see cref="XYUVRQVortex" />s.</param>
|
||||
/// <returns>Instances of <see cref="XYUVRQVortex" />.</returns>
|
||||
public static IEnumerable<XYUVRQVortex> FromFloatArray(float[] floats)
|
||||
{
|
||||
for (var i = 0; i + 6 <= floats.Length; i += 6)
|
||||
{
|
||||
yield return new XYUVRQVortex(
|
||||
(int) floats[i],
|
||||
(int) floats[i + 1],
|
||||
(int) floats[i + 2],
|
||||
(int) floats[i + 3],
|
||||
floats[i + 4],
|
||||
floats[i + 5]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="XYUVRQVortex" /> for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns><see langword="true" /> if both instances are equal, otherwise <see langword="false" /></returns>
|
||||
public static bool operator ==(XYUVRQVortex left, XYUVRQVortex right)
|
||||
{
|
||||
return Equals(left, right) || left?.Equals(right) == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instance of <see cref="XYUVRQVortex" /> for in-equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns><see langword="true" /> if both instances are not equal, otherwise <see langword="false" /></returns>
|
||||
public static bool operator !=(XYUVRQVortex left, XYUVRQVortex right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Equals(obj as XYUVRQVortex);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = Q.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ R.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ U;
|
||||
hashCode = (hashCode * 397) ^ V;
|
||||
hashCode = (hashCode * 397) ^ X;
|
||||
hashCode = (hashCode * 397) ^ Y;
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this instance of <see cref="XYUVRQVortex"/> as a float array.
|
||||
/// </summary>
|
||||
/// <returns>An array of float values representing this instance of <see cref="XYUVRQVortex"/>.</returns>
|
||||
public float[] AsFloatArray()
|
||||
{
|
||||
return new[] {X, Y, U, V, R, Q};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user