aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xfree86/dri2
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xfree86/dri2')
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.c36
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.h3
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2ext.c4
3 files changed, 38 insertions, 5 deletions
diff --git a/xorg-server/hw/xfree86/dri2/dri2.c b/xorg-server/hw/xfree86/dri2/dri2.c
index 0d613be8e..d6441a234 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.c
+++ b/xorg-server/hw/xfree86/dri2/dri2.c
@@ -181,6 +181,7 @@ DRI2AllocateDrawable(DrawablePtr pDraw)
pPriv->last_swap_ust = 0;
list_init(&pPriv->reference_list);
pPriv->serialNumber = DRI2DrawableSerial(pDraw);
+ pPriv->needInvalidate = FALSE;
if (pDraw->type == DRAWABLE_WINDOW) {
pWin = (WindowPtr) pDraw;
@@ -376,6 +377,7 @@ allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
int old_buf = find_attachment(pPriv, attachment);
if ((old_buf < 0)
+ || attachment == DRI2BufferFrontLeft
|| !dimensions_match
|| (pPriv->buffers[old_buf]->format != format)) {
*buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
@@ -585,7 +587,7 @@ DRI2InvalidateDrawable(DrawablePtr pDraw)
pPriv->needInvalidate = FALSE;
list_for_each_entry(ref, &pPriv->reference_list, link)
- ref->invalidate(pDraw, ref->priv);
+ ref->invalidate(pDraw, ref->priv, ref->id);
}
/*
@@ -828,6 +830,19 @@ DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable)
return FALSE;
}
+/*
+ * A TraverseTree callback to invalidate all windows using the same
+ * pixmap
+ */
+static int
+DRI2InvalidateWalk(WindowPtr pWin, pointer data)
+{
+ if (pWin->drawable.pScreen->GetWindowPixmap(pWin) != data)
+ return WT_DONTWALKCHILDREN;
+ DRI2InvalidateDrawable(&pWin->drawable);
+ return WT_WALKCHILDREN;
+}
+
int
DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
CARD64 divisor, CARD64 remainder, CARD64 *swap_target,
@@ -928,7 +943,24 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
*/
*swap_target = pPriv->swap_count + pPriv->swapsPending;
- DRI2InvalidateDrawable(pDraw);
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr) pDraw;
+ PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
+
+ /*
+ * Find the top-most window using this pixmap
+ */
+ while (pWin->parent && pScreen->GetWindowPixmap(pWin->parent) == pPixmap)
+ pWin = pWin->parent;
+
+ /*
+ * Walk the sub-tree to invalidate all of the
+ * windows using the same pixmap
+ */
+ TraverseTree(pWin, DRI2InvalidateWalk, pPixmap);
+ DRI2InvalidateDrawable(&pPixmap->drawable);
+ } else
+ DRI2InvalidateDrawable(pDraw);
return Success;
}
diff --git a/xorg-server/hw/xfree86/dri2/dri2.h b/xorg-server/hw/xfree86/dri2/dri2.h
index 9c93209d1..a67e35f73 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.h
+++ b/xorg-server/hw/xfree86/dri2/dri2.h
@@ -166,7 +166,8 @@ typedef int (*DRI2ScheduleWaitMSCProcPtr)(ClientPtr client,
CARD64 remainder);
typedef void (*DRI2InvalidateProcPtr)(DrawablePtr pDraw,
- void *data);
+ void *data,
+ XID id);
/**
* DRI2 calls this hook when ever swap_limit is going to be changed. Default
diff --git a/xorg-server/hw/xfree86/dri2/dri2ext.c b/xorg-server/hw/xfree86/dri2/dri2ext.c
index e612cf051..73ef7f25e 100644
--- a/xorg-server/hw/xfree86/dri2/dri2ext.c
+++ b/xorg-server/hw/xfree86/dri2/dri2ext.c
@@ -156,13 +156,13 @@ ProcDRI2Authenticate(ClientPtr client)
}
static void
-DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv)
+DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv, XID id)
{
xDRI2InvalidateBuffers event;
ClientPtr client = priv;
event.type = DRI2EventBase + DRI2_InvalidateBuffers;
- event.drawable = pDraw->id;
+ event.drawable = id;
WriteEventsToClient(client, 1, (xEvent *)&event);
}