summaryrefslogtreecommitdiffstats
path: root/src/glx/dri3_glx.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-01-26 16:14:29 -0800
committerEric Anholt <eric@anholt.net>2014-01-30 17:29:33 -0800
commit3fbd1b0cb576b46ac8df2697cb388db78f48012d (patch)
tree63af9ff419152b770a4d8d6f7440e88033dc1076 /src/glx/dri3_glx.c
parentaea4757eb4caf6f980fdaa2b9345f26329c29d12 (diff)
downloadexternal_mesa3d-3fbd1b0cb576b46ac8df2697cb388db78f48012d.zip
external_mesa3d-3fbd1b0cb576b46ac8df2697cb388db78f48012d.tar.gz
external_mesa3d-3fbd1b0cb576b46ac8df2697cb388db78f48012d.tar.bz2
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 <keithp@keithp.com> Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'src/glx/dri3_glx.c')
-rw-r--r--src/glx/dri3_glx.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index 94f0eca..70ec057 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;
}