[PATCH] dri2: Invalidate window pixmaps

Ville Syrjälä ville.syrjala at nokia.com
Mon Feb 7 10:52:57 PST 2011


While a redirected window is flipped, it's pixmap may still be used as
and EGL image and should also get invalidated. When sending invalidate
events for a window, also send the events for it's pixmap.

Signed-off-by: Ville Syrjälä <ville.syrjala at nokia.com>
---
 hw/xfree86/dri2/dri2.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 03011ff..5faf042 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -673,6 +673,17 @@ DRI2InvalidateDrawable(DRI2DrawablePtr pPriv)
 	ref->invalidate(pPriv, ref->priv, ref->id);
 }
 
+static void
+DRI2InvalidateWindowPixmap(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
+    DRI2DrawablePtr pPriv = DRI2GetDrawable(&pPixmap->drawable);
+
+    if (pPriv)
+	DRI2InvalidateDrawable(pPriv);
+}
+
 /*
  * In the direct rendered case, we throttle the clients that have more
  * than their share of outstanding swaps (and thus busy buffers) when a
@@ -1071,6 +1082,8 @@ DRI2SwapBuffers(ClientPtr client, DRI2DrawablePtr pPriv, CARD64 target_msc,
     *swap_target = pPriv->swap_count + pPriv->swapsPending;
 
     DRI2InvalidateDrawable(pPriv);
+    if (pDraw->type == DRAWABLE_WINDOW)
+	DRI2InvalidateWindowPixmap((WindowPtr)pDraw);
 
     DRI2CopyFrontToFakeFront(pDraw, pPriv);
     return Success;
@@ -1248,6 +1261,7 @@ DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
 	return Success;
 
     DRI2InvalidateDrawable(DRI2GetDrawable(pDraw));
+    DRI2InvalidateWindowPixmap(pWin);
     return Success;
 }
 
-- 
1.7.3.4

I do wonder if we could always attach the ref list to the window pixmap
instead of the window itself. That would avoid the need to walk the
whole window tree when a flip occurs. But I didn't look into this any
further, so I'm not sure how we would handle cases where the window
pixmap changes.

> Also re-generate the real front buffer information every time the client asks
> for it, or we might keep around stale cached information.

For offscreen flipping I solved this by always updating the buffer
information in the ReuseBufferNotify() hook. But I suppose your solution
fits better into the current dri2 design.

BTW I don't really like the current dri2 design. The old interface with
one CreateBuffers call instead of multiple CreateBuffer calls seemed
better. It made it easier to do some things in the driver code. For
example the depth_pixmap handling in the ati driver looks broken with
the new dri2 interface. It would also allow the driver to make a copy
from the old buffer to the new buffer in case the client had already
started rendering. OTOH I suppose the client could just avoid
re-getting the buffers after it's started rendering. And I suppose
the copy could also be done by adding a new hook to the current dri2
interface.

> Fixes https://bugs.freedesktop.org/show_bug.cgi?id=35452 .
> 
> Signed-off-by: Michel Dänzer <daenzer at vmware.com>
> ---
>  hw/xfree86/dri2/dri2.c |   19 ++++++++++++++++++-
>  1 files changed, 18 insertions(+), 1 deletions(-)
> 
> diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
> index d8851f2..c229959 100644
> --- a/hw/xfree86/dri2/dri2.c
> +++ b/hw/xfree86/dri2/dri2.c
> @@ -339,6 +339,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);
> @@ -814,6 +815,15 @@ DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable)
>      return FALSE;
>  }
>  
> +static int
> +DRI2SwapWalk(WindowPtr pWin, pointer data)
> +{
> +    if (pWin->drawable.pScreen->GetWindowPixmap(pWin) == data)
> +	DRI2InvalidateDrawable(&pWin->drawable);
> +
> +    return WT_WALKCHILDREN;
> +}
> +
>  int
>  DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
>  		CARD64 divisor, CARD64 remainder, CARD64 *swap_target,
> @@ -914,7 +924,14 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
>       */
>      *swap_target = pPriv->swap_count + pPriv->swapsPending;
>  
> -    DRI2InvalidateDrawable(pDraw);
> +    if (pDraw->type == DRAWABLE_WINDOW) {
> +	/* Invalidate DRI2 buffers for all windows with the same window pixmap
> +	 * as this one.
> +	 */
> +	WalkTree(pScreen, DRI2SwapWalk,
> +		 pScreen->GetWindowPixmap((WindowPtr)pDraw));
> +    } else
> +	DRI2InvalidateDrawable(pDraw);
>  
>      return Success;
>  }
> -- 
> 1.7.4.1
> 
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel

-- 
Ville Syrjälä


More information about the xorg-devel mailing list