On Wed, 14 Jul 2010 16:20:40 +0300
Pauli Nieminen <ext-pauli.niemi...@nokia.com> wrote:

> This allows ddx to set swap_limit if there is variable number of
> buffers for drawable.
> 
> This allows ddx driver to select triple buffering to avoid problems if
> frame rate is close to VSYNC rate. While driver may want to keep
> composite swaps double buffered to save memory.
> 
> Signed-off-by: Pauli Nieminen <ext-pauli.niemi...@nokia.com>
> ---

Have you tested this?  I think there are a few things on the server
side that need work to make triple (or more) buffering work.  Here's
the patch I last used to work on it...

To make things fast, you'll need some extra buffers allocated in the
DRI2 drawable, and you'll need to switch between them at swapbuffers
time, along with upping the swap_limit.

-- 
Jesse Barnes, Intel Open Source Technology Center
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index f9ba8e7..93634ba 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -82,6 +82,8 @@ 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 */
+    Bool		 triple_buffer;
+    DRI2BufferPtr	 extra_back; /* for triple buffering */
 } DRI2DrawableRec, *DRI2DrawablePtr;
 
 typedef struct _DRI2Screen {
@@ -163,6 +165,8 @@ DRI2AllocateDrawable(DrawablePtr pDraw)
     pPriv->last_swap_msc = 0;
     pPriv->last_swap_ust = 0;
     list_init(&pPriv->reference_list);
+    pPriv->triple_buffer = TRUE;
+    pPriv->extra_back = NULL;
 
     if (pDraw->type == DRAWABLE_WINDOW) {
 	pWin = (WindowPtr) pDraw;
@@ -371,7 +375,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
     int need_real_front = 0;
     int need_fake_front = 0;
     int have_fake_front = 0;
-    int front_format = 0;
+    int front_format = 0, back_format = 0;
     int dimensions_match;
     int buffers_changed = 0;
     int i;
@@ -408,6 +412,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
 	if (attachment == DRI2BufferBackLeft) {
 	    need_real_front++;
 	    front_format = format;
+	    back_format = format;
 	}
 
 	if (attachment == DRI2BufferFrontLeft) {
@@ -427,6 +432,17 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
 	}
     }
 
+    if (pPriv->triple_buffer) {
+	if (!dimensions_match) {
+	    (*ds->DestroyBuffer)(pDraw, pPriv->extra_back);
+	    pPriv->extra_back = NULL;
+	}
+
+	if (!pPriv->extra_back)
+	    pPriv->extra_back = (*ds->CreateBuffer)(pDraw, DRI2BufferBackLeft,
+						    back_format);
+    }
+
     if (need_real_front > 0) {
 	if (allocate_or_reuse_buffer(pDraw, ds, pPriv, DRI2BufferFrontLeft,
 				     front_format, dimensions_match,
@@ -727,6 +743,16 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
     pPriv->last_swap_msc = frame;
     pPriv->last_swap_ust = ust;
 
+    if (pPriv->triple_buffer) {
+	DRI2BufferPtr tmp;
+	int i;
+
+	i = find_attachment(pPriv, DRI2BufferBackLeft);
+	tmp = pPriv->extra_back;
+	pPriv->extra_back = pPriv->buffers[i];
+	pPriv->buffers[i] = tmp;
+    }
+
     DRI2WakeClient(client, pDraw, frame, tv_sec, tv_usec);
 }
 
_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to