On Wed, 14 Jul 2010 16:20:40 +0300
Pauli Nieminen <[email protected]> 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 <[email protected]>
> ---
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);
}
_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel