mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 21:30:09 +01:00
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>
This commit is contained in:
parent
aea4757eb4
commit
3fbd1b0cb5
2 changed files with 35 additions and 24 deletions
|
|
@ -269,6 +269,16 @@ dri3_create_context(struct glx_screen *base,
|
|||
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)
|
||||
{
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue