Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to use seperated TDP when device power on Battery Mode #833

Merged
merged 1 commit into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions HandheldCompanion/Managers/PerformanceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
using HandheldCompanion.Processors;
using HandheldCompanion.Utils;
using HandheldCompanion.Views;
using HandheldCompanion.Views.Pages;
using Microsoft.Win32;
using RTSSSharedMemoryNET;
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using Timer = System.Timers.Timer;

namespace HandheldCompanion.Managers;
Expand Down Expand Up @@ -99,6 +102,9 @@ public PerformanceManager()
autoWatchdog = new Timer { Interval = INTERVAL_AUTO, AutoReset = true, Enabled = false };
autoWatchdog.Elapsed += AutoTDPWatchdog_Elapsed;

// Monitor Power Status
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;

ProfileManager.Applied += ProfileManager_Applied;
ProfileManager.Discarded += ProfileManager_Discarded;

Expand All @@ -115,6 +121,11 @@ public PerformanceManager()
MaxDegreeOfParallelism = Convert.ToInt32(Environment.ProcessorCount / 2);
}

private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
ProfilesPage.RequestUpdate();
}

private void SettingsManagerOnSettingValueChanged(string name, object value)
{
switch (name)
Expand All @@ -140,18 +151,24 @@ private void ProfileManager_Applied(Profile profile, ProfileUpdateSource source)
// apply profile defined TDP
if (profile.TDPOverrideEnabled && profile.TDPOverrideValues is not null)
{
double[] TDPOverrideValues;
// Check if using TDP on Battery & is not Plugged in
bool PluggedInStatus = SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online;
if (profile.TDPOnBatteryEnabled && profile.TDPOnBatteryValues is not null && !PluggedInStatus) TDPOverrideValues = profile.TDPOnBatteryValues;
else TDPOverrideValues = profile.TDPOverrideValues;

if (!profile.AutoTDPEnabled)
{
// Manual TDP is set, use it and set max limit
RequestTDP(profile.TDPOverrideValues);
RequestTDP(TDPOverrideValues);
StartTDPWatchdog();
AutoTDPMax = SettingsManager.GetInt("ConfigurableTDPOverrideUp");
}
else
{
// Both manual TDP and AutoTDP are on,
// use manual slider as the max limit for AutoTDP
AutoTDPMax = profile.TDPOverrideValues[0];
AutoTDPMax = TDPOverrideValues[0];
StopTDPWatchdog(true);
}
}
Expand Down
2 changes: 2 additions & 0 deletions HandheldCompanion/Misc/Profile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@
// power
public bool TDPOverrideEnabled { get; set; }
public double[] TDPOverrideValues { get; set; }
public bool TDPOnBatteryEnabled { get; set; }
public double[] TDPOnBatteryValues { get; set; }
Comment on lines 123 to +127
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The addition of TDPOnBatteryEnabled and TDPOnBatteryValues properties is consistent with the feature being implemented. However, ensure that these properties are properly serialized and deserialized when the Profile objects are saved and loaded. Also, consider initializing TDPOverrideValues and TDPOnBatteryValues to prevent null reference exceptions when they are accessed before being set.

+   public double[] TDPOverrideValues { get; set; } = new double[0];
+   public double[] TDPOnBatteryValues { get; set; } = new double[0];

Commitable suggestion

[!IMPORTANT]
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// power
public bool TDPOverrideEnabled { get; set; }
public double[] TDPOverrideValues { get; set; }
public bool TDPOnBatteryEnabled { get; set; }
public double[] TDPOnBatteryValues { get; set; }
// power
public bool TDPOverrideEnabled { get; set; }
public double[] TDPOverrideValues { get; set; } = new double[0];
public bool TDPOnBatteryEnabled { get; set; }
public double[] TDPOnBatteryValues { get; set; } = new double[0];


public bool GPUOverrideEnabled { get; set; }
public double GPUOverrideValue { get; set; }
Expand Down Expand Up @@ -150,7 +152,7 @@
new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
}

public int CompareTo(object obj)

Check warning on line 155 in HandheldCompanion/Misc/Profile.cs

View workflow job for this annotation

GitHub Actions / Build and Release

