[xserver,1/2] prime: Sync shared pixmap from root window instead of screen pixmap

Submitted by Michel Dänzer on Feb. 1, 2017, 9:35 a.m.

Details

Message ID 20170201093557.14982-2-michel@daenzer.net
State Accepted
Commit b5b292896f647c85f03f53b20b2f03c0e94de428
Headers show
Series "present: Allow flipping with PRIME slave outputs" ( rev: 1 ) in X.org (DEPRECATED - USE GITLAB)

Not browsing as part of any series.

Commit Message

Michel Dänzer Feb. 1, 2017, 9:35 a.m.
From: Michel Dänzer <michel.daenzer@amd.com>

The screen pixmap doesn't receive updates while there's a Present flip
window.

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
---
 dix/pixmap.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

Patch hide | download patch | download mbox

diff --git a/dix/pixmap.c b/dix/pixmap.c
index 49267a19b..ef0083083 100644
--- a/dix/pixmap.c
+++ b/dix/pixmap.c
@@ -233,7 +233,8 @@  PixmapStartDirtyTracking(PixmapPtr src,
     RegionUnion(damageregion, damageregion, &dstregion);
     RegionUninit(&dstregion);
 
-    DamageRegister(&src->drawable, dirty_update->damage);
+    DamageRegister(screen->root ? &screen->root->drawable : &src->drawable,
+                   dirty_update->damage);
     xorg_list_add(&dirty_update->ent, &screen->pixmap_dirty_list);
     return TRUE;
 }
