[PATCH] DRI2: use ConfigNotify to re-allocate buffers if root window changes

Jesse Barnes jbarnes at virtuousgeek.org
Thu Jul 8 11:39:01 PDT 2010


If the root window changes size, we need to re-allocate any DRI2
buffers that share the same pixmap so that they'll pick up the new root
pixmap (if the underlying driver ended up creating a new one).

So make sure we hook into the ConfigNotify chain in randr, and track
root pixmap changes in the DRI2 screen struct, re-allocating DRI2
buffers as needed when the changes occur.

Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index f9ba8e7..a12542b 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -82,6 +82,7 @@ typedef struct _DRI2Drawable {
     CARD64		 last_swap_msc; /* msc at completion of most recent swap */
     CARD64		 last_swap_ust; /* ust at completion of most recent swap */
     int			 swap_limit; /* for N-buffering */
+    unsigned long	 rootSequence; /* sequence this drawable was allocated against */
 } DRI2DrawableRec, *DRI2DrawablePtr;
 
 typedef struct _DRI2Screen {
@@ -92,6 +93,7 @@ typedef struct _DRI2Screen {
     const char			*deviceName;
     int				 fd;
     unsigned int		 lastSequence;
+    unsigned long		 rootSequence;
 
     DRI2CreateBufferProcPtr	 CreateBuffer;
     DRI2DestroyBufferProcPtr	 DestroyBuffer;
@@ -315,6 +317,20 @@ find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
 }
 
 static Bool
+DRI2DrawableIsScreen(DrawablePtr pDraw)
+{
+    ScreenPtr pScreen = pDraw->pScreen;
+    PixmapPtr pixmap;
+
+    if (pDraw->type != DRAWABLE_WINDOW)
+	return FALSE;
+
+    pixmap = pScreen->GetWindowPixmap((WindowPtr) pDraw);
+
+    return pixmap == pScreen->GetScreenPixmap(pScreen);
+}
+
+static Bool
 allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
 			 DRI2DrawablePtr pPriv,
 			 unsigned int attachment, unsigned int format,
@@ -324,8 +340,11 @@ allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
 
     if ((old_buf < 0)
 	|| !dimensions_match
-	|| (pPriv->buffers[old_buf]->format != format)) {
+	|| (pPriv->buffers[old_buf]->format != format)
+	|| ((DRI2DrawableIsScreen(pDraw) &&
+	     pPriv->rootSequence != ds->rootSequence))) {
 	*buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
+	pPriv->rootSequence = ds->rootSequence;
 	return TRUE;
 
     } else {
@@ -1021,6 +1040,9 @@ DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
 	    return ret;
     }
 
+    if (pWin == pScreen->root)
+	ds->rootSequence++;
+
     if (!dd || (dd->width == w && dd->height == h))
 	return Success;
 
@@ -1064,6 +1086,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
     ds->screen         = pScreen;
     ds->fd	       = info->fd;
     ds->deviceName     = info->deviceName;
+    ds->rootSequence   = 0;
     dri2_major         = 1;
 
     ds->CreateBuffer   = info->CreateBuffer;
diff --git a/randr/rrscreen.c b/randr/rrscreen.c
index f58e657..8627fc1 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -83,7 +83,11 @@ RRSendConfigNotify (ScreenPtr pScreen)
     event.u.configureNotify.y = 0;
 
     /* XXX xinerama stuff ? */
-    
+    if (pScreen->ConfigNotify)
+	(*pScreen->ConfigNotify)(pWin, 0, 0, pWin->drawable.width,
+				 pWin->drawable.height, pWin->borderWidth,
+				 NULL);
+
     event.u.configureNotify.width = pWin->drawable.width;
     event.u.configureNotify.height = pWin->drawable.height;
     event.u.configureNotify.borderWidth = wBorderWidth (pWin);


More information about the xorg-devel mailing list