- U_01-* ... U_20-* : Include patches that haven't made it into the 7.7.1 release. This means almost all commits between xf86-video-ati-7.7.0 and 12d30eeb9711bd2b1609d6bbb74c4a1760596f72. Fixes (bsc#990066). OBS-URL: https://build.opensuse.org/request/show/438260 OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xf86-video-ati?expand=0&rev=51
164 lines
4.7 KiB
Diff
164 lines
4.7 KiB
Diff
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
|
|
}
|
|
|