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
This commit is contained in:
Mario Limonciello 2024-07-17 12:09:14 -05:00
parent 69e90eeb50
commit 0ce9b63d47
2 changed files with 47 additions and 5 deletions

View file

@ -47,6 +47,7 @@ struct _PpdActionAmdgpuPanelPower
gint panel_power_saving; gint panel_power_saving;
gboolean valid_battery; gboolean valid_battery;
gboolean on_battery; gboolean on_battery;
gdouble battery_level;
}; };
G_DEFINE_TYPE (PpdActionAmdgpuPanelPower, ppd_action_amdgpu_panel_power, PPD_TYPE_ACTION) 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) { if (self->on_battery) {
switch (self->last_profile) { switch (self->last_profile) {
case PPD_PROFILE_POWER_SAVER: 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; break;
case PPD_PROFILE_BALANCED: case PPD_PROFILE_BALANCED:
target = 1; if (!self->battery_level || self->battery_level >= 30)
target = 0;
else
target = 1;
break; break;
case PPD_PROFILE_PERFORMANCE: case PPD_PROFILE_PERFORMANCE:
target = 0; 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)) if (!set_panel_power (self, target, error))
return FALSE; return FALSE;
self->panel_power_saving = target; self->panel_power_saving = target;
@ -204,6 +216,19 @@ ppd_action_amdgpu_panel_power_power_changed (PpdAction *action,
} }
self->valid_battery = TRUE; 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); 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->probe = ppd_action_amdgpu_panel_power_probe;
driver_class->activate_profile = ppd_action_amdgpu_panel_power_activate_profile; driver_class->activate_profile = ppd_action_amdgpu_panel_power_activate_profile;
driver_class->power_changed = ppd_action_amdgpu_panel_power_power_changed; driver_class->power_changed = ppd_action_amdgpu_panel_power_power_changed;
driver_class->battery_changed = ppd_action_amdgpu_panel_power_battery_changed;
} }
static void static void

View file

@ -1623,18 +1623,34 @@ class Tests(dbusmock.DBusTestCase):
# start upower and try again # start upower and try again
self.stop_daemon() self.stop_daemon()
self.start_dbus_template( _, obj, _ = self.start_dbus_template(
"upower", "upower",
{"DaemonVersion": "0.99", "OnBattery": True}, {"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() 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.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") 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.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") self.assert_sysfs_attr_eventually_is(edp, amdgpu_panel_power_savings, "3")
# add another device that supports the feature # add another device that supports the feature