From 0ce9b63d474f39c5cf87b51d191a6eeafb5c324f Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 17 Jul 2024 12:09:14 -0500 Subject: [PATCH] amdgpu_panel_power: Add support for progressive ABM levels More users use power saver as their default value than expected, and so ABM is a more negative experience for some of them. Instead of a table of values, use "progressive" values that change based on battery life. The selected values: * Balanced + AC: ABM 0 * Balanced + battery: >= 30% battery ABM 0 < 30% battery ABM 1 * Power Saver + AC: ABM 0 * Power Saver + battery: >= 50% battery ABM 0 30-49% battery ABM 1 20-30% battery ABM 2 <20% battery ABM 3 --- src/ppd-action-amdgpu-panel-power.c | 30 +++++++++++++++++++++++++++-- tests/integration_test.py | 22 ++++++++++++++++++--- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/ppd-action-amdgpu-panel-power.c b/src/ppd-action-amdgpu-panel-power.c index 0405804..b865f88 100644 --- a/src/ppd-action-amdgpu-panel-power.c +++ b/src/ppd-action-amdgpu-panel-power.c @@ -47,6 +47,7 @@ struct _PpdActionAmdgpuPanelPower gint panel_power_saving; gboolean valid_battery; gboolean on_battery; + gdouble battery_level; }; G_DEFINE_TYPE (PpdActionAmdgpuPanelPower, ppd_action_amdgpu_panel_power, PPD_TYPE_ACTION) @@ -148,10 +149,20 @@ ppd_action_amdgpu_panel_update_target (PpdActionAmdgpuPanelPower *self, if (self->on_battery) { switch (self->last_profile) { case PPD_PROFILE_POWER_SAVER: - target = 3; + if (!self->battery_level || self->battery_level >= 50) + target = 0; + else if (self->battery_level > 30) + target = 1; + else if (self->battery_level > 20 && self->battery_level <= 30) + target = 2; + else /* < 20 */ + target = 3; break; case PPD_PROFILE_BALANCED: - target = 1; + if (!self->battery_level || self->battery_level >= 30) + target = 0; + else + target = 1; break; case PPD_PROFILE_PERFORMANCE: target = 0; @@ -159,6 +170,7 @@ ppd_action_amdgpu_panel_update_target (PpdActionAmdgpuPanelPower *self, } } + g_info("Updating panel to %d due to 🔋 %d (%f)", target, self->on_battery, self->battery_level); if (!set_panel_power (self, target, error)) return FALSE; self->panel_power_saving = target; @@ -204,6 +216,19 @@ ppd_action_amdgpu_panel_power_power_changed (PpdAction *action, } self->valid_battery = TRUE; + + return ppd_action_amdgpu_panel_update_target (self, error); +} + +static gboolean +ppd_action_amdgpu_panel_power_battery_changed (PpdAction *action, + gdouble val, + GError **error) +{ + PpdActionAmdgpuPanelPower *self = PPD_ACTION_AMDGPU_PANEL_POWER (action); + + self->battery_level = val; + return ppd_action_amdgpu_panel_update_target (self, error); } @@ -284,6 +309,7 @@ ppd_action_amdgpu_panel_power_class_init (PpdActionAmdgpuPanelPowerClass *klass) driver_class->probe = ppd_action_amdgpu_panel_power_probe; driver_class->activate_profile = ppd_action_amdgpu_panel_power_activate_profile; driver_class->power_changed = ppd_action_amdgpu_panel_power_power_changed; + driver_class->battery_changed = ppd_action_amdgpu_panel_power_battery_changed; } static void diff --git a/tests/integration_test.py b/tests/integration_test.py index 6375b12..92b1485 100644 --- a/tests/integration_test.py +++ b/tests/integration_test.py @@ -1623,18 +1623,34 @@ class Tests(dbusmock.DBusTestCase): # start upower and try again self.stop_daemon() - self.start_dbus_template( + _, obj, _ = self.start_dbus_template( "upower", {"DaemonVersion": "0.99", "OnBattery": True}, ) + obj.SetupDisplayDevice( + 2, 1, 50.0, 40.0, 80.0, 2.5, 3600, 1800, True, "half battery", 3 + ) self.start_daemon() - # verify balanced updated it + # verify balanced has it off at half battery self.set_dbus_property("ActiveProfile", GLib.Variant.new_string("balanced")) + self.assert_sysfs_attr_eventually_is(edp, amdgpu_panel_power_savings, "0") + + # verify balanced turned it on when less than third battery + obj.SetupDisplayDevice(2, 1, 29.0, 40.0, 80.0, 2.5, 3600, 1800, True, "29%", 3) self.assert_sysfs_attr_eventually_is(edp, amdgpu_panel_power_savings, "1") - # verify power saver updated it + # switch to power saver with a large battery, make sure off + obj.SetupDisplayDevice(2, 1, 70, 40.0, 80.0, 2.5, 3600, 1800, True, "70%", 3) self.set_dbus_property("ActiveProfile", GLib.Variant.new_string("power-saver")) + self.assert_sysfs_attr_eventually_is(edp, amdgpu_panel_power_savings, "0") + + # set power saver with less than half battery, should turn on + obj.SetupDisplayDevice(2, 1, 49, 40.0, 80.0, 2.5, 3600, 1800, True, "49%", 3) + self.assert_sysfs_attr_eventually_is(edp, amdgpu_panel_power_savings, "1") + + # set power saver with very little battery, should turn on at 3 + obj.SetupDisplayDevice(2, 1, 15, 40.0, 80.0, 2.5, 3600, 1800, True, "15%", 3) self.assert_sysfs_attr_eventually_is(edp, amdgpu_panel_power_savings, "3") # add another device that supports the feature