[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