powersave - document som things and add screen blank override for pwrsv

add a screen power save mode than overrides regular powersave (bug is
subordinat to forced power save).
This commit is contained in:
Carsten Haitzler 2020-11-12 15:28:54 +00:00
parent b386d7b911
commit e5bf0d66eb
6 changed files with 105 additions and 50 deletions

View File

@ -12,6 +12,8 @@ struct _E_Powersave_Sleeper
{
Ecore_Pipe *pipe;
int fd;
Eina_Bool go E_BITFIELD;
Eina_Bool free_requested E_BITFIELD;
};
/* local subsystem functions */
@ -30,11 +32,13 @@ static Eina_List *deferred_actions = NULL;
static Ecore_Timer *deferred_timer = NULL;
static E_Powersave_Mode powersave_mode = E_POWERSAVE_MODE_LOW;
static E_Powersave_Mode powersave_mode_force = E_POWERSAVE_MODE_NONE;
static E_Powersave_Mode powersave_mode_screen = E_POWERSAVE_MODE_NONE;
static double defer_time = 5.0;
static Eina_Bool powersave_force = EINA_FALSE;
static Eina_List *powersave_sleepers = NULL;
static Eina_Bool powersave_deferred_suspend = EINA_FALSE;
static Eina_Bool powersave_deferred_hibernate = EINA_FALSE;
static Eina_Bool powersave_screen = EINA_FALSE;
/* externally accessible functions */
EINTERN int
@ -99,6 +103,7 @@ e_powersave_mode_set(E_Powersave_Mode mode)
else if (mode > e_config->powersave.max) mode = e_config->powersave.max;
if (powersave_mode == mode) return;
printf("PWSAVE %i/%i\n", (int)mode, (int)E_POWERSAVE_MODE_FREEZE);
powersave_mode = mode;
if (powersave_force) return;
@ -110,6 +115,7 @@ E_API E_Powersave_Mode
e_powersave_mode_get(void)
{
if (powersave_force) return powersave_mode_force;
if (powersave_screen) return powersave_mode_screen;
return powersave_mode;
}
@ -117,6 +123,7 @@ E_API void
e_powersave_mode_force(E_Powersave_Mode mode)
{
if (mode == powersave_mode_force) return;
printf("PWSAVE FORCE %i/%i\n", (int)mode, (int)E_POWERSAVE_MODE_FREEZE);
powersave_force = EINA_TRUE;
powersave_mode_force = mode;
_e_powersave_event_change_send(powersave_mode_force);
@ -127,6 +134,7 @@ E_API void
e_powersave_mode_unforce(void)
{
if (!powersave_force) return;
printf("PWSAVE UNFORCE\n");
powersave_force = EINA_FALSE;
if (powersave_mode_force != powersave_mode)
{
@ -136,6 +144,34 @@ e_powersave_mode_unforce(void)
powersave_mode_force = E_POWERSAVE_MODE_NONE;
}
E_API void
e_powersave_mode_screen_set(E_Powersave_Mode mode)
{
if (mode == powersave_mode_screen) return;
printf("PWSAVE SCREEN SET %i/%i\n", (int)mode, (int)E_POWERSAVE_MODE_FREEZE);
powersave_screen = EINA_TRUE;
powersave_mode_screen = mode;
if (!powersave_force)
{
_e_powersave_event_change_send(powersave_mode_screen);
_e_powersave_mode_eval();
}
}
E_API void
e_powersave_mode_screen_unset(void)
{
if (!powersave_screen) return;
printf("PWSAVE SCREEN UNSET\n");
powersave_screen = EINA_FALSE;
if ((!powersave_force) && (powersave_mode_screen != powersave_mode))
{
_e_powersave_event_change_send(powersave_screen);
_e_powersave_mode_eval();
}
powersave_mode_screen = E_POWERSAVE_MODE_NONE;
}
E_API E_Powersave_Sleeper *
e_powersave_sleeper_new(void)
{
@ -159,12 +195,12 @@ e_powersave_sleeper_free(E_Powersave_Sleeper *sleeper)
{
if (!sleeper) return;
ecore_pipe_del(sleeper->pipe);
powersave_sleepers = eina_list_remove(powersave_sleepers, sleeper);
eina_freeq_ptr_add(eina_freeq_main_get(), sleeper, free, sizeof(*sleeper));
powersave_sleepers = eina_list_remove(powersave_sleepers, sleeper);
}
E_API void
e_powersave_sleeper_sleep(E_Powersave_Sleeper *sleeper, int poll_interval)
e_powersave_sleeper_sleep(E_Powersave_Sleeper *sleeper, int poll_interval, Eina_Bool allow_save)
{
double timf;
unsigned int tim;
@ -174,8 +210,20 @@ e_powersave_sleeper_sleep(E_Powersave_Sleeper *sleeper, int poll_interval)
char buf[1] = { 1 };
if (!sleeper) return;
if (e_powersave_mode_get() == E_POWERSAVE_MODE_FREEZE) timf = 3600;
else timf = (double)poll_interval / 8.0;
if (allow_save)
{
if (e_powersave_mode_get() == E_POWERSAVE_MODE_FREEZE)
timf = 3600.0;
else if (e_powersave_mode_get() == E_POWERSAVE_MODE_EXTREME)
timf = (double)poll_interval / 2.0;
else if (e_powersave_mode_get() == E_POWERSAVE_MODE_HIGH)
timf = (double)poll_interval / 4.0;
else
timf = (double)poll_interval / 8.0;
}
else
timf = (double)poll_interval / 8.0;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&exfds);
@ -191,14 +239,13 @@ e_powersave_sleeper_sleep(E_Powersave_Sleeper *sleeper, int poll_interval)
{
if (read(sleeper->fd, buf, 1) < 0)
fprintf(stderr, "%s: ERROR READING FROM FD\n", __func__);
if (buf[0] == 1) // was woken up by mainloop to do another poll
return;
}
else if (ret == 0)
{
return;
}
}
}
E_API void
e_powersave_defer_suspend(void)
@ -331,8 +378,7 @@ _e_powersave_event_change_send(E_Powersave_Mode mode)
{
E_Event_Powersave_Update *ev;
printf("CHANGE PW SAVE MODE TO %i / %i\n",
(int)mode, E_POWERSAVE_MODE_EXTREME);
printf("PWSAVE TO %i/%i\n", (int)mode, (int)E_POWERSAVE_MODE_FREEZE);
ev = E_NEW(E_Event_Powersave_Update, 1);
ev->mode = mode;
ecore_event_add(E_EVENT_POWERSAVE_UPDATE, ev, _e_powersave_event_update_free, NULL);

View File

@ -2,12 +2,12 @@
typedef enum _E_Powersave_Mode
{
E_POWERSAVE_MODE_NONE,
E_POWERSAVE_MODE_LOW,
E_POWERSAVE_MODE_MEDIUM,
E_POWERSAVE_MODE_HIGH,
E_POWERSAVE_MODE_EXTREME,
E_POWERSAVE_MODE_FREEZE
E_POWERSAVE_MODE_NONE, // no powersaving
E_POWERSAVE_MODE_LOW, // normal power management - AC plugged in
E_POWERSAVE_MODE_MEDIUM, // lots of battery available but not on AC
E_POWERSAVE_MODE_HIGH, // have enough battery but good to save powwr
E_POWERSAVE_MODE_EXTREME, // low on battery save more
E_POWERSAVE_MODE_FREEZE // really try and do as little as possible
} E_Powersave_Mode;
typedef struct _E_Powersave_Deferred_Action E_Powersave_Deferred_Action;
@ -29,19 +29,32 @@ struct _E_Event_Powersave_Update
EINTERN int e_powersave_init(void);
EINTERN int e_powersave_shutdown(void);
// do this thing somw time later - how much later depends on power save mode
// this is done in the mainloop
E_API E_Powersave_Deferred_Action *e_powersave_deferred_action_add(void (*func) (void *data), const void *data);
E_API void e_powersave_deferred_action_del(E_Powersave_Deferred_Action *pa);
E_API void e_powersave_mode_set(E_Powersave_Mode mode);
E_API E_Powersave_Mode e_powersave_mode_get(void);
// force is used by e's system core to use "connected standby" where the system
// should be aslpee but not regular suspend - soits still alive but it needs
// to try and be as idle as possible
E_API void e_powersave_mode_force(E_Powersave_Mode mode);
E_API void e_powersave_mode_unforce(void);
E_API E_Powersave_Sleeper *e_powersave_sleeper_new(void);
E_API void e_powersave_sleeper_free(E_Powersave_Sleeper *sleeper);
// used by screen saving/blanking to set a specific power mode when screens
// are off/not visible
E_API void e_powersave_mode_screen_set(E_Powersave_Mode mode);
E_API void e_powersave_mode_screen_unset(void);
E_API void e_powersave_defer_suspend(void);
E_API void e_powersave_defer_hibernate(void);
E_API void e_powersave_defer_cancel(void);
// sleepers are meant to be used in threads polling for things. create in
// mainloop then use and sleep in a thread,
E_API E_Powersave_Sleeper *e_powersave_sleeper_new(void);
E_API void e_powersave_sleeper_free(E_Powersave_Sleeper *sleeper);
// the below function is INTENDED to be called from a thread
E_API void e_powersave_sleeper_sleep(E_Powersave_Sleeper *sleeper, int poll_interval);
E_API void e_powersave_sleeper_sleep(E_Powersave_Sleeper *sleeper, int poll_interval, Eina_Bool allow_save);
/* FIXME: in the powersave system add things like pre-loading entire files
* int memory for pre-caching to avoid disk spinup, when in an appropriate
@ -53,12 +66,5 @@ E_API void e_powersave_sleeper_sleep(E_Powersave_Sleeper
/* FIXME: in powersave mode also reduce ecore timer precision, so timers
* will be dispatched together and system will wakeup less. */
/* FIXME: in powersave mode also add the ability to change screenblanker
* preferences when in powersave mode as well as check in the screensaver
* has kicked in */
/* FIXME: in powersave mode also if screenblanker has kicked in be able to
* auto-suspend etc. etc. */
#endif
#endif

View File

@ -237,6 +237,7 @@ _e_screensaver_handler_desk_show_cb(void *data EINA_UNUSED, int type EINA_UNUSED
static Eina_Bool
_e_screensaver_idle_timer_cb(void *d EINA_UNUSED)
{
e_powersave_mode_screen_set(E_POWERSAVE_MODE_FREEZE);
ecore_event_add(E_EVENT_SCREENSAVER_ON, NULL, NULL, NULL);
screensaver_idle_timer = NULL;
return EINA_FALSE;
@ -452,9 +453,12 @@ e_screensaver_eval(Eina_Bool saver_on)
if (!_screensaver_ignore)
{
if (!e_screensaver_on_get())
{
e_powersave_mode_screen_set(E_POWERSAVE_MODE_FREEZE);
ecore_event_add(E_EVENT_SCREENSAVER_ON, NULL, NULL, NULL);
}
}
}
return;
}
else
@ -485,6 +489,7 @@ e_screensaver_eval(Eina_Bool saver_on)
{
if (e_screensaver_on_get())
{
e_powersave_mode_screen_unset();
e_screensaver_update();
ecore_event_add(E_EVENT_SCREENSAVER_OFF, NULL, NULL, NULL);
}

View File

@ -988,8 +988,6 @@ _e_sys_cb_acpi_event(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
E_Event_Acpi *ev = event;
if (e_powersave_mode_get() == E_POWERSAVE_MODE_FREEZE)
{
if (((ev->type == E_ACPI_TYPE_LID) &&
(ev->status == E_ACPI_LID_OPEN)) ||
(ev->type == E_ACPI_TYPE_POWER) ||
@ -1001,11 +999,10 @@ _e_sys_cb_acpi_event(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
_e_sys_acpi_handler = NULL;
}
e_powersave_mode_unforce();
ecore_timer_add(1.0, _e_sys_resume_delay, NULL);
ecore_timer_add(0.5, _e_sys_resume_delay, NULL);
// XXX: need some way of, at the system level, restoring
// system and devices back to running normally
}
}
return ECORE_CALLBACK_PASS_ON;
}

View File

@ -1323,7 +1323,7 @@ static void
_cpufreq_cb_frequency_check_done(void *data, Ecore_Thread *th EINA_UNUSED)
{
Thread_Config *thc = data;
e_powersave_sleeper_free(thc->sleeper);
if (thc->sleeper) e_powersave_sleeper_free(thc->sleeper);
free(thc);
}
@ -1342,7 +1342,7 @@ _cpufreq_cb_frequency_check_main(void *data, Ecore_Thread *th)
else
_cpufreq_status_free(status);
if (ecore_thread_check(th)) break;
e_powersave_sleeper_sleep(thc->sleeper, thc->interval);
e_powersave_sleeper_sleep(thc->sleeper, thc->interval, EINA_TRUE);
}
}

View File

@ -51,7 +51,7 @@ static void
_temperature_thread_free(Tempthread *tth)
{
eina_stringshare_del(tth->sensor_name);
e_powersave_sleeper_free(tth->sleeper);
if (tth->sleeper) e_powersave_sleeper_free(tth->sleeper);
free(tth->extn);
free(tth);
}
@ -260,6 +260,7 @@ _temperature_face_shutdown(const Eina_Hash *hash EINA_UNUSED, const void *key EI
Config_Face *inst;
inst = hdata;
// XXX: sleeper free
if (inst->th) ecore_thread_cancel(inst->th);
if (inst->sensor_name) eina_stringshare_del(inst->sensor_name);
if (inst->id) eina_stringshare_del(inst->id);
@ -294,7 +295,7 @@ _temperature_check_main(void *data, Ecore_Thread *th)
if (ptemp != temp) ecore_thread_feedback(th, (void *)((long)temp));
ptemp = temp;
if (ecore_thread_check(th)) break;
e_powersave_sleeper_sleep(tth->sleeper, tth->poll_interval);
e_powersave_sleeper_sleep(tth->sleeper, tth->poll_interval, EINA_TRUE);
}
}