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

Reply via email to