@@ -260,6 +261,7 @@  PixmapDirtyCopyArea(PixmapPtr dst,
                     RegionPtr dirty_region)
 {
     ScreenPtr pScreen = dirty->src->drawable.pScreen;
+    DrawablePtr src = pScreen->root ? &pScreen->root->drawable : &dirty->src->drawable;
     int n;
     BoxPtr b;
     GCPtr pGC;
@@ -267,7 +269,13 @@  PixmapDirtyCopyArea(PixmapPtr dst,
     n = RegionNumRects(dirty_region);
     b = RegionRects(dirty_region);
 
-    pGC = GetScratchGC(dirty->src->drawable.depth, pScreen);
+    pGC = GetScratchGC(src->depth, pScreen);
+    if (pScreen->root) {
+        ChangeGCVal subWindowMode;
+
+        subWindowMode.val = IncludeInferiors;
+        ChangeGC(NullClient, pGC, GCSubwindowMode, &subWindowMode);
+    }
     ValidateGC(&dst->drawable, pGC);
 
     while (n--) {
@@ -278,7 +286,7 @@  PixmapDirtyCopyArea(PixmapPtr dst,
         w = dst_box.x2 - dst_box.x1;
         h = dst_box.y2 - dst_box.y1;
 
-        pGC->ops->CopyArea(&dirty->src->drawable, &dst->drawable, pGC,
+        pGC->ops->CopyArea(src, &dst->drawable, pGC,
                            dirty->x + dst_box.x1, dirty->y + dst_box.y1, w, h,
                            dirty->dst_x + dst_box.x1,
                            dirty->dst_y + dst_box.y1);
@@ -301,7 +309,7 @@  PixmapDirtyCompositeRotate(PixmapPtr dst_pixmap,
     int error;
 
     src = CreatePicture(None,
-                        &dirty->src->drawable,
+                        &pScreen->root->drawable,
                         format,
                         CPSubwindowMode,
                         &include_inferiors, serverClient, &error);

Comments

On 01/02/17 06:35 PM, Michel Dänzer wrote:
> From: Michel Dänzer <michel.daenzer@amd.com>
> 
> The screen pixmap doesn't receive updates while there's a Present flip
> window.
> 
> Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
> ---
>  dix/pixmap.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/dix/pixmap.c b/dix/pixmap.c
> index 49267a19b..ef0083083 100644
> --- a/dix/pixmap.c
> +++ b/dix/pixmap.c
> @@ -233,7 +233,8 @@ PixmapStartDirtyTracking(PixmapPtr src,
>      RegionUnion(damageregion, damageregion, &dstregion);
>      RegionUninit(&dstregion);
>  
> -    DamageRegister(&src->drawable, dirty_update->damage);
> +    DamageRegister(screen->root ? &screen->root->drawable : &src->drawable,
> +                   dirty_update->damage);

I discovered a problem with this. Looks like on server shutdown the
root window can be destroyed before the scanout pixmap is detached, see
valgrind output below.

Is there any solution for this other than wrapping DestroyWindow and
calling PixmapStopDirtyTracking when a root window is destroyed?


==32070== Invalid read of size 8
==32070==    at 0x23E20A: DamageDestroy (damage.c:1812)
==32070==    by 0x176560: PixmapStopDirtyTracking (pixmap.c:250)
==32070==    by 0x2190A6: RRCrtcDetachScanoutPixmap (rrcrtc.c:405)
==32070==    by 0x219147: RRCrtcDestroyResource (rrcrtc.c:883)
==32070==    by 0x17D296: doFreeResource (resource.c:880)
==32070==    by 0x17E49D: FreeClientResources (resource.c:1146)
==32070==    by 0x17E56B: FreeAllResources (resource.c:1161)
==32070==    by 0x15CA97: dix_main (main.c:303)
==32070==    by 0x6B5B2B0: (below main) (libc-start.c:291)
==32070==  Address 0x13f12f68 is 104 bytes inside a block of size 120 free'd
==32070==    at 0x4C2CDDB: free (vg_replace_malloc.c:530)
==32070==    by 0x23E357: damageDestroyWindow (damage.c:1567)
==32070==    by 0x1FD056: XvDestroyWindow (xvmain.c:385)
==32070==    by 0x1B293E: xf86XVDestroyWindow (xf86xv.c:1020)
==32070==    by 0x1EBDFB: compDestroyWindow (compwindow.c:607)
==32070==    by 0x18A2F4: FreeWindowResources (window.c:1031)
==32070==    by 0x18D577: DeleteWindow (window.c:1099)
==32070==    by 0x17D296: doFreeResource (resource.c:880)
==32070==    by 0x17E49D: FreeClientResources (resource.c:1146)
==32070==    by 0x17E56B: FreeAllResources (resource.c:1161)
==32070==    by 0x15CA97: dix_main (main.c:303)
==32070==    by 0x6B5B2B0: (below main) (libc-start.c:291)
==32070==  Block was alloc'd at
==32070==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==32070==    by 0x1773C5: _dixAllocateObjectWithPrivates (privates.c:486)
==32070==    by 0x23DEE7: DamageCreate (damage.c:1699)
==32070==    by 0x17638A: PixmapStartDirtyTracking (pixmap.c:198)
==32070==    by 0x219D6D: rrSetupPixmapSharing (rrcrtc.c:591)
==32070==    by 0x219D6D: RRCrtcSet (rrcrtc.c:761)
==32070==    by 0x21AC53: ProcRRSetCrtcConfig (rrcrtc.c:1367)
==32070==    by 0x1588C8: Dispatch (dispatch.c:479)
==32070==    by 0x15CA64: dix_main (main.c:287)
==32070==    by 0x6B5B2B0: (below main) (libc-start.c:291)
On Tue, 2017-02-14 at 18:36 +0900, Michel Dänzer wrote:

> I discovered a problem with this. Looks like on server shutdown the
> root window can be destroyed before the scanout pixmap is detached, see
> valgrind output below.
> 
> Is there any solution for this other than wrapping DestroyWindow and
> calling PixmapStopDirtyTracking when a root window is destroyed?

Perhaps the DamageCreate in PixmapStartDirtyTracking needs a destroy
hook that unhooks the pixmap from the dirty list?

- ajax