Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Maintenance:5844
xf86-video-ati.openSUSE_Leap_42.2_Update
U_16-Only-copy-from-screen-pixmap-to-shared-pix...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File U_16-Only-copy-from-screen-pixmap-to-shared-pixmap-on-demand-for-slave-scanout.patch of Package xf86-video-ati.openSUSE_Leap_42.2_Update
From: Michel Dänzer <michel.daenzer@amd.com> Date: Tue Dec 1 17:58:13 2015 +0900 Subject: [PATCH 16/20]Only copy from screen pixmap to shared pixmap on demand for slave scanout Patch-mainline: Upstream Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati Git-commit: 99232f64db52812a843cd616d263d3a6b90eef3d References: bsc#990066 Signed-off-by: Max Staudt <mstaudt@suse.de> 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.deucher@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 }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor