dri3: Add GLX_EXT_buffer_age support
v2: Indent according to Mesa style, reuse sbc instead of making a new swap_count field, and actually get a usable back before returning the age of the back (fixing updated piglit tests). Changes by anholt. Signed-off-by: Adel Gadllah <adel.gadllah@gmail.com> Reviewed-by: Robert Bragg <robert@sixbynine.org> (v1) Reviewed-by: Adel Gadllah <adel.gadllah@gmail.com> (v2) Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
0b02d8a633
commit
a69fabc76c
|
@ -1287,6 +1287,7 @@ dri2CreateScreen(int screen, struct glx_display * priv)
|
|||
psp->waitForSBC = NULL;
|
||||
psp->setSwapInterval = NULL;
|
||||
psp->getSwapInterval = NULL;
|
||||
psp->getBufferAge = NULL;
|
||||
|
||||
if (pdp->driMinor >= 2) {
|
||||
psp->getDrawableMSC = dri2DrawableGetMSC;
|
||||
|
|
|
@ -1340,6 +1340,7 @@ dri3_swap_buffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
|
|||
target_msc = priv->msc + priv->swap_interval * (priv->send_sbc - priv->recv_sbc);
|
||||
|
||||
priv->buffers[buf_id]->busy = 1;
|
||||
priv->buffers[buf_id]->last_swap = priv->send_sbc;
|
||||
xcb_present_pixmap(c,
|
||||
priv->base.xDrawable,
|
||||
priv->buffers[buf_id]->pixmap,
|
||||
|
@ -1379,6 +1380,22 @@ dri3_swap_buffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
dri3_get_buffer_age(__GLXDRIdrawable *pdraw)
|
||||
{
|
||||
xcb_connection_t *c = XGetXCBConnection(pdraw->psc->dpy);
|
||||
struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
|
||||
int back_id = DRI3_BACK_ID(dri3_find_back(c, priv));
|
||||
|
||||
if (back_id < 0 || !priv->buffers[back_id])
|
||||
return 0;
|
||||
|
||||
if (priv->buffers[back_id]->last_swap != 0)
|
||||
return priv->send_sbc - priv->buffers[back_id]->last_swap + 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** dri3_open
|
||||
*
|
||||
* Wrapper around xcb_dri3_open
|
||||
|
@ -1737,6 +1754,9 @@ dri3_create_screen(int screen, struct glx_display * priv)
|
|||
psp->copySubBuffer = dri3_copy_sub_buffer;
|
||||
__glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
|
||||
|
||||
psp->getBufferAge = dri3_get_buffer_age;
|
||||
__glXEnableDirectExtension(&psc->base, "GLX_EXT_buffer_age");
|
||||
|
||||
free(driverName);
|
||||
free(deviceName);
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ struct dri3_buffer {
|
|||
uint32_t cpp;
|
||||
uint32_t flags;
|
||||
uint32_t width, height;
|
||||
uint64_t last_swap;
|
||||
|
||||
enum dri3_buffer_type buffer_type;
|
||||
};
|
||||
|
|
|
@ -285,6 +285,10 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
|
|||
unsigned int num_attributes;
|
||||
GLboolean use_glx_1_3;
|
||||
|
||||
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
||||
__GLXDRIdrawable *pdraw;
|
||||
#endif
|
||||
|
||||
if (dpy == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -311,6 +315,32 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
|
|||
if (!opcode)
|
||||
return 0;
|
||||
|
||||
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
||||
pdraw = GetGLXDRIDrawable(dpy, drawable);
|
||||
|
||||
if (attribute == GLX_BACK_BUFFER_AGE_EXT) {
|
||||
struct glx_screen *psc = pdraw->psc;
|
||||
struct glx_context *gc = __glXGetCurrentContext();
|
||||
|
||||
/* The GLX_EXT_buffer_age spec says:
|
||||
*
|
||||
* "If querying GLX_BACK_BUFFER_AGE_EXT and <draw> is not bound to
|
||||
* the calling thread's current context a GLXBadDrawable error is
|
||||
* generated."
|
||||
*/
|
||||
if (gc == NULL || gc->currentDpy != dpy ||
|
||||
(gc->currentDrawable != drawable && gc->currentReadable != drawable)) {
|
||||
__glXSendError(dpy, GLXBadDrawable, drawable, X_GLXGetDrawableAttributes, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (psc->driScreen->getBufferAge != NULL)
|
||||
*value = psc->driScreen->getBufferAge(pdraw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
LockDisplay(dpy);
|
||||
|
||||
if (use_glx_1_3) {
|
||||
|
@ -350,9 +380,6 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
|
|||
_XEatData(dpy, length);
|
||||
}
|
||||
else {
|
||||
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
||||
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
|
||||
#endif
|
||||
_XRead(dpy, (char *) data, length * sizeof(CARD32));
|
||||
|
||||
/* Search the set of returned attributes for the attribute requested by
|
||||
|
|
|
@ -125,6 +125,7 @@ struct __GLXDRIscreenRec {
|
|||
int64_t *msc, int64_t *sbc);
|
||||
int (*setSwapInterval)(__GLXDRIdrawable *pdraw, int interval);
|
||||
int (*getSwapInterval)(__GLXDRIdrawable *pdraw);
|
||||
int (*getBufferAge)(__GLXDRIdrawable *pdraw);
|
||||
};
|
||||
|
||||
struct __GLXDRIdrawableRec
|
||||
|
|
|
@ -103,6 +103,7 @@ static const struct extension_info known_glx_extensions[] = {
|
|||
{ GLX(SGIX_visual_select_group), VER(0,0), Y, Y, N, N },
|
||||
{ GLX(EXT_texture_from_pixmap), VER(0,0), Y, N, N, N },
|
||||
{ GLX(INTEL_swap_event), VER(0,0), Y, N, N, N },
|
||||
{ GLX(EXT_buffer_age), VER(0,0), Y, N, Y, Y },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ enum
|
|||
SGIX_visual_select_group_bit,
|
||||
EXT_texture_from_pixmap_bit,
|
||||
INTEL_swap_event_bit,
|
||||
EXT_buffer_age_bit,
|
||||
};
|
||||
|
||||
/* From the GLX perspective, the ARB and EXT extensions are identical. Use a
|
||||
|
|
Loading…
Reference in New Issue