Nullability of reference types in type of parameter 'obj' of 'int Profile.CompareTo(object obj)' doesn't match implicitly implemented member 'int IComparable.CompareTo(object? obj)' (possibly because of nullability attributes).
{
var profile = (Profile)obj;
return profile.Name.CompareTo(Name);
Expand Down
18 changes: 18 additions & 0 deletions HandheldCompanion/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions HandheldCompanion/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2357,4 +2357,10 @@ with motion input enabled, use selected button(s) to disable motion.</value>
<data name="LayoutPage_SetAsDefault" xml:space="preserve">
<value>Make this the default layout</value>
</data>
<data name="ProfilesPage_TDPOnBattery" xml:space="preserve">
<value>TDP settings On Battery</value>
</data>
<data name="ProfilesPage_TDPOnBatteryDesc" xml:space="preserve">
<value>Using seperated TDP settings when On Battery</value>
</data>
</root>
61 changes: 61 additions & 0 deletions HandheldCompanion/Views/Pages/ProfilesPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,68 @@
</DockPanel>
</StackPanel>
</Grid>
<!-- TDP On Battery limit -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="9*" MinWidth="200" />
<ColumnDefinition MinWidth="200" />
</Grid.ColumnDefinitions>

<StackPanel Orientation="Vertical">
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Text="{x:Static resx:Resources.ProfilesPage_TDPOnBattery}" />
<TextBlock
Foreground="{DynamicResource SystemControlForegroundBaseMediumBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Static resx:Resources.ProfilesPage_TDPOnBatteryDesc}"
TextWrapping="Wrap" />
</StackPanel>

<ui:ToggleSwitch
Name="TDPOnBatteryToggle"
IsEnabled="{Binding ElementName=TDPToggle, Path=IsOn}"
Grid.Column="1"
HorizontalAlignment="Right"
Style="{DynamicResource InvertedToggleSwitchStyle}"
Toggled="TDPOnBatteryToggle_Toggled" />
</Grid>
<!-- Content -->
<Grid IsEnabled="{Binding ElementName=TDPToggle, Path=IsOn}">

<StackPanel>
<TextBlock
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{x:Static resx:Resources.ProfilesPage_PowerLimitTarget}" />

<DockPanel ScrollViewer.PanningMode="HorizontalOnly">
<TextBlock
Width="35"
VerticalAlignment="Center"
Text="{Binding Value, StringFormat=N0, ElementName=TDPOnBatterySlider, Mode=OneWay}"
TextAlignment="Center" />
<TextBlock
Width="30"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{x:Static resx:Resources.QuickPerformancePage_TDPUnitWatt}" />
<Slider IsEnabled="{Binding ElementName=TDPOnBatteryToggle, Path=IsOn}"
x:Name="TDPOnBatterySlider"
Margin="6,0,0,0"
VerticalAlignment="Center"
AutoToolTipPrecision="0"
IsMoveToPointEnabled="True"
IsSnapToTickEnabled="True"
LargeChange="5"
Maximum="30"
Minimum="5"
SmallChange="1"
Style="{DynamicResource SliderStyle1}"
TickFrequency="1"
TickPlacement="BottomRight"
ValueChanged="TDPOnBatterySlider_ValueChanged" />
</DockPanel>
</StackPanel>
</Grid>
<!-- Separator -->
<Separator
Margin="-46,0,-16,0"
Expand Down
41 changes: 41 additions & 0 deletions HandheldCompanion/Views/Pages/ProfilesPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ public void SettingsManager_SettingValueChanged(string name, object value)
using (new ScopedLock(updateLock))
{
TDPSlider.Minimum = (double)value;
TDPOnBatterySlider.Minimum = (double)value;
}
}
break;
Expand All @@ -138,6 +139,7 @@ public void SettingsManager_SettingValueChanged(string name, object value)
using (new ScopedLock(updateLock))
{
TDPSlider.Maximum = (double)value;
TDPOnBatterySlider.Maximum = (double)value;
}
}
break;
Expand Down Expand Up @@ -401,6 +403,17 @@ private void DrawProfile()
TDPSlider.Minimum = SettingsManager.GetInt("ConfigurableTDPOverrideDown");
TDPSlider.Maximum = SettingsManager.GetInt("ConfigurableTDPOverrideUp");

// Sustained TDP On Battery settings (slow, stapm, long)
TDPOnBatteryToggle.IsOn = selectedProfile.TDPOnBatteryEnabled;
var TDPOnBattery = selectedProfile.TDPOnBatteryValues is not null
? selectedProfile.TDPOnBatteryValues
: MainWindow.CurrentDevice.nTDP;
TDPOnBatterySlider.Value = TDPOnBattery[(int)PowerType.Slow];

// define slider(s) min and max values based on device specifications
TDPOnBatterySlider.Minimum = SettingsManager.GetInt("ConfigurableTDPOverrideDown");
TDPOnBatterySlider.Maximum = SettingsManager.GetInt("ConfigurableTDPOverrideUp");

// Automatic TDP
AutoTDPToggle.IsOn = selectedProfile.AutoTDPEnabled;
AutoTDPSlider.Value = (int)selectedProfile.AutoTDPRequestedFPS;
Expand Down Expand Up @@ -572,6 +585,34 @@ private void TDPSlider_ValueChanged(object sender, RoutedPropertyChangedEventArg
RequestUpdate();
}

private void TDPOnBatteryToggle_Toggled(object sender, RoutedEventArgs e)
{
// wait until lock is released
if (updateLock)
return;

selectedProfile.TDPOnBatteryEnabled = TDPOnBatteryToggle.IsOn;
RequestUpdate();
}

private void TDPOnBatterySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (!TDPOnBatterySlider.IsInitialized)
return;

