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. (Ported from radeon commit 99232f64db52812a843cd616d263d3a6b90eef3d) Signed-off-by: Michel Dänzer <michel.daen...@amd.com> --- src/amdgpu_kms.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c index 0342ef8..5e3d322 100644 --- a/src/amdgpu_kms.c +++ b/src/amdgpu_kms.c @@ -363,6 +363,9 @@ redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region) { ScrnInfoPtr scrn = xf86ScreenToScrn(dirty->src->drawable.pScreen); + if (RegionNil(region)) + goto out; + if (dirty->slave_dst->master_pixmap) DamageRegionAppend(&dirty->slave_dst->drawable, region); @@ -376,6 +379,7 @@ redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region) if (dirty->slave_dst->master_pixmap) DamageRegionProcessPending(&dirty->slave_dst->drawable); +out: DamageEmpty(dirty->damage); } @@ -388,6 +392,39 @@ amdgpu_prime_scanout_update_abort(xf86CrtcPtr crtc, void *event_data) } void +amdgpu_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 amdgpu_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data) { @@ -400,8 +437,12 @@ amdgpu_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)) + amdgpu_sync_shared_pixmap(dirty); + region = dirty_region(dirty); redisplay_dirty(dirty, region); RegionDestroy(region); break; @@ -465,26 +506,42 @@ amdgpu_prime_scanout_update(PixmapDirtyUpdatePtr dirty) drmmode_crtc->scanout_update_pending = TRUE; } -static void amdgpu_dirty_update(ScreenPtr screen) +static void +amdgpu_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)) amdgpu_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 @@ -766,7 +823,7 @@ static void AMDGPUBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) amdgpu_glamor_flush(pScrn); #ifdef AMDGPU_PIXMAP_SHARING - amdgpu_dirty_update(pScreen); + amdgpu_dirty_update(pScrn); #endif } -- 2.9.3 _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx