compositor: Add internal support to track idle inhibition requests

Adds a helper routine weston_output_inhibited_outputs() which returns a
mask of outputs that should inhibit screen idling.

Use this routine to check for inhibiting outputs for handling of idle
behaviors in core:  In sleep mode, only halt repainting outputs that
don't have valid inhibits.  Don't send these monitors DPMS off commands
either, if the system would otherwise be powering them down.

Signed-off-by: Bryce Harrington <bryce@osg.samsung.com>

v5: Drop unused view variable
dev
Bryce Harrington 8 years ago
parent fde5adbedb
commit f8300c87d5
  1. 54
      libweston/compositor.c
  2. 10
      libweston/compositor.h

@ -485,6 +485,8 @@ weston_surface_create(struct weston_compositor *compositor)
wl_list_init(&surface->pointer_constraints); wl_list_init(&surface->pointer_constraints);
surface->inhibit_idling = false;
return surface; return surface;
} }
@ -2320,15 +2322,42 @@ weston_output_schedule_repaint_reset(struct weston_output *output)
TL_POINT("core_repaint_exit_loop", TLP_OUTPUT(output), TLP_END); TL_POINT("core_repaint_exit_loop", TLP_OUTPUT(output), TLP_END);
} }
/** Retrieves a mask of outputs that should inhibit screensaving
*
* \param compositor The compositor instance.
* \return An output mask indicating the ids of all inhibiting outputs
*
* Checks for surfaces whose clients have requested that they
* disable the screenserver and display powersaving. Note
* the output ids for these surfaces.
*/
WL_EXPORT uint32_t
weston_compositor_inhibited_outputs(struct weston_compositor *compositor)
{
struct weston_view *view;
uint32_t inhibited_outputs_mask = 0;
wl_list_for_each(view, &compositor->view_list, link) {
/* Does the view's surface inhibit this output? */
if (!view->surface->inhibit_idling)
continue;
inhibited_outputs_mask |= view->output_mask;
}
return inhibited_outputs_mask;
}
static int static int
output_repaint_timer_handler(void *data) output_repaint_timer_handler(void *data)
{ {
struct weston_output *output = data; struct weston_output *output = data;
struct weston_compositor *compositor = output->compositor; struct weston_compositor *compositor = output->compositor;
uint32_t inhibited_outputs_mask = weston_compositor_inhibited_outputs(compositor);
if (output->repaint_needed && if (output->repaint_needed &&
compositor->state != WESTON_COMPOSITOR_SLEEPING &&
compositor->state != WESTON_COMPOSITOR_OFFSCREEN && compositor->state != WESTON_COMPOSITOR_OFFSCREEN &&
(compositor->state != WESTON_COMPOSITOR_SLEEPING
|| inhibited_outputs_mask & (1 << output->id)) &&
weston_output_repaint(output) == 0) weston_output_repaint(output) == 0)
return 0; return 0;
@ -2450,9 +2479,15 @@ weston_output_schedule_repaint(struct weston_output *output)
{ {
struct weston_compositor *compositor = output->compositor; struct weston_compositor *compositor = output->compositor;
struct wl_event_loop *loop; struct wl_event_loop *loop;
uint32_t inhibited_outputs_mask = weston_compositor_inhibited_outputs(compositor);
if (compositor->state == WESTON_COMPOSITOR_SLEEPING || /* If we're offscreen, or if we're sleeping and the monitor
compositor->state == WESTON_COMPOSITOR_OFFSCREEN) * isn't currently being inhibited by an active surface, then
* skip repainting.
*/
if (compositor->state == WESTON_COMPOSITOR_OFFSCREEN ||
(compositor->state == WESTON_COMPOSITOR_SLEEPING &&
!(inhibited_outputs_mask & (1 << output->id))))
return; return;
if (!output->repaint_needed) if (!output->repaint_needed)
@ -3902,10 +3937,19 @@ weston_compositor_dpms(struct weston_compositor *compositor,
enum dpms_enum state) enum dpms_enum state)
{ {
struct weston_output *output; struct weston_output *output;
uint32_t inhibited_outputs_mask = weston_compositor_inhibited_outputs(compositor);
wl_list_for_each(output, &compositor->output_list, link) {
if (!output->set_dpms)
continue;
/* If output is idle-inhibited, don't toggle to any DPMS state except ON. */
if (state != WESTON_DPMS_ON &&
inhibited_outputs_mask & (1 << output->id))
continue;
wl_list_for_each(output, &compositor->output_list, link)
if (output->set_dpms)
output->set_dpms(output, state); output->set_dpms(output, state);
}
} }
/** Restores the compositor to active status /** Restores the compositor to active status

@ -1155,6 +1155,14 @@ struct weston_surface {
/* An list of per seat pointer constraints. */ /* An list of per seat pointer constraints. */
struct wl_list pointer_constraints; struct wl_list pointer_constraints;
/*
* Indicates the surface prefers no screenblanking, screensaving,
* or other automatic obscurement to kick in while the surface is
* considered "active" by the shell.
*/
bool inhibit_idling;
}; };
struct weston_subsurface { struct weston_subsurface {
@ -1331,6 +1339,8 @@ void
weston_output_schedule_repaint(struct weston_output *output); weston_output_schedule_repaint(struct weston_output *output);
void void
weston_output_damage(struct weston_output *output); weston_output_damage(struct weston_output *output);
uint32_t
weston_compositor_inhibited_outputs(struct weston_compositor *compositor);
void void
weston_compositor_schedule_repaint(struct weston_compositor *compositor); weston_compositor_schedule_repaint(struct weston_compositor *compositor);
void void

Loading…
Cancel
Save