[PATCH v2 2/2] drm: rcar-du: Clip planes to screen boundaries

Laurent Pinchart laurent.pinchart at ideasonboard.com
Sun Nov 26 11:18:46 UTC 2017


Hi Ville,

On Thursday, 16 November 2017 19:04:26 EET Ville Syrjälä wrote:
> On Mon, Nov 13, 2017 at 10:47:00AM +0200, Laurent Pinchart wrote:
> > Unlike the KMS API, the hardware doesn't support planes exceeding the
> > screen boundaries or planes being located fully off-screen. We need to
> > clip plane coordinates to support the use case.
> > 
> > Fortunately the DRM core offers the drm_plane_helper_check_state()
> > helper that valides the scaling factor and clips the plane coordinates.
> > Use it to implement the plane atomic check and use the clipped source
> > and destination rectangles from the plane state instead of the unclipped
> > source and CRTC coordinates to configure the device.
> > 
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas at ideasonboard.com>
> > ---
> > 
> >  drivers/gpu/drm/rcar-du/rcar_du_crtc.c  |  3 ++-
> >  drivers/gpu/drm/rcar-du/rcar_du_plane.c | 37 +++++++++++++++++++++-------
> >  drivers/gpu/drm/rcar-du/rcar_du_vsp.c   | 10 ++++++---
> >  3 files changed, 39 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index b492063a6e1f..5685d5af6998
> > 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> > @@ -319,7 +319,8 @@ static void rcar_du_crtc_update_planes(struct
> > rcar_du_crtc *rcrtc)> 
> >  		struct rcar_du_plane *plane = &rcrtc->group->planes[i];
> >  		unsigned int j;
> > 
> > -		if (plane->plane.state->crtc != &rcrtc->crtc)
> > +		if (plane->plane.state->crtc != &rcrtc->crtc ||
> > +		    !plane->plane.state->visible)
> > 
> >  			continue;
> >  		
> >  		/* Insert the plane in the sorted planes array. */
> > 
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> > b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index
> > 4f076c364f25..9cf02b44902d 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> > @@ -570,16 +570,39 @@ int __rcar_du_plane_atomic_check(struct drm_plane
> > *plane,
> >  				 const struct rcar_du_format_info **format)
> >  {
> >  	struct drm_device *dev = plane->dev;
> > +	struct drm_crtc_state *crtc_state;
> > +	struct drm_rect clip;
> > +	int ret;
> > 
> > -	if (!state->fb || !state->crtc) {
> > +	if (!state->crtc) {
> > +		/*
> > +		 * The visible field is not reset by the DRM core but only
> > +		 * updated by drm_plane_helper_check_state(), set it manually.
> > +		 */
> > +		state->visible = false;
> >  		*format = NULL;
> >  		return 0;
> > -	}
> > +	};
> 
> spurious ;

Oops, my bad, I'll fix that.

> > -	if (state->src_w >> 16 != state->crtc_w ||
> > -	    state->src_h >> 16 != state->crtc_h) {
> > -		dev_dbg(dev->dev, "%s: scaling not supported\n", __func__);
> > -		return -EINVAL;
> > +	crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
> > +	if (IS_ERR(crtc_state))
> > +		return PTR_ERR(crtc_state);
> > +
> > +	clip.x1 = 0;
> > +	clip.y1 = 0;
> > +	clip.x2 = crtc_state->adjusted_mode.hdisplay;
> > +	clip.y2 = crtc_state->adjusted_mode.vdisplay;
> 
> crtc_state->mode would be more correct. I messed that up too in my
> recent vmwgfx fix [1]. But this should probably work just as well
> if you don't have a crtc scaler in your pipeline.

Indeed, my CRTC can't scale, so this works, but I'll fix it nonetheless.

> Also you may want to leave the clip empty when !crtc_state->enable.
> That way you'll be guaranteed to get visible==false. The helper is
> currently a bit broken wrt. the crtc->enable vs. crtc_state->enable.
> I've fixed that in [1] as well but those patches haven't been pushed
> yet.

[1] has landed in drm-misc, I'll rebase this series on top of that, and will 
send a pull request when drm-misc gets merged in Dave's tree.

> After getting that stuff in, I'm going to attempt moving this
> clipping stuff entirely into the helper to avoid these kinds of
> mistakes in the future.

Good idea, thanks.

> [1] https://patchwork.freedesktop.org/series/33001/
> 
> > +
> > +	ret = drm_plane_helper_check_state(state, &clip,
> > +					   DRM_PLANE_HELPER_NO_SCALING,
> > +					   DRM_PLANE_HELPER_NO_SCALING,
> > +					   true, true);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	if (!state->visible) {
> > +		*format = NULL;
> > +		return 0;
> >  	}
> >  	
> >  	*format = rcar_du_format_info(state->fb->format->format);

-- 
Regards,

Laurent Pinchart



More information about the dri-devel mailing list