[WIP] Partially completed NVIDIA spannedScreens

Partway through having the Screens properly populated for the NVIDIA surround screen setups, but have struck an issue with the extra non-surround screens in a combined surround and non-surround screen setup. The additional non-surround screens don't have any X & Y positions set within the mosaic config, which means I should really be using the WIndows config details, but there isn't anyway to identify which windows screen path matches which nvidia display ID. THe only way to do this is to start storing the NVIDIA displayconfig too.
This commit is contained in:
Terry MacDonald 2021-09-01 14:30:33 +12:00
parent bc6242a8bb
commit 52d2f4f0f6
4 changed files with 199 additions and 111 deletions

View File

@ -254,13 +254,18 @@ namespace DisplayMagicianShared.NVIDIA
public override bool PerformPostLoadingTasks()
{
// First thing we do is to set up the Screens
_screens = GetScreenPositions();
//_screens = GetScreenPositions();
return true;
}
public override List<ScreenPosition> GetScreenPositions()
{
// Set up some colours
Color primaryScreenColor = Color.FromArgb(150, 255, 97, 27); // represents Primary screen blue
Color spannedScreenColor = Color.FromArgb(118, 185, 0); // represents NVIDIA Green
Color normalScreenColor = Color.FromArgb(195, 195, 195); // represents normal screen colour (gray)
// Now we create the screens structure from the AMD profile information
_screens = new List<ScreenPosition>();
@ -271,109 +276,209 @@ namespace DisplayMagicianShared.NVIDIA
// Return an empty screen if we have no Display Config Paths to use!
return _screens;
}
// TODO: Make the NVIDIA displays show the individual screens and overlap!
/*// Create a dictionary of all the screen sizes we want
Dictionary<string,SpannedScreenPosition> MosaicScreens = new Dictionary<string,SpannedScreenPosition>();
for (int i = 0; i < _nvidiaDisplayConfig.MosaicConfig.MosaicGridCount; i++)
// Now we need to check for Spanned screens
if (_nvidiaDisplayConfig.MosaicConfig.IsMosaicEnabled)
{
for (int j = 0; j < _nvidiaDisplayConfig.MosaicConfig.MosaicViewports.Where(item => item); j++)
// TODO: Make the NVIDIA displays show the individual screens and overlap!
// Create a dictionary of all the screen sizes we want
//Dictionary<string,SpannedScreenPosition> MosaicScreens = new Dictionary<string,SpannedScreenPosition>();
for (int i = 0; i < _nvidiaDisplayConfig.MosaicConfig.MosaicGridCount; i++)
{
}
}*/
foreach (var path in _windowsDisplayConfig.DisplayConfigPaths)
{
// For each path we go through and get the relevant info we need.
if (_windowsDisplayConfig.DisplayConfigPaths.Length > 0)
{
// Set some basics about the screen
ScreenPosition screen = new ScreenPosition();
screen.Library = "NVIDIA";
UInt32 sourceId = path.SourceInfo.Id;
UInt32 targetId = path.TargetInfo.Id;
// Go through the screens as Windows knows them, and then enhance the info with Mosaic data if it applies
foreach (DISPLAYCONFIG_MODE_INFO displayMode in _windowsDisplayConfig.DisplayConfigModes)
{
// Find the matching Display Config Source Mode
if (displayMode.InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE && displayMode.Id == sourceId)
{
screen.Name = targetId.ToString();
//screen.DisplayConnector = displayMode.DisplayConnector;
screen.ScreenX = displayMode.SourceMode.Position.X;
screen.ScreenY = displayMode.SourceMode.Position.Y;
screen.ScreenWidth = (int)displayMode.SourceMode.Width;
screen.ScreenHeight = (int)displayMode.SourceMode.Height;
// If we're at the 0,0 coordinate then we're the primary monitor
if (screen.ScreenX == 0 && screen.ScreenY == 0)
{
screen.IsPrimary = true;
}
// Figure out if this is a spanned screen, and if so, record this info
if (_nvidiaDisplayConfig.MosaicConfig.IsMosaicEnabled)
{
}
break;
}
}
foreach (ADVANCED_HDR_INFO_PER_PATH hdrInfo in _windowsDisplayConfig.DisplayHDRStates)
{
// Find the matching HDR information
if (hdrInfo.Id == targetId)
{
// HDR information
if (hdrInfo.AdvancedColorInfo.AdvancedColorSupported)
{
screen.HDRSupported = true;
if (hdrInfo.AdvancedColorInfo.AdvancedColorEnabled)
{
screen.HDREnabled = true;
}
else
{
screen.HDREnabled = false;
}
}
else
{
screen.HDRSupported = false;
screen.HDREnabled = false;
}
break;
}
}
// Now we need to check for Spanned screens
if (_nvidiaDisplayConfig.MosaicConfig.IsMosaicEnabled)
if (_nvidiaDisplayConfig.MosaicConfig.MosaicGridTopos[i].DisplayCount > 1)
{
// Set some basics about the screen
screen.SpannedScreens = new List<SpannedScreenPosition>();
screen.Name = "NVIDIA Surround/Mosaic";
screen.IsSpanned = true;
screen.Colour = Color.FromArgb(118, 185, 0); // represents NVIDIA Green
screen.SpannedName = "NVIDIA Surround/Mosaic";
screen.SpannedRows = (int)_nvidiaDisplayConfig.MosaicConfig.MosaicGridTopos[i].Rows;
screen.SpannedColumns = (int)_nvidiaDisplayConfig.MosaicConfig.MosaicGridTopos[i].Columns;
screen.Colour = spannedScreenColor;
// This is a combined surround/mosaic screen
// We need to build the size of the screen to match it later so we check the MosaicViewports
uint minX = 0;
uint minY = 0;
uint maxX = 0;
uint maxY = 0;
uint overallX = 0;
uint overallY = 0;
int overallWidth = 0;
int overallHeight = 0;
for (int j = 0; j < _nvidiaDisplayConfig.MosaicConfig.MosaicGridTopos[i].DisplayCount; j++)
{
SpannedScreenPosition spannedScreen = new SpannedScreenPosition();
spannedScreen.Name = _nvidiaDisplayConfig.MosaicConfig.MosaicGridTopos[i].Displays[j].DisplayId.ToString();
spannedScreen.Colour = spannedScreenColor;
// Calculate screen size
NV_RECT viewRect = _nvidiaDisplayConfig.MosaicConfig.MosaicViewports[i][j];
if (viewRect.Left < minX)
{
minX = viewRect.Left;
}
if (viewRect.Top < minY)
{
minY = viewRect.Top;
}
if (viewRect.Right > maxX)
{
maxX = viewRect.Right;
}
if (viewRect.Bottom > maxY)
{
maxY = viewRect.Bottom;
}
uint width = viewRect.Right - viewRect.Left + 1;
uint height = viewRect.Bottom - viewRect.Top + 1;
spannedScreen.ScreenX = (int)viewRect.Left;
spannedScreen.ScreenY = (int)viewRect.Top;
spannedScreen.ScreenWidth = (int)width;
spannedScreen.ScreenHeight = (int)height;
// Figure out the overall figures for the screen
if (viewRect.Left < overallX)
{
overallX = viewRect.Left;
}
if (viewRect.Top < overallY)
{
overallY = viewRect.Top;
}
overallWidth = (int)maxX - (int)minX + 1;
overallHeight = (int)maxY - (int)minY + 1;
spannedScreen.Row = i + 1;
spannedScreen.Column = j + 1;
// Add the spanned screen to the screen
screen.SpannedScreens.Add(spannedScreen);
}
//screen.Name = targetId.ToString();
//screen.DisplayConnector = displayMode.DisplayConnector;
screen.ScreenX = (int)overallX;
screen.ScreenY = (int)overallY;
screen.ScreenWidth = (int)overallWidth;
screen.ScreenHeight = (int)overallHeight;
// If we're at the 0,0 coordinate then we're the primary monitor
if (screen.ScreenX == 0 && screen.ScreenY == 0)
{
// Record we're primary screen
screen.IsPrimary = true;
// Change the colour to be the primary colour, but only if it isn't a surround screen
if (screen.Colour != spannedScreenColor)
{
screen.Colour = primaryScreenColor;
}
}
}
else
else if (_nvidiaDisplayConfig.MosaicConfig.MosaicGridTopos[i].DisplayCount == 1)
{
screen.IsSpanned = false;
screen.Colour = Color.FromArgb(195, 195, 195); // represents normal screen colour
// This is a single screen
// Set some basics about the screen
NV_MOSAIC_DISPLAY_SETTING_V1 viewDisplaySettings = _nvidiaDisplayConfig.MosaicConfig.MosaicGridTopos[i].DisplaySettings;
screen.ScreenX = (int)viewDisplaySettings.;
screen.ScreenY = (int)viewDisplaySettings.Top;
screen.ScreenWidth = (int)viewDisplaySettings.Width;
screen.ScreenHeight = (int)viewDisplaySettings.Height;
// If we're at the 0,0 coordinate then we're the primary monitor
if (screen.ScreenX == 0 && screen.ScreenY == 0)
{
screen.IsPrimary = true;
screen.Colour = primaryScreenColor;
}
}
_screens.Add(screen);
}
}
else
{
foreach (var path in _windowsDisplayConfig.DisplayConfigPaths)
{
// For each path we go through and get the relevant info we need.
if (_windowsDisplayConfig.DisplayConfigPaths.Length > 0)
{
// Set some basics about the screen
ScreenPosition screen = new ScreenPosition();
screen.Library = "NVIDIA";
screen.IsSpanned = false;
screen.Colour = normalScreenColor; // this is the default unless overridden by the primary screen
UInt32 sourceId = path.SourceInfo.Id;
UInt32 targetId = path.TargetInfo.Id;
// Go through the screens as Windows knows them, and then enhance the info with Mosaic data if it applies
foreach (DISPLAYCONFIG_MODE_INFO displayMode in _windowsDisplayConfig.DisplayConfigModes)
{
// Find the matching Display Config Source Mode
if (displayMode.InfoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE && displayMode.Id == sourceId)
{
screen.Name = targetId.ToString();
//screen.DisplayConnector = displayMode.DisplayConnector;
screen.ScreenX = displayMode.SourceMode.Position.X;
screen.ScreenY = displayMode.SourceMode.Position.Y;
screen.ScreenWidth = (int)displayMode.SourceMode.Width;
screen.ScreenHeight = (int)displayMode.SourceMode.Height;
// If we're at the 0,0 coordinate then we're the primary monitor
if (screen.ScreenX == 0 && screen.ScreenY == 0)
{
screen.IsPrimary = true;
screen.Colour = primaryScreenColor;
}
break;
}
}
foreach (ADVANCED_HDR_INFO_PER_PATH hdrInfo in _windowsDisplayConfig.DisplayHDRStates)
{
// Find the matching HDR information
if (hdrInfo.Id == targetId)
{
// HDR information
if (hdrInfo.AdvancedColorInfo.AdvancedColorSupported)
{
screen.HDRSupported = true;
if (hdrInfo.AdvancedColorInfo.AdvancedColorEnabled)
{
screen.HDREnabled = true;
}
else
{
screen.HDREnabled = false;
}
}
else
{
screen.HDRSupported = false;
screen.HDREnabled = false;
}
break;
}
}
_screens.Add(screen);
}
}
}
/*
// Go through the screens, and update the Mosaic screens with their info (if there are any)
if (_nvidiaDisplayConfig.MosaicConfig.IsMosaicEnabled)
if (_nvidiaDisplayConfig.MosaicConfig.IsMosaicEnabled && _nvidiaDisplayConfig.MosaicConfig.MosaicGridTopos.Length)
{
// *** Enum values for the mosaic topology type ***
// NV_MOSAIC_TOPO_1x2_BASIC = 1

View File

@ -59,21 +59,6 @@ namespace DisplayMagicianShared
return rect;
}
/*public static Size GetLargestResolution(List<ScreenPosition> screens)
{
Size largest = Size.Empty;
foreach (ScreenPosition screen in screens)
{
if ((ulong)screen.ScreenWidth * (ulong)screen.ScreenHeight > (ulong)largest.Width * (ulong)largest.Height)
{
largest = new Size(screen.ScreenWidth, screen.ScreenHeight);
}
}
return largest;
}*/
/// <summary>
/// Creates a rounded rectangle path
@ -131,10 +116,10 @@ namespace DisplayMagicianShared
public Bitmap ToTightestBitmap(int width = 256, int height = 0, PixelFormat format = PixelFormat.Format32bppArgb)
{
var viewSize = CalculateViewSize(_profile.Screens, 0, 0);
int viewSizeRatio = Convert.ToInt32(viewSize.Width / viewSize.Height);
double viewSizeRatio = viewSize.Width / viewSize.Height;
if (height == 0)
height = width / viewSizeRatio;
height = Convert.ToInt32((double)width / viewSizeRatio);
var bitmap = new Bitmap(width, height, format);
bitmap.MakeTransparent();

View File

@ -30,9 +30,8 @@ namespace DisplayMagicianShared
internal bool HDREnabled;
public List<string> Features;
// If the screen is AMD Eyefinity or NVIDIA Surround or similar, it has screens that are part of it
// These fields indicate this. THe spanned screens are added to the SpannedScreens field
// These fields indicate this. The spanned screens are added to the SpannedScreens field as required
public bool IsSpanned;
public string SpannedName;
public List<SpannedScreenPosition> SpannedScreens;
public int SpannedColumns;
public int SpannedRows;
@ -45,7 +44,6 @@ namespace DisplayMagicianShared
public int ScreenWidth;
public int ScreenHeight;
public string Name;
public bool IsPrimary;
public Color Colour;
public List<string> Features;
public int Column;

View File

@ -1007,7 +1007,7 @@ namespace DisplayMagicianShared.Windows
public List<string> GetCurrentPCIVideoCardVendors()
{
SharedLogger.logger.Error($"WinLibrary/GetCurrentPCIVideoCardVendors: Getting the current PCI vendor ids for the videocards reported to Windows");
SharedLogger.logger.Trace($"WinLibrary/GetCurrentPCIVideoCardVendors: Getting the current PCI vendor ids for the videocards reported to Windows");
List<string> videoCardVendorIds = new List<string>();