From ca7c696b06ebaf70caa97e6958f0c0af664a96eb Mon Sep 17 00:00:00 2001 From: Terry MacDonald Date: Wed, 7 Oct 2020 21:58:05 +1300 Subject: [PATCH] Bypassed NVIDIA Grid Topology if not needed Added some logic to check if either the from or to profile conatins an NVIDIA surround screen. If not, then there is no need to apply a GridTopology as it is all single devices! Saves up to 15 seconds on swap over. --- .../NVIDIA/SurroundTopologyDisplay.cs | 2 +- HeliosPlus.Shared/ProfileRepository.cs | 23 ++----- HeliosPlus/Program.cs | 65 ++++++++++++------- .../UIForms/ApplyingProfileForm.Designer.cs | 11 ++-- 4 files changed, 54 insertions(+), 47 deletions(-) diff --git a/HeliosPlus.Shared/NVIDIA/SurroundTopologyDisplay.cs b/HeliosPlus.Shared/NVIDIA/SurroundTopologyDisplay.cs index fe22496..dbc71d0 100644 --- a/HeliosPlus.Shared/NVIDIA/SurroundTopologyDisplay.cs +++ b/HeliosPlus.Shared/NVIDIA/SurroundTopologyDisplay.cs @@ -36,7 +36,7 @@ namespace HeliosPlus.Shared.NVIDIA //Debug.WriteLine($"SurroundTopologyDisplay/NVIDIAApiException exception: {ex.Message}: {ex.StackTrace} - {ex.InnerException}"); // If we hit here then we cannot find the DisplayName from the EDID Data from the GPU // So we just make one up using the DisplayID - DisplayName = $"Display {display.DisplayDevice.Output.OutputId}:{DisplayId}"; + DisplayName = $"Display #{DisplayId}"; } } diff --git a/HeliosPlus.Shared/ProfileRepository.cs b/HeliosPlus.Shared/ProfileRepository.cs index ee17cda..53fb1c3 100644 --- a/HeliosPlus.Shared/ProfileRepository.cs +++ b/HeliosPlus.Shared/ProfileRepository.cs @@ -826,7 +826,7 @@ namespace HeliosPlus.Shared return displayIdentifiers; } - public static bool ApplyTopology(ProfileItem profile) + public static bool ApplyNVIDIAGridTopology(ProfileItem profile) { Debug.Print("ProfileRepository.ApplyTopology()"); @@ -844,7 +844,9 @@ namespace HeliosPlus.Shared if (surroundTopologies.Length == 0) { - // This profile does not use NVIDIA Surround + // The profile we're changing to does not use NVIDIA Surround + // So we need to set the Grid Topologies to individual screens + // in preparation for the PathInfo step later var currentTopologies = GridTopology.GetGridTopologies(); if (currentTopologies.Any(topology => topology.Rows * topology.Columns > 1)) @@ -872,7 +874,7 @@ namespace HeliosPlus.Shared } } - public static bool ApplyPathInfo(ProfileItem profile) + public static bool ApplyWindowsDisplayPathInfo(ProfileItem profile) { Debug.Print("ProfileRepository.ApplyPathInfo()"); if (!(profile is ProfileItem)) @@ -880,22 +882,7 @@ namespace HeliosPlus.Shared try { - /*var viewports = profile.Viewports; - foreach (var viewport in viewports) - { - var vpPathInfo = viewport.ToPathInfo(); - }*/ - - - var pathInfos = profile.Paths.Select(paths => paths.ToPathInfo()).Where(info => info != null).ToArray(); - //var PathInfos2 = NvAPIWrapper.Display.PathInfo.GetDisplaysConfig(); - /*if (!pathInfos.Any()) - { - throw new InvalidOperationException( - @"Display configuration changed since this profile is created. Please re-create this profile."); - }*/ - //var PathInfo2 = WindowsDisplayAPI.DisplayConfig.PathInfo.GetActivePaths(); PathInfo.ApplyPathInfos(pathInfos, true, true, true); return true; } diff --git a/HeliosPlus/Program.cs b/HeliosPlus/Program.cs index 78f2581..1999338 100644 --- a/HeliosPlus/Program.cs +++ b/HeliosPlus/Program.cs @@ -312,7 +312,7 @@ namespace HeliosPlus { Task applyTopologyTask = new Task(() => { Console.WriteLine("Program/ApplyProfile : Applying Profile Topology " + profile.Name); - if (!ProfileRepository.ApplyTopology(profile)) + if (!ProfileRepository.ApplyNVIDIAGridTopology(profile)) { // Somehow return that this profile topology didn't apply } @@ -320,7 +320,7 @@ namespace HeliosPlus { Task applyPathInfoTask = new Task(() => { Console.WriteLine("Program/ApplyProfile : Applying Profile Path " + profile.Name); - if (!ProfileRepository.ApplyPathInfo(profile)) + if (!ProfileRepository.ApplyWindowsDisplayPathInfo(profile)) { // Somehow return that this profile path info didn't apply } @@ -329,40 +329,59 @@ namespace HeliosPlus { // Set up the UI forms to show ApplyingProfileForm timeoutForm = new ApplyingProfileForm(null, 3, $"Changing to '{profile.Name}' Profile", "Press ESC to cancel", Color.Orange, true); - ApplyingProfileForm topologyForm = new ApplyingProfileForm(applyTopologyTask, 15, $"Changing to '{profile.Name}' Profile", "Applying Topology (Step one of two)", Color.Aquamarine); - ApplyingProfileForm pathInfoForm = new ApplyingProfileForm(applyPathInfoTask, 15, $"Changing to '{profile.Name}' Profile", "Applying Path Info (Step two of two)", Color.LawnGreen); + ApplyingProfileForm topologyForm = new ApplyingProfileForm(applyTopologyTask, 15, $"Changing to '{profile.Name}' Profile", "Applying NVIDIA Grid Topology", Color.Aquamarine); + ApplyingProfileForm pathInfoForm = new ApplyingProfileForm(applyPathInfoTask, 15, $"Changing to '{profile.Name}' Profile", "Applying Windows Display Device settings", Color.LawnGreen); if (timeoutForm.ShowDialog() == DialogResult.Cancel) { return false; } - topologyForm.ShowDialog(); - - try + // We only want to do the topology change if the profile we're on now + // or the profile we're going to are NVIDIA surround profiles + int toProfileSurroundTopologyCount = + profile.Paths.SelectMany(paths => paths.TargetDisplays) + .Select(target => target.SurroundTopology) + .Where(topology => topology != null) + .Select(topology => topology.ToGridTopology()) + .Count(); + int fromProfileSurroundTopologyCount = + ProfileRepository.CurrentProfile.Paths.SelectMany(paths => paths.TargetDisplays) + .Select(target => target.SurroundTopology) + .Where(topology => topology != null) + .Select(topology => topology.ToGridTopology()) + .Count(); + + if (toProfileSurroundTopologyCount > 0 || fromProfileSurroundTopologyCount > 0) { - applyTopologyTask.Wait(); - } - catch (AggregateException ae) - { - foreach (var e in ae.InnerExceptions) + topologyForm.ShowDialog(); + + try { - // Handle the custom exception. - if (e is ApplyTopologyException) + applyTopologyTask.Wait(); + } + catch (AggregateException ae) + { + foreach (var e in ae.InnerExceptions) { - Console.WriteLine(e.Message); - } - // Rethrow any other exception. - else - { - throw; + // Handle the custom exception. + if (e is ApplyTopologyException) + { + Console.WriteLine(e.Message); + } + // Rethrow any other exception. + else + { + throw; + } } } + + if (applyTopologyTask.IsFaulted) + Console.WriteLine("Program/ApplyProfile : Applying Profile Topology stage failed to complete"); } - if (applyTopologyTask.IsFaulted) - Console.WriteLine("Program/ApplyProfile : Applying Profile Topology stage failed to complete"); - + // We always want to do the WindowsDisplayAPI PathInfo part pathInfoForm.ShowDialog(); applyPathInfoTask.Wait(); try diff --git a/HeliosPlus/UIForms/ApplyingProfileForm.Designer.cs b/HeliosPlus/UIForms/ApplyingProfileForm.Designer.cs index 1a631e2..756ad15 100644 --- a/HeliosPlus/UIForms/ApplyingProfileForm.Designer.cs +++ b/HeliosPlus/UIForms/ApplyingProfileForm.Designer.cs @@ -40,6 +40,7 @@ // progressPanel // this.progressPanel.Anchor = System.Windows.Forms.AnchorStyles.None; + this.progressPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(50)))), ((int)(((byte)(50))))); this.progressPanel.Controls.Add(this.lbl_sub_message); this.progressPanel.Controls.Add(this.progressBar); this.progressPanel.Controls.Add(this.lbl_message); @@ -52,9 +53,9 @@ // this.lbl_sub_message.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.lbl_sub_message.ForeColor = System.Drawing.Color.White; - this.lbl_sub_message.Location = new System.Drawing.Point(148, 67); + this.lbl_sub_message.Location = new System.Drawing.Point(73, 67); this.lbl_sub_message.Name = "lbl_sub_message"; - this.lbl_sub_message.Size = new System.Drawing.Size(330, 30); + this.lbl_sub_message.Size = new System.Drawing.Size(501, 30); this.lbl_sub_message.TabIndex = 2; this.lbl_sub_message.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // @@ -62,10 +63,10 @@ // this.progressBar.AnimationFunction = WinFormAnimation.KnownAnimationFunctions.Liner; this.progressBar.AnimationSpeed = 1000; - this.progressBar.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40))))); + this.progressBar.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(50)))), ((int)(((byte)(50))))); this.progressBar.Font = new System.Drawing.Font("Microsoft Sans Serif", 39.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.progressBar.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); - this.progressBar.InnerColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); + this.progressBar.InnerColor = System.Drawing.Color.Ivory; this.progressBar.InnerMargin = 0; this.progressBar.InnerWidth = 0; this.progressBar.Location = new System.Drawing.Point(243, 125); @@ -108,7 +109,7 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40))))); + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(50)))), ((int)(((byte)(50))))); this.ClientSize = new System.Drawing.Size(800, 450); this.Controls.Add(this.progressPanel); this.DoubleBuffered = true;