All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michel Dänzer" <michel-otUistvHUpPR7s880joybQ@public.gmane.org>
To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Subject: [PATCH xf86-video-amdgpu 08/12] Only copy from screen pixmap to shared pixmap on demand for slave scanout
Date: Thu,  8 Sep 2016 19:02:41 +0900	[thread overview]
Message-ID: <20160908100242.19964-8-michel@daenzer.net> (raw)
In-Reply-To: <20160908100242.19964-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>

From: Michel Dänzer <michel.daenzer@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.daenzer@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

  parent reply	other threads:[~2016-09-08 10:02 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-08 10:02 [PATCH xf86-video-amdgpu 01/12] Add explicit AMDGPU_DRM_QUEUE_ERROR define Michel Dänzer
     [not found] ` <20160908100242.19964-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
2016-09-08 10:02   ` [PATCH xf86-video-amdgpu 02/12] Use EventCallback to avoid flushing every time in the FlushCallback Michel Dänzer
2016-09-08 10:02   ` [PATCH xf86-video-amdgpu 03/12] Keep track of damage event related flushes per-client Michel Dänzer
2016-09-08 10:02   ` [PATCH xf86-video-amdgpu 04/12] Wait for pending flips to complete before turning off an output or CRTC Michel Dänzer
2016-09-08 10:02   ` [PATCH xf86-video-amdgpu 05/12] Use drmmode_crtc_scanout_* helpers for RandR 1.4 scanout pixmaps Michel Dänzer
2016-09-08 10:02   ` [PATCH xf86-video-amdgpu 06/12] Handle RandR 1.4 slave dirty updates via amdgpu_drm_queue Michel Dänzer
2016-09-08 10:02   ` [PATCH xf86-video-amdgpu 07/12] Track damage accurately for RandR 1.4 slave scanout Michel Dänzer
2016-09-08 10:02   ` Michel Dänzer [this message]
2016-09-08 10:02   ` [PATCH xf86-video-amdgpu 09/12] Factor out transform_region helper Michel Dänzer
2016-09-08 10:03   ` [PATCH xf86-video-amdgpu 10/12] Move up amdgpu_scanout_extents_intersect Michel Dänzer
     [not found]     ` <20160908100310.20051-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
2016-09-08 10:03       ` [PATCH xf86-video-amdgpu 11/12] Synchronize scanout pixmaps for TearFree Michel Dänzer
2016-09-08 10:03       ` [PATCH xf86-video-amdgpu 12/12] Make TearFree effective with PRIME slave scanout Michel Dänzer
     [not found]         ` <20160908100310.20051-3-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
2016-09-08 12:53           ` Deucher, Alexander

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160908100242.19964-8-michel@daenzer.net \
    --to=michel-otuistvhuppr7s880joybq@public.gmane.org \
    --cc=amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.