All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH xf86-video-ati 1/2] Only copy from screen pixmap to shared pixmap on demand for slave scanout
@ 2016-08-31  8:55 Michel Dänzer
       [not found] ` <20160831085543.5286-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: Michel Dänzer @ 2016-08-31  8:55 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

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.

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
---
 src/radeon_kms.c | 100 +++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 78 insertions(+), 22 deletions(-)

diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 51f320c..0c8996d 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)
 {
@@ -473,16 +510,20 @@ radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t u
     drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
     PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap;
     PixmapDirtyUpdatePtr dirty;
+    RegionPtr region;
 
     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);
+	if (dirty->src != scanoutpix ||
+	    dirty->slave_dst != drmmode_crtc->scanout[0].pixmap)
+	    continue;
 
-	    redisplay_dirty(dirty, region);
-	    RegionDestroy(region);
-	    break;
-	}
+	if (master_has_sync_shared_pixmap(scrn, dirty))
+	    radeon_sync_shared_pixmap(dirty);
+
+	region = dirty_region(dirty);
+	redisplay_dirty(dirty, region);
+	RegionDestroy(region);
+	break;
     }
 
     drmmode_crtc->scanout_update_pending = FALSE;
@@ -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 (RegionNotEmpty(region)) {
-			if (screen->isGPU)
-				radeon_prime_scanout_update(ent);
-			else
-				redisplay_dirty(ent, region);
+		if (screen->isGPU) {
+			ScreenPtr master_screen = ent->src->master_pixmap->drawable.pScreen;
+			PixmapDirtyUpdatePtr master_ent;
+
+			xorg_list_for_each_entry(master_ent, &master_screen->pixmap_dirty_list, ent) {
+				if (master_ent->slave_dst != ent->src)
+					continue;
+
+				if (master_has_sync_shared_pixmap(scrn, ent))
+					region = dirty_region(master_ent);
+				else
+					region = dirty_region(ent);
+
+				if (RegionNotEmpty(region))
+					radeon_prime_scanout_update(ent);
+				else
+					DamageEmpty(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
 }
 
-- 
2.9.3

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH xf86-video-ati 2/2] Add support for ScreenPtr::SyncSharedPixmap
       [not found] ` <20160831085543.5286-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
@ 2016-08-31  8:55   ` Michel Dänzer
       [not found]     ` <20160831085543.5286-2-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
  2016-09-01  7:46   ` [PATCH v2 xf86-video-ati 1/2] Only copy from screen pixmap to shared pixmap on demand for slave scanout Michel Dänzer
  1 sibling, 1 reply; 5+ messages in thread
From: Michel Dänzer @ 2016-08-31  8:55 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Michel Dänzer <michel.daenzer@amd.com>

This allows deferring shared pixmap updates between different drivers.

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
---

This change requires a corresponding xserver change adding the
SyncSharedPixmap field. I'll only push it once the xserver change has
landed.

 src/radeon_kms.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 0c8996d..f43c30f 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -485,6 +485,35 @@ radeon_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty)
     }
 }
 
+
+#if HAS_SYNC_SHARED_PIXMAP
+
+static Bool
+master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
+{
+    ScreenPtr master_screen = dirty->src->master_pixmap->drawable.pScreen;
+
+    return master_screen->SyncSharedPixmap != NULL;
+}
+
+static Bool
+slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
+{
+    ScreenPtr slave_screen = dirty->slave_dst->drawable.pScreen;
+
+    return slave_screen->SyncSharedPixmap != NULL;
+}
+
+static void
+call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty)
+{
+    ScreenPtr master_screen = dirty->src->master_pixmap->drawable.pScreen;
+
+    master_screen->SyncSharedPixmap(dirty);
+}
+
+#else /* !HAS_SYNC_SHARED_PIXMAP */
+
 static Bool
 master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
 {
@@ -501,6 +530,15 @@ slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr dirty)
     return slave_scrn->driverName == scrn->driverName;
 }
 
+static void
+call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty)
+{
+    radeon_sync_shared_pixmap(dirty);
+}
+
+#endif /* HAS_SYNC_SHARED_PIXMAPS */
+
+
 void
 radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
 				    void *event_data)
@@ -518,7 +556,7 @@ radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t u
 	    continue;
 
 	if (master_has_sync_shared_pixmap(scrn, dirty))
-	    radeon_sync_shared_pixmap(dirty);
+	    call_sync_shared_pixmap(dirty);
 
 	region = dirty_region(dirty);
 	redisplay_dirty(dirty, region);
@@ -2128,6 +2166,9 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
 #ifdef RADEON_PIXMAP_SHARING
     pScreen->StartPixmapTracking = PixmapStartDirtyTracking;
     pScreen->StopPixmapTracking = PixmapStopDirtyTracking;
+#if HAS_SYNC_SHARED_PIXMAP
+    pScreen->SyncSharedPixmap = radeon_sync_shared_pixmap;
+#endif
 #endif
 
    if (!xf86CrtcScreenInit (pScreen))
-- 
2.9.3

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* RE: [PATCH xf86-video-ati 2/2] Add support for ScreenPtr::SyncSharedPixmap
       [not found]     ` <20160831085543.5286-2-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
