> -----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