[PATCH xf86-video-ati 3/3] Track damage accurately for RandR 1.4 slave scanout

Deucher, Alexander Alexander.Deucher at amd.com
Fri Aug 19 15:33:32 UTC 2016


> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces at lists.freedesktop.org] On Behalf
> Of Michel Dänzer
> Sent: Friday, August 19, 2016 6:01 AM
> To: amd-gfx at lists.freedesktop.org
> Subject: [PATCH xf86-video-ati 3/3] Track damage accurately for RandR 1.4
> slave scanout
> 
> From: Michel Dänzer <michel.daenzer at amd.com>
> 
> This further reduces the PCIe bandwidth usage.
> 
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>

For the series:
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  src/radeon_kms.c | 82
> ++++++++++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 71 insertions(+), 11 deletions(-)
> 
> diff --git a/src/radeon_kms.c b/src/radeon_kms.c
> index adf56fd..e353d66 100644
> --- a/src/radeon_kms.c
> +++ b/src/radeon_kms.c
> @@ -382,23 +382,76 @@ static Bool
> RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
>  }
> 
>  #ifdef RADEON_PIXMAP_SHARING
> +static RegionPtr
> +dirty_region(PixmapDirtyUpdatePtr dirty)
> +{
> +	RegionPtr damageregion = DamageRegion(dirty->damage);
> +	RegionPtr dstregion;
> +
> +#ifdef HAS_DIRTYTRACKING_ROTATION
> +	if (dirty->rotation != RR_Rotate_0) {
> +		BoxPtr boxes = RegionRects(damageregion);
> +		int nboxes = RegionNumRects(damageregion);
> +		xRectanglePtr rects = malloc(nboxes * sizeof(*rects));
> +		int dst_w = dirty->slave_dst->drawable.width;
> +		int dst_h = dirty->slave_dst->drawable.height;
> +		int nrects = 0;
> +		BoxRec box;
> +		int i;
> +
> +		for (i = 0; i < nboxes; i++) {
> +			box.x1 = boxes[i].x1;
> +			box.x2 = boxes[i].x2;
> +			box.y1 = boxes[i].y1;
> +			box.y2 = boxes[i].y2;
> +			pixman_f_transform_bounds(&dirty->f_inverse,
> &box);
> +
> +			box.x1 = max(box.x1, 0);
> +			box.y1 = max(box.y1, 0);
> +			box.x2 = min(box.x2, dst_w);
> +			box.y2 = min(box.y2, dst_h);
> +			if (box.x1 >= box.x2 || box.y1 >= box.y2)
> +				continue;
> +
> +			rects[nrects].x = box.x1;
> +			rects[nrects].y = box.y1;
> +			rects[nrects].width = box.x2 - box.x1;
> +			rects[nrects].height = box.y2 - box.y1;
> +			nrects++;
> +		}
> +		dstregion = RegionFromRects(nrects, rects, CT_UNSORTED);
> +	} else
> +#endif
> +	{
> +	    RegionRec pixregion;
> +
> +	    dstregion = RegionDuplicate(damageregion);
> +	    RegionTranslate(dstregion, -dirty->x, -dirty->y);
> +	    PixmapRegionInit(&pixregion, dirty->slave_dst);
> +	    RegionIntersect(dstregion, dstregion, &pixregion);
> +	    RegionUninit(&pixregion);
> +	}
> +
> +	return dstregion;
> +}
> +
>  static void
> -redisplay_dirty(PixmapDirtyUpdatePtr dirty)
> +redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region)
>  {
>  	ScrnInfoPtr pScrn = xf86ScreenToScrn(dirty->src-
> >drawable.pScreen);
> -	RegionRec pixregion;
> 
> -	PixmapRegionInit(&pixregion, dirty->slave_dst);
> -	DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
> +	if (dirty->slave_dst->master_pixmap)
> +	    DamageRegionAppend(&dirty->slave_dst->drawable, region);
> +
>  #ifdef HAS_DIRTYTRACKING_ROTATION
>  	PixmapSyncDirtyHelper(dirty);
>  #else
> -	PixmapSyncDirtyHelper(dirty, &pixregion);
> +	PixmapSyncDirtyHelper(dirty, region);
>  #endif
> 
>  	radeon_cs_flush_indirect(pScrn);
> -	DamageRegionProcessPending(&dirty->slave_dst->drawable);
> -	RegionUninit(&pixregion);
> +	if (dirty->slave_dst->master_pixmap)
> +	    DamageRegionProcessPending(&dirty->slave_dst->drawable);
> 
>  	DamageEmpty(dirty->damage);
>  }
> @@ -424,7 +477,10 @@
> radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame,
> uint64_t u
>      xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
>  	if (dirty->src == scanoutpix &&
>  	    dirty->slave_dst == drmmode_crtc->scanout[0].pixmap) {
> -	    redisplay_dirty(dirty);
> +	    RegionPtr region = dirty_region(dirty);
> +
> +	    redisplay_dirty(dirty, region);
> +	    RegionDestroy(region);
>  	    break;
>  	}
>      }
> @@ -488,20 +544,24 @@
> radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
>  static void
>  radeon_dirty_update(ScreenPtr screen)
>  {
> -	RegionPtr region;
>  	PixmapDirtyUpdatePtr ent;
> 
>  	if (xorg_list_is_empty(&screen->pixmap_dirty_list))
>  		return;
> 
>  	xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
> -		region = DamageRegion(ent->damage);
> +		RegionPtr region = dirty_region(ent);
> +
>  		if (RegionNotEmpty(region)) {
>  			if (screen->isGPU)
>  				radeon_prime_scanout_update(ent);
>  			else
> -				redisplay_dirty(ent);
> +				redisplay_dirty(ent, region);
> +		} else {
> +			DamageEmpty(ent->damage);
>  		}
> +
> +		RegionDestroy(region);
>  	}
>  }
>  #endif
> --
> 2.9.3
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list