// wait until lock is released
if (updateLock)
return;

selectedProfile.TDPOnBatteryValues = new double[3]
{
(int)TDPOnBatterySlider.Value,
(int)TDPOnBatterySlider.Value,
(int)TDPOnBatterySlider.Value
};
RequestUpdate();
}
Comment on lines 585 to +614
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RequestUpdate method is called after setting the TDP values, which is good for ensuring that changes are queued for submission. However, the cast to (int) may not be necessary if the slider values are already double. If the intention is to store integers, it's fine, but if the underlying TDP settings can accept double values, consider removing the cast to avoid unnecessary precision loss.

-            (int)TDPSlider.Value,
-            (int)TDPSlider.Value,
-            (int)TDPSlider.Value
+            TDPSlider.Value,
+            TDPSlider.Value,
+            TDPSlider.Value

Commitable suggestion

[!IMPORTANT]
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
RequestUpdate();
}
private void TDPOnBatteryToggle_Toggled(object sender, RoutedEventArgs e)
{
// wait until lock is released
if (updateLock)
return;
selectedProfile.TDPOnBatteryEnabled = TDPOnBatteryToggle.IsOn;
RequestUpdate();
}
private void TDPOnBatterySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (!TDPOnBatterySlider.IsInitialized)
return;
// wait until lock is released
if (updateLock)
return;
selectedProfile.TDPOnBatteryValues = new double[3]
{
(int)TDPOnBatterySlider.Value,
(int)TDPOnBatterySlider.Value,
(int)TDPOnBatterySlider.Value
};
RequestUpdate();
}
private void TDPOnBatterySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (!TDPOnBatterySlider.IsInitialized)
return;
// wait until lock is released
if (updateLock)
return;
selectedProfile.TDPOnBatteryValues = new double[3]
{
TDPOnBatterySlider.Value,
TDPOnBatterySlider.Value,
TDPOnBatterySlider.Value
};
RequestUpdate();
}


private void FramerateToggle_Toggled(object sender, RoutedEventArgs e)
{
// UI thread (async)
Expand Down
61 changes: 60 additions & 1 deletion HandheldCompanion/Views/QuickPages/QuickProfilesPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,68 @@
TickPlacement="BottomRight"
ValueChanged="TDPSlider_ValueChanged" />
</DockPanel>

<!-- TDP On Battery Limit -->
<Grid Margin="0,8,0,0" d:Visibility="Visible" Visibility="{Binding ElementName=TDPToggle, Path=IsOn, Converter={StaticResource BooleanToVisibilityConverter}}">
<DockPanel>
<ui:FontIcon
Height="40"
HorizontalAlignment="Center"
FontFamily="{DynamicResource SymbolThemeFontFamily}"
Glyph="&#xEBA9;" />

<ui:SimpleStackPanel Margin="12,0,0,0" VerticalAlignment="Center">
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Text="{x:Static resx:Resources.ProfilesPage_TDPOnBattery}" />
<TextBlock
Foreground="{DynamicResource SystemControlForegroundBaseMediumBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Static resx:Resources.ProfilesPage_TDPOnBatteryDesc}"
TextWrapping="Wrap" />
</ui:SimpleStackPanel>
</DockPanel>

<ui:ToggleSwitch
Name="TDPOnBatteryToggle"
Grid.Column="1"
HorizontalAlignment="Right"
Style="{DynamicResource InvertedToggleSwitchStyle}"
Toggled="TDPOnBatteryToggle_Toggled"/>
</Grid>

<StackPanel d:Visibility="Visible" Visibility="{Binding ElementName=TDPOnBatteryToggle, Path=IsOn, Converter={StaticResource BooleanToVisibilityConverter}}">
<TextBlock
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{x:Static resx:Resources.QuickProfilesPage_PowerLimitTarget}" />
<DockPanel Margin="8,0,0,0" ScrollViewer.PanningMode="HorizontalOnly">
<TextBlock
Width="35"
VerticalAlignment="Center"
Text="{Binding Value, StringFormat=N0, ElementName=TDPOnBatterySlider, Mode=OneWay}"
TextAlignment="Center" />
<TextBlock
Width="30"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Text="{x:Static resx:Resources.QuickPerformancePage_TDPUnitWatt}" />
<Slider
x:Name="TDPOnBatterySlider"
Margin="8,0,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
AutoToolTipPrecision="0"
IsMoveToPointEnabled="True"
IsSnapToTickEnabled="True"
LargeChange="5"
SmallChange="1"
Style="{DynamicResource SliderStyle1}"
TickFrequency="1"
TickPlacement="BottomRight"
ValueChanged="TDPOnBatterySlider_ValueChanged" />
</DockPanel>
</StackPanel>
</StackPanel>
</ui:SimpleStackPanel>

<Separator Background="{DynamicResource ExpanderHeaderBackground}" />

<!-- Auto TDP -->
Expand Down
Loading
Loading