[PATCH weston v4 1/3] compositor: If the output is inhibited, don't idle it off
Bryce Harrington
bryce at osg.samsung.com
Wed Aug 17 05:09:50 UTC 2016
On Tue, Aug 16, 2016 at 09:51:01AM -0500, Derek Foreman wrote:
> On 15/08/16 09:33 PM, Bryce Harrington wrote:
> > On Mon, Aug 15, 2016 at 06:57:52PM -0500, Derek Foreman wrote:
> >> On 10/08/16 07:25 PM, Bryce Harrington wrote:
> >>> 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 at osg.samsung.com>
> >>> ---
> >>> libweston/compositor.c | 57 ++++++++++++++++++++++++++++++++++++++++++++------
> >>> libweston/compositor.h | 10 +++++++++
> >>> 2 files changed, 61 insertions(+), 6 deletions(-)
> >>>
> >>> diff --git a/libweston/compositor.c b/libweston/compositor.c
> >>> index b17c76d..aa14504 100644
> >>> --- a/libweston/compositor.c
> >>> +++ b/libweston/compositor.c
> >>> @@ -485,6 +485,8 @@ weston_surface_create(struct weston_compositor *compositor)
> >>>
> >>> wl_list_init(&surface->pointer_constraints);
> >>>
> >>> + surface->inhibit_idling = false;
> >>> +
> >>> 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);
> >>> }
> >>>
> >>> +/** 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
> >>> output_repaint_timer_handler(void *data)
> >>> {
> >>> struct weston_output *output = data;
> >>> struct weston_compositor *compositor = output->compositor;
> >>> + uint32_t inhibited_outputs_mask = weston_compositor_inhibited_outputs(compositor);
> >>>
> >>> if (output->repaint_needed &&
> >>> - compositor->state != WESTON_COMPOSITOR_SLEEPING &&
> >>
> >> I don't like that this patch changes the meaning of
> >> "WESTON_COMPOSITOR_SLEEPING" - should at least make an effort to update
> >> all relevant comments such as the one immediately before
> >> "weston_compositor_sleep" and the one in the enum definition in
> >> compositor.h...
> >
> > I'm not sure what you mean?
>
> Well, as a quick example, in compositor.h, the comment after
> WESTON_COMPOSITOR_SLEEPING is:
> /* same as offscreen, but also set dpms to off */
>
> This isn't accurate anymore as it's possible for us to be
> WESTON_COMPOSITOR_SLEEPING and not actually have any displays with dpms
> off at all, isn't it?
Yes that's true, if there are idle inhibits being honored, some or all
of the displays would not be dpms'd off.
> It becomes very confusing to figure out what's going on when "sleeping"
> doesn't necessarily mean anything is asleep at all. Maybe a new state
> should be introduced, but at a minimum all of the comments related to
> sleeping should be updated to be in sync with the new behaviour.
Do you mean rename WESTON_COMPOSITOR_SLEEPING to something more
descriptive, or to actually split SLEEP state into two different states?
If the former, what would be a better term than "sleeping" in this case?
WESTON_COMPOSITOR_INACTIVE? _STOPPED? ... _DROWSY?
Or, for just updating the comments, would tacking on "...where
applicable" be adequate, or would you want something more elaborate?
> >>> compositor->state != WESTON_COMPOSITOR_OFFSCREEN &&
> >>> + (compositor->state != WESTON_COMPOSITOR_SLEEPING
> >>> + || inhibited_outputs_mask & (1 << output->id)) &&
> >>> weston_output_repaint(output) == 0)
> >>> return 0;
> >>>
> >>> @@ -2450,9 +2479,15 @@ weston_output_schedule_repaint(struct weston_output *output)
> >>> {
> >>> struct weston_compositor *compositor = output->compositor;
> >>> struct wl_event_loop *loop;
> >>> + uint32_t inhibited_outputs_mask = weston_compositor_inhibited_outputs(compositor);
> >>>
> >>> - if (compositor->state == WESTON_COMPOSITOR_SLEEPING ||
> >>> - compositor->state == WESTON_COMPOSITOR_OFFSCREEN)
> >>> + /* If we're offscreen, or if we're sleeping and the monitor
> >>> + * 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;
> >>>
> >>> if (!output->repaint_needed)
> >>> @@ -3859,10 +3894,20 @@ weston_compositor_dpms(struct weston_compositor *compositor,
> >>> enum dpms_enum state)
> >>> {
> >>
> >> The doxy block before this function has now become wrong, hasn't it?
> >
> > Not sure exactly what you mean by 'wrong', but I suppose it could
> > benefit from being updated to mention that idled outputs won't be
> > toggled off. Is that what you're referring to?
>
> Well, the doxy says "Set a DPMS mode on all of the compositor's outputs"
>
> After the patch it doesn't do that, it conditionally turns off monitors
> that aren't being governed by a blanker inhibitor.
Ok, does this strike you as better?
/** Apply a DPMS mode to the compositor's outputs.
*
* Outputs may skip setting the DPMS state if they are being used to
* display an surface that is requesting idle behaviors be inhibited.
*
* \param compositor The compositor instance
* \param state The DPMS state the outputs will be set to
*/
> >>> struct weston_output *output;
> >>> + struct weston_view *view;
> >>> + uint32_t inhibited_outputs_mask = weston_compositor_inhibited_outputs(compositor);
> >>>
> >>> - wl_list_for_each(output, &compositor->output_list, link)
> >>> - if (output->set_dpms)
> >>> - output->set_dpms(output, state);
> >>> + 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;
> >>> +
> >>> + output->set_dpms(output, state);
> >>> + }
> >>> }
> >>>
> >>> /** Restores the compositor to active status
> >>> diff --git a/libweston/compositor.h b/libweston/compositor.h
> >>> index 0133084..3a9a098 100644
> >>> --- a/libweston/compositor.h
> >>> +++ b/libweston/compositor.h
> >>> @@ -1140,6 +1140,14 @@ struct weston_surface {
> >>>
> >>> /* An list of per seat 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;
> >>
> >> I find this a bit unclear - "idling" doesn't feel properly descriptive,
> >> and the comment gives me the impression that an "idle inhibit surface"
> >> will be redrawn even if it's obscured - does that mean surface frame
> >> events for the surface will be generated even if it's not visible in any
> >> way?
> >
> > Suggestions? If the surface in in the view_list and assigned to an
> > output, then the idle inhibition will be honored.
>
> I guess I'm fine with it, no need to bike shed this point.
Ok.
> >> Also, what's the bit about the surface being considered active by the
> >> shell mean?
> >
> > That functionality got axed in an earlier review, this bit of doc was
> > missed. Just ignore everything after "while".
>
> Ah, ok, thought that might be the case. Would be good to see a patch
> with the text fixed.
I've applied this fix locally. I can repost the patchset once the
remainder of your review comments are resolved (and rebased to
trunk... which is proving to be a bit of a head scratcher due to the
libweston-desktop port.)
Thanks again for reviewing!
Bryce
> Thanks,
> Derek
>
> > Thanks,
> > Bryce
> >
> >> Thanks,
> >> Derek
> >>
> >>> +
> >>> };
> >>>
> >>> struct weston_subsurface {
> >>> @@ -1316,6 +1324,8 @@ void
> >>> weston_output_schedule_repaint(struct weston_output *output);
> >>> void
> >>> weston_output_damage(struct weston_output *output);
> >>> +uint32_t
> >>> +weston_compositor_inhibited_outputs(struct weston_compositor *compositor);
> >>> void
> >>> weston_compositor_schedule_repaint(struct weston_compositor *compositor);
> >>> void
> >>>
More information about the wayland-devel
mailing list