> -----Original Message----- > From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf > Of Michel Dänzer > Sent: Thursday, September 01, 2016 3:46 AM > To: amd-gfx@lists.freedesktop.org > Subject: [PATCH v2 xf86-video-ati 1/2] Only copy from screen pixmap to > shared pixmap on demand for slave scanout > > From: Michel Dänzer <michel.daen...@amd.com> > > Only copy once for each time we update the corresponding scanout pixmap. > This can significantly reduce the bandwidth usage when there are > frequent updates to the screen pixmap. > > This initial implementation only works when both the master and slave > screens use this driver. > > v2: > * Reduce churn in radeon_prime_scanout_update_handler > * Clear the correct damage in radeon_dirty_update > > Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> [v1] > Signed-off-by: Michel Dänzer <michel.daen...@amd.com>
Reviewed-by: Alex Deucher <alexander.deuc...@amd.com> > --- > src/radeon_kms.c | 82 > +++++++++++++++++++++++++++++++++++++++++++++++--------- > 1 file changed, 69 insertions(+), 13 deletions(-) > > diff --git a/src/radeon_kms.c b/src/radeon_kms.c > index 51f320c..711e84a 100644 > --- a/src/radeon_kms.c > +++ b/src/radeon_kms.c > @@ -440,6 +440,9 @@ redisplay_dirty(PixmapDirtyUpdatePtr dirty, > RegionPtr region) > { > ScrnInfoPtr pScrn = xf86ScreenToScrn(dirty->src- > >drawable.pScreen); > > + if (RegionNil(region)) > + goto out; > + > if (dirty->slave_dst->master_pixmap) > DamageRegionAppend(&dirty->slave_dst->drawable, region); > > @@ -453,6 +456,7 @@ redisplay_dirty(PixmapDirtyUpdatePtr dirty, > RegionPtr region) > if (dirty->slave_dst->master_pixmap) > DamageRegionProcessPending(&dirty->slave_dst->drawable); > > +out: > DamageEmpty(dirty->damage); > } > > @@ -465,6 +469,39 @@ radeon_prime_scanout_update_abort(xf86CrtcPtr > crtc, void *event_data) > } > > void > +radeon_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty) > +{ > + ScreenPtr master_screen = dirty->src->master_pixmap- > >drawable.pScreen; > + PixmapDirtyUpdatePtr ent; > + RegionPtr region; > + > + xorg_list_for_each_entry(ent, &master_screen->pixmap_dirty_list, ent) > { > + if (ent->slave_dst != dirty->src) > + continue; > + > + region = dirty_region(ent); > + redisplay_dirty(ent, region); > + RegionDestroy(region); > + } > +} > + > +static Bool > +master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr > dirty) > +{ > + ScrnInfoPtr master_scrn = xf86ScreenToScrn(dirty->src->master_pixmap- > >drawable.pScreen); > + > + return master_scrn->driverName == scrn->driverName; > +} > + > +static Bool > +slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr > dirty) > +{ > + ScrnInfoPtr slave_scrn = xf86ScreenToScrn(dirty->slave_dst- > >drawable.pScreen); > + > + return slave_scrn->driverName == scrn->driverName; > +} > + > +void > radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, > uint64_t usec, > void *event_data) > { > @@ -477,8 +514,12 @@ > 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) { > - RegionPtr region = dirty_region(dirty); > + RegionPtr region; > > + if (master_has_sync_shared_pixmap(scrn, dirty)) > + radeon_sync_shared_pixmap(dirty); > + > + region = dirty_region(dirty); > redisplay_dirty(dirty, region); > RegionDestroy(region); > break; > @@ -542,26 +583,41 @@ > radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) > } > > static void > -radeon_dirty_update(ScreenPtr screen) > +radeon_dirty_update(ScrnInfoPtr scrn) > { > + ScreenPtr screen = scrn->pScreen; > PixmapDirtyUpdatePtr ent; > - > - if (xorg_list_is_empty(&screen->pixmap_dirty_list)) > - return; > + RegionPtr region; > > xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) { > - RegionPtr region = dirty_region(ent); > + if (screen->isGPU) { > + PixmapDirtyUpdatePtr region_ent = ent; > + > + if (master_has_sync_shared_pixmap(scrn, ent)) { > + ScreenPtr master_screen = ent->src- > >master_pixmap->drawable.pScreen; > > - if (RegionNotEmpty(region)) { > - if (screen->isGPU) > + xorg_list_for_each_entry(region_ent, > &master_screen->pixmap_dirty_list, ent) { > + if (region_ent->slave_dst == ent- > >src) > + break; > + } > + } > + > + region = dirty_region(region_ent); > + > + if (RegionNotEmpty(region)) > radeon_prime_scanout_update(ent); > else > - redisplay_dirty(ent, region); > + DamageEmpty(region_ent->damage); > + > + RegionDestroy(region); > } else { > - DamageEmpty(ent->damage); > - } > + if (slave_has_sync_shared_pixmap(scrn, ent)) > + continue; > > - RegionDestroy(region); > + region = dirty_region(ent); > + redisplay_dirty(ent, region); > + RegionDestroy(region); > + } > } > } > #endif > @@ -861,7 +917,7 @@ static void > RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) > radeon_cs_flush_indirect(pScrn); > > #ifdef RADEON_PIXMAP_SHARING > - radeon_dirty_update(pScreen); > + radeon_dirty_update(pScrn); > #endif > } > > -- > 2.9.3 > > _______________________________________________ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx