diff options
author | Keith Packard <[email protected]> | 2014-01-26 16:14:29 -0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2014-01-30 17:29:33 -0800 |
commit | 3fbd1b0cb576b46ac8df2697cb388db78f48012d (patch) | |
tree | 63af9ff419152b770a4d8d6f7440e88033dc1076 | |
parent | aea4757eb4caf6f980fdaa2b9345f26329c29d12 (diff) |
dri3: Track current Present swap mode and adjust buffer counts
This automatically adjusts the number of buffers that we want based on
what swapping mode the X server is using and the current swap interval:
swap mode interval buffers
copy > 0 1
copy 0 2
flip > 0 2
flip 0 3
Note that flip with swap interval 0 is currently limited to twice the
underlying refresh rate because of how the kernel manages flipping. Moving
from 3 to 4 buffers would help, but that seems ridiculous.
v2: Just update num_back at the point that the values that change num_back
change. This means we'll have the updated value at the point that the
freeing of old going-to-be-unused backbuffers happens, which might not
have been the case before (change by anholt, acked by keithp).
Signed-off-by: Keith Packard <[email protected]>
Signed-off-by: Eric Anholt <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
-rw-r--r-- | src/glx/dri3_glx.c | 35 | ||||
-rw-r--r-- | src/glx/dri3_priv.h | 24 |
2 files changed, 35 insertions, 24 deletions
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c index 94f0eca8588..70ec057d0b6 100644 --- a/src/glx/dri3_glx.c +++ b/src/glx/dri3_glx.c @@ -270,6 +270,16 @@ static void dri3_free_render_buffer(struct dri3_drawable *pdraw, struct dri3_buffer *buffer); static void +dri3_update_num_back(struct dri3_drawable *priv) +{ + priv->num_back = 1; + if (priv->flipping) + priv->num_back++; + if (priv->swap_interval == 0) + priv->num_back++; +} + +static void dri3_destroy_drawable(__GLXDRIdrawable *base) { struct dri3_screen *psc = (struct dri3_screen *) base->psc; @@ -326,6 +336,8 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable, break; } + dri3_update_num_back(pdraw); + (void) __glXInitialize(psc->base.dpy); /* Create a new drawable */ @@ -373,6 +385,15 @@ dri3_handle_present_event(struct dri3_drawable *priv, xcb_present_generic_event_ priv->recv_sbc = (priv->send_sbc & 0xffffffff00000000LL) | ce->serial; if (priv->recv_sbc > priv->send_sbc) priv->recv_sbc -= 0x100000000; + switch (ce->mode) { + case XCB_PRESENT_COMPLETE_MODE_FLIP: + priv->flipping = true; + break; + case XCB_PRESENT_COMPLETE_MODE_COPY: + priv->flipping = false; + break; + } + dri3_update_num_back(priv); } else { priv->recv_msc_serial = ce->serial; } @@ -389,6 +410,10 @@ dri3_handle_present_event(struct dri3_drawable *priv, xcb_present_generic_event_ if (buf && buf->pixmap == ie->pixmap) { buf->busy = 0; + if (priv->num_back <= b && b < DRI3_MAX_BACK) { + dri3_free_render_buffer(priv, buf); + priv->buffers[b] = NULL; + } break; } } @@ -1067,10 +1092,9 @@ dri3_find_back(xcb_connection_t *c, struct dri3_drawable *priv) xcb_present_generic_event_t *ge; for (;;) { - - for (b = 0; b < DRI3_NUM_BACK; b++) { - int id = DRI3_BACK_ID(b); - struct dri3_buffer *buffer = priv->buffers[id]; + for (b = 0; b < priv->num_back; b++) { + int id = DRI3_BACK_ID(b); + struct dri3_buffer *buffer = priv->buffers[id]; if (!buffer) return b; @@ -1185,7 +1209,7 @@ dri3_free_buffers(__DRIdrawable *driDrawable, switch (buffer_type) { case dri3_buffer_back: first_id = DRI3_BACK_ID(0); - n_id = DRI3_NUM_BACK; + n_id = DRI3_MAX_BACK; break; case dri3_buffer_front: first_id = DRI3_FRONT_ID; @@ -1437,6 +1461,7 @@ dri3_set_swap_interval(__GLXDRIdrawable *pdraw, int interval) } priv->swap_interval = interval; + dri3_update_num_back(priv); return 0; } diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h index 9d142cf5137..1d124f8abd7 100644 --- a/src/glx/dri3_priv.h +++ b/src/glx/dri3_priv.h @@ -143,25 +143,9 @@ struct dri3_context __DRIcontext *driContext; }; -#define DRI3_NUM_BACK 2 +#define DRI3_MAX_BACK 3 #define DRI3_BACK_ID(i) (i) -#define DRI3_FRONT_ID (DRI3_NUM_BACK) - -static inline int -dri3_buf_id_next(int buf_id) -{ - if (buf_id == DRI3_NUM_BACK - 1) - return 0; - return buf_id + 1; -} - -static inline int -dri3_buf_id_prev(int buf_id) -{ - if (buf_id == 0) - return DRI3_NUM_BACK - 1; - return buf_id - 1; -} +#define DRI3_FRONT_ID (DRI3_MAX_BACK) static inline int dri3_pixmap_buf_id(enum dri3_buffer_type buffer_type) @@ -172,7 +156,7 @@ dri3_pixmap_buf_id(enum dri3_buffer_type buffer_type) return DRI3_FRONT_ID; } -#define DRI3_NUM_BUFFERS (1 + DRI3_NUM_BACK) +#define DRI3_NUM_BUFFERS (1 + DRI3_MAX_BACK) struct dri3_drawable { __GLXDRIdrawable base; @@ -182,6 +166,7 @@ struct dri3_drawable { uint8_t have_back; uint8_t have_fake_front; uint8_t is_pixmap; + uint8_t flipping; /* SBC numbers are tracked by using the serial numbers * in the present request and complete events @@ -198,6 +183,7 @@ struct dri3_drawable { struct dri3_buffer *buffers[DRI3_NUM_BUFFERS]; int cur_back; + int num_back; uint32_t *stamp; |