- 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
145 lines
4.2 KiB
Diff
145 lines
4.2 KiB
Diff
From: Michel Dänzer <michel.daenzer@amd.com>
|
|
Date: Mon Nov 30 18:54:12 2015 +0900
|
|
Subject: [PATCH 14/20]Track damage accurately for RandR 1.4 slave scanout
|
|
Patch-mainline: Upstream
|
|
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
|
|
Git-commit: b0867063abb197b9134166706d99fcbe5f204bb5
|
|
References: bsc#990066
|
|
Signed-off-by: Max Staudt <mstaudt@suse.de>
|
|
|
|
This further reduces the PCIe bandwidth usage.
|
|
|
|
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
|
---
|
|
src/radeon_kms.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++--------
|
|
1 file changed, 71 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
|
|
index 07ba362..c10fb42 100644
|
|
--- a/src/radeon_kms.c
|
|
+++ b/src/radeon_kms.c
|
|
@@ -382,23 +382,76 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
|
|
}
|
|
|
|
#ifdef RADEON_PIXMAP_SHARING
|
|
+static RegionPtr
|
|
+dirty_region(PixmapDirtyUpdatePtr dirty)
|
|
+{
|
|
+ RegionPtr damageregion = DamageRegion(dirty->damage);
|
|
+ RegionPtr dstregion;
|
|
+
|
|
+#ifdef HAS_DIRTYTRACKING_ROTATION
|
|
+ if (dirty->rotation != RR_Rotate_0) {
|
|
+ BoxPtr boxes = RegionRects(damageregion);
|
|
+ int nboxes = RegionNumRects(damageregion);
|
|
+ xRectanglePtr rects = malloc(nboxes * sizeof(*rects));
|
|
+ int dst_w = dirty->slave_dst->drawable.width;
|
|
+ int dst_h = dirty->slave_dst->drawable.height;
|
|
+ int nrects = 0;
|
|
+ BoxRec box;
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < nboxes; i++) {
|
|
+ box.x1 = boxes[i].x1;
|
|
+ box.x2 = boxes[i].x2;
|
|
+ box.y1 = boxes[i].y1;
|
|
+ box.y2 = boxes[i].y2;
|
|
+ pixman_f_transform_bounds(&dirty->f_inverse, &box);
|
|
+
|
|
+ box.x1 = max(box.x1, 0);
|
|
+ box.y1 = max(box.y1, 0);
|
|
+ box.x2 = min(box.x2, dst_w);
|
|
+ box.y2 = min(box.y2, dst_h);
|
|
+ if (box.x1 >= box.x2 || box.y1 >= box.y2)
|
|
+ continue;
|
|
+
|
|
+ rects[nrects].x = box.x1;
|
|
+ rects[nrects].y = box.y1;
|
|
+ rects[nrects].width = box.x2 - box.x1;
|
|
+ rects[nrects].height = box.y2 - box.y1;
|
|
+ nrects++;
|
|
+ }
|
|
+ dstregion = RegionFromRects(nrects, rects, CT_UNSORTED);
|
|
+ } else
|
|
+#endif
|
|
+ {
|
|
+ RegionRec pixregion;
|
|
+
|
|
+ dstregion = RegionDuplicate(damageregion);
|
|
+ RegionTranslate(dstregion, -dirty->x, -dirty->y);
|
|
+ PixmapRegionInit(&pixregion, dirty->slave_dst);
|
|
+ RegionIntersect(dstregion, dstregion, &pixregion);
|
|
+ RegionUninit(&pixregion);
|
|
+ }
|
|
+
|
|
+ return dstregion;
|
|
+}
|
|
+
|
|
static void
|
|
-redisplay_dirty(PixmapDirtyUpdatePtr dirty)
|
|
+redisplay_dirty(PixmapDirtyUpdatePtr dirty, RegionPtr region)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86ScreenToScrn(dirty->src->drawable.pScreen);
|
|
- RegionRec pixregion;
|
|
|
|
- PixmapRegionInit(&pixregion, dirty->slave_dst);
|
|
- DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
|
|
+ if (dirty->slave_dst->master_pixmap)
|
|
+ DamageRegionAppend(&dirty->slave_dst->drawable, region);
|
|
+
|
|
#ifdef HAS_DIRTYTRACKING_ROTATION
|
|
PixmapSyncDirtyHelper(dirty);
|
|
#else
|
|
- PixmapSyncDirtyHelper(dirty, &pixregion);
|
|
+ PixmapSyncDirtyHelper(dirty, region);
|
|
#endif
|
|
|
|
radeon_cs_flush_indirect(pScrn);
|
|
- DamageRegionProcessPending(&dirty->slave_dst->drawable);
|
|
- RegionUninit(&pixregion);
|
|
+ if (dirty->slave_dst->master_pixmap)
|
|
+ DamageRegionProcessPending(&dirty->slave_dst->drawable);
|
|
|
|
DamageEmpty(dirty->damage);
|
|
}
|
|
@@ -424,7 +477,10 @@ 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) {
|
|
- redisplay_dirty(dirty);
|
|
+ RegionPtr region = dirty_region(dirty);
|
|
+
|
|
+ redisplay_dirty(dirty, region);
|
|
+ RegionDestroy(region);
|
|
break;
|
|
}
|
|
}
|
|
@@ -488,20 +544,24 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
|
|
static void
|
|
radeon_dirty_update(ScreenPtr screen)
|
|
{
|
|
- RegionPtr region;
|
|
PixmapDirtyUpdatePtr ent;
|
|
|
|
if (xorg_list_is_empty(&screen->pixmap_dirty_list))
|
|
return;
|
|
|
|
xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
|
|
- region = DamageRegion(ent->damage);
|
|
+ RegionPtr region = dirty_region(ent);
|
|
+
|
|
if (RegionNotEmpty(region)) {
|
|
if (screen->isGPU)
|
|
radeon_prime_scanout_update(ent);
|
|
else
|
|
- redisplay_dirty(ent);
|
|
+ redisplay_dirty(ent, region);
|
|
+ } else {
|
|
+ DamageEmpty(ent->damage);
|
|
}
|
|
+
|
|
+ RegionDestroy(region);
|
|
}
|
|
}
|
|
#endif
|