@ 2016-08-31 15:07       ` Deucher, Alexander
  0 siblings, 0 replies; 5+ messages in thread
From: Deucher, Alexander @ 2016-08-31 15:07 UTC (permalink / raw)
  To: Michel Dänzer, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces@lists.freedesktop.org] On Behalf
> Of Michel Dänzer
> Sent: Wednesday, August 31, 2016 4:56 AM
> To: amd-gfx@lists.freedesktop.org
> Subject: [PATCH xf86-video-ati 2/2] Add support for
> ScreenPtr::SyncSharedPixmap
> 
> From: Michel Dänzer <michel.daenzer@amd.com>
> 
> This allows deferring shared pixmap updates between different drivers.
> 
> Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>

For the series:
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
> 
> This change requires a corresponding xserver change adding the
> SyncSharedPixmap field. I'll only push it once the xserver change has
> landed.
> 
>  src/radeon_kms.c | 43
> ++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 42 insertions(+), 1 deletion(-)
> 
> diff --git a/src/radeon_kms.c b/src/radeon_kms.c
> index 0c8996d..f43c30f 100644
> --- a/src/radeon_kms.c
> +++ b/src/radeon_kms.c
> @@ -485,6 +485,35 @@
> radeon_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty)
>      }
>  }
> 
> +
> +#if HAS_SYNC_SHARED_PIXMAP
> +
> +static Bool
> +master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr
> dirty)
> +{
> +    ScreenPtr master_screen = dirty->src->master_pixmap-
> >drawable.pScreen;
> +
> +    return master_screen->SyncSharedPixmap != NULL;
> +}
> +
> +static Bool
> +slave_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr
> dirty)
> +{
> +    ScreenPtr slave_screen = dirty->slave_dst->drawable.pScreen;
> +
> +    return slave_screen->SyncSharedPixmap != NULL;
> +}
> +
> +static void
> +call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty)
> +{
> +    ScreenPtr master_screen = dirty->src->master_pixmap-
> >drawable.pScreen;
> +
> +    master_screen->SyncSharedPixmap(dirty);
> +}
> +
> +#else /* !HAS_SYNC_SHARED_PIXMAP */
> +
>  static Bool
>  master_has_sync_shared_pixmap(ScrnInfoPtr scrn, PixmapDirtyUpdatePtr
> dirty)
>  {
> @@ -501,6 +530,15 @@ slave_has_sync_shared_pixmap(ScrnInfoPtr scrn,
> PixmapDirtyUpdatePtr dirty)
>      return slave_scrn->driverName == scrn->driverName;
>  }
> 
> +static void
> +call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty)
> +{
> +    radeon_sync_shared_pixmap(dirty);
> +}
> +
> +#endif /* HAS_SYNC_SHARED_PIXMAPS */
> +
> +
>  void
>  radeon_prime_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame,
> uint64_t usec,
>  				    void *event_data)
> @@ -518,7 +556,7 @@ radeon_prime_scanout_update_handler(xf86CrtcPtr
> crtc, uint32_t frame, uint64_t u
>  	    continue;
> 
>  	if (master_has_sync_shared_pixmap(scrn, dirty))
> -	    radeon_sync_shared_pixmap(dirty);
> +	    call_sync_shared_pixmap(dirty);
> 
>  	region = dirty_region(dirty);
>  	redisplay_dirty(dirty, region);
> @@ -2128,6 +2166,9 @@ Bool
> RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
>  #ifdef RADEON_PIXMAP_SHARING
>      pScreen->StartPixmapTracking = PixmapStartDirtyTracking;
>      pScreen->StopPixmapTracking = PixmapStopDirtyTracking;
> +#if HAS_SYNC_SHARED_PIXMAP
> +    pScreen->SyncSharedPixmap = radeon_sync_shared_pixmap;
> +#endif
>  #endif
> 
>     if (!xf86CrtcScreenInit (pScreen))
> --
> 2.9.3
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 xf86-video-ati 1/2] Only copy from screen pixmap to shared pixmap on demand for slave scanout
       [not found] ` <20160831085543.5286-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
  2016-08-31  8:55   ` [PATCH xf86-video-ati 2/2] Add support for ScreenPtr::SyncSharedPixmap Michel Dänzer
@ 2016-09-01  7:46   ` Michel Dänzer
       [not found]     ` <20160901074613.31805-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
  1 sibling, 1 reply; 5+ messages in thread
From: Michel Dänzer @ 2016-09-01  7:46 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

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.

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> [v1]
Signed-off-by: Michel Dänzer <michel.daenzer@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
 }
 
-- 
2.9.3

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* RE: [PATCH v2 xf86-video-ati 1/2] Only copy from screen pixmap to shared pixmap on demand for slave scanout
       [not found]     ` <20160901074613.31805-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
@ 2016-09-01 13:49       ` Deucher, Alexander
  0 siblings, 0 replies; 5+ messages in thread
From: Deucher, Alexander @ 2016-09-01 13:49 UTC (permalink / raw)
  To: 'Michel Dänzer', amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces@lists.freedesktop.org] On Behalf
> Of Michel Dänzer
> Sent: Thursday, September 01, 2016 3:46 AM
> To: amd-gfx@lists.freedesktop.org
> Subject: [PATCH v2 xf86-video-ati 1/2] Only copy from screen pixmap to
> shared pixmap on demand for slave scanout
> 
> 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.
> 
> 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> [v1]
> Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>

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
>  }
> 
> --
> 2.9.3
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-09-01 13:49 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-31  8:55 [PATCH xf86-video-ati 1/2] Only copy from screen pixmap to shared pixmap on demand for slave scanout Michel Dänzer
     [not found] ` <20160831085543.5286-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
2016-08-31  8:55   ` [PATCH xf86-video-ati 2/2] Add support for ScreenPtr::SyncSharedPixmap Michel Dänzer
     [not found]     ` <20160831085543.5286-2-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
2016-08-31 15:07       ` Deucher, Alexander
2016-09-01  7:46   ` [PATCH v2 xf86-video-ati 1/2] Only copy from screen pixmap to shared pixmap on demand for slave scanout Michel Dänzer
     [not found]     ` <20160901074613.31805-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
2016-09-01 13:49       ` Deucher, Alexander

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.