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 <[email protected]>

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);
_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to