[PATCH weston v12 09/40] compositor-drm: Move repaint state application to flush

Pekka Paalanen ppaalanen at gmail.com
Wed Jan 17 13:27:43 UTC 2018


On Fri, 10 Nov 2017 14:53:56 +0100
Michael Tretter <m.tretter at pengutronix.de> wrote:

> Hi Daniel,
> 
> On Tue, 26 Sep 2017 18:15:42 +0100, Daniel Stone wrote:
> > Split repaint into two stages, as implied by the grouped-repaint
> > interface: drm_output_repaint generates the repaint state only, and
> > drm_repaint_flush applies it.
> > 
> > This also moves DPMS into output state. Previously, the usual way to
> > DPMS off was that repaint would be called and apply its state,
> > followed by set_dpms being called afterwards to push the DPMS state
> > separately. As this happens before the repaint_flush hook, with no
> > change to DPMS we would set DPMS off, then immediately re-enable the
> > output by posting the repaint. Not ideal.
> > 
> > Moving DPMS application at the same time complicates this patch, but I
> > couldn't find a way to split it; if we keep set_dpms before
> > begin_flush then we break DPMS off, or if we try to move DPMS to
> > output state before using the repaint flush, we get stuck as the
> > repaint hook generates an asynchronous state update, followed
> > immediately by set_dpms generating a synchronous state update.
> > 
> > Signed-off-by: Daniel Stone <daniels at collabora.com>
> > ---
> >  libweston/compositor-drm.c | 313
> > ++++++++++++++++++++++++++++++++++----------- 1 file changed, 240
> > insertions(+), 73 deletions(-)
> > 
> > diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> > index 530b0fd5..6c1c6881 100644
> > --- a/libweston/compositor-drm.c
> > +++ b/libweston/compositor-drm.c

> > @@ -3197,28 +3316,72 @@ drm_set_backlight(struct weston_output
> > *output_base, uint32_t value)
> > backlight_set_brightness(output->backlight, new_brightness); }
> >  
> > +/**
> > + * Power output on or off
> > + *
> > + * The DPMS/power level of an output is used to switch it on or off.
> > This
> > + * is DRM's hook for doing so, which can called either as part of
> > repaint,
> > + * or independently of the repaint loop.
> > + *
> > + * If we are called as part of repaint, we simply set the relevant
> > bit in
> > + * state and return.
> > + */
> >  static void
> >  drm_set_dpms(struct weston_output *output_base, enum dpms_enum level)
> >  {
> >  	struct drm_output *output = to_drm_output(output_base);
> > -	struct weston_compositor *ec = output_base->compositor;
> > -	struct drm_backend *b = to_drm_backend(ec);
> > -	struct drm_property_info *prop =
> > -		&output->props_conn[WDRM_CONNECTOR_DPMS];
> > +	struct drm_backend *b =
> > to_drm_backend(output_base->compositor);
> > +	struct drm_pending_state *pending_state = b->repaint_data;
> > +	struct drm_output_state *state;
> >  	int ret;
> >  
> > -	if (!prop->prop_id)
> > +	/* If we're being called during the repaint loop, then this
> > is
> > +	 * simple: discard any previously-generated state, and
> > create a new
> > +	 * state where we disable everything. When we come to flush,
> > this
> > +	 * will be applied. */
> > +	if (pending_state) {
> > +		/* The repaint loop already sets DPMS on; we don't
> > need to
> > +		 * explicitly set it on here, as it will already
> > happen
> > +		 * whilst applying the repaint state. */
> > +		if (level == WESTON_DPMS_ON)
> > +			return;
> > +
> > +		state = drm_pending_state_get_output(pending_state,
> > output);
> > +		if (state)
> > +			drm_output_state_free(state);
> > +		state = drm_output_get_disable_state(pending_state,
> > output);
> > +		state->dpms = level;
> > +		return;
> > +	}
> > +
> > +	if (output->state_cur->dpms == level)
> >  		return;
> >  
> > -	ret = drmModeConnectorSetProperty(b->drm.fd,
> > output->connector_id,
> > -					  prop->prop_id, level);
> > -	if (ret) {
> > -		weston_log("DRM: DPMS: failed property set for %s\n",
> > -			   output->base.name);
> > +	/* As we throw everything away when disabling, just send us
> > back through
> > +	 * a repaint cycle. */
> > +	if (level == WESTON_DPMS_ON) {
> > +		if (output->dpms_off_pending)
> > +			output->dpms_off_pending = 0;
> > +		weston_output_schedule_repaint(output_base);
> >  		return;
> >  	}
> >  
> > -	output->dpms = level;
> > +	if (output->state_cur->dpms == WESTON_DPMS_OFF)
> > +		return;
> > +
> > +	/* If we've already got a request in the pipeline, then we
> > need to
> > +	 * park our DPMS request until that request has quiesced. */
> > +	if (output->state_last) {
> > +		output->dpms_off_pending = 1;
> > +		return;
> > +	}
> > +
> > +	pending_state = drm_pending_state_alloc(b);
> > +	drm_output_state_duplicate(output->state_cur, pending_state,
> > +				   DRM_OUTPUT_STATE_CLEAR_PLANES);
> > +	ret = drm_pending_state_apply(pending_state);  
> 
> The page flip from this call violates the assertion repaint_state ==
> REPAINT_AWAITING_COMPLETION in weston_output_finish_frame(). The
> FADE_OUT animation seems to mask this case, but I can trigger it by
> directly calling weston_compositor_sleep().

Hi,

when reviewing v14, I have been going through old review comments, and
this one made me think hard. Turning an output DPMS off should not
generate a pageflip event, and since a fresh pending_state is being
allocated and applied here, there should be no other cause for a
pagelip event either.

Finally I realized, the above code is missing
	output_state->dpms = WESTON_DPMS_OFF;

So it's not even turning off the output, it's just committing a normal
state with no framebuffers... changed?

> As a workaround, I check for the repaint_status in
> drm_output_update_complete() and skip the call to
> weston_output_frame_finish(), but I don't really like, because it
> exposes the compositor status to compositor-drm.

v14 has a similar workaround, and I wonder if that is unnecessary when
the turning off is properly synchronous.


Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20180117/ae67e474/attachment.sig>


More information about the wayland-devel mailing list