[Mesa-dev] [PATCHv4 3/3] dri3: Add GLX_EXT_buffer_age support
Adel Gadllah
adel.gadllah at gmail.com
Wed Feb 26 15:27:09 PST 2014
Signed-off-by: Adel Gadllah <adel.gadllah at gmail.com>
Reviewed-by: Robert Bragg <robert at sixbynine.org>
---
src/glx/dri2_glx.c | 1 +
src/glx/dri3_glx.c | 19 +++++++++++++++++++
src/glx/dri3_priv.h | 2 ++
src/glx/glx_pbuffer.c | 33 ++++++++++++++++++++++++++++++---
src/glx/glxclient.h | 1 +
src/glx/glxextensions.c | 1 +
src/glx/glxextensions.h | 1 +
7 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 67fe9c1..146802a 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -1288,6 +1288,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;
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index 70ec057..383abec 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -319,6 +319,7 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable,
pdraw->swap_interval = 1; /* default may be overridden below */
pdraw->have_back = 0;
pdraw->have_fake_front = 0;
+ pdraw->swap_count = 1;
if (psc->config)
psc->config->configQueryi(psc->driScreen,
@@ -1345,6 +1346,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->swap_count;
xcb_present_pixmap(c,
priv->base.xDrawable,
priv->buffers[buf_id]->pixmap,
@@ -1379,11 +1381,25 @@ dri3_swap_buffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
xcb_flush(c);
if (priv->stamp)
++(*priv->stamp);
+
+ priv->swap_count++;
}
return ret;
}
+static int
+dri3_get_buffer_age(__GLXDRIdrawable *pdraw)
+{
+ struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
+ const struct dri3_buffer *const back = dri3_back_buffer(priv);
+
+ if (back->last_swap != 0)
+ return priv->swap_count - back->last_swap;
+ else
+ return 0;
+}
+
/** dri3_open
*
* Wrapper around xcb_dri3_open
@@ -1742,6 +1758,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);
diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h
index 1d124f8..d00440a 100644
--- a/src/glx/dri3_priv.h
+++ b/src/glx/dri3_priv.h
@@ -97,6 +97,7 @@ struct dri3_buffer {
uint32_t cpp;
uint32_t flags;
uint32_t width, height;
+ uint32_t last_swap;
enum dri3_buffer_type buffer_type;
};
@@ -184,6 +185,7 @@ struct dri3_drawable {
struct dri3_buffer *buffers[DRI3_NUM_BUFFERS];
int cur_back;
int num_back;
+ uint32_t swap_count;
uint32_t *stamp;
diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c
index 978730c..0cd0554 100644
--- a/src/glx/glx_pbuffer.c
+++ b/src/glx/glx_pbuffer.c
@@ -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
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index a7118af..74c19c4 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -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
diff --git a/src/glx/glxextensions.c b/src/glx/glxextensions.c
index f186c13..ac1b4a7 100644
--- a/src/glx/glxextensions.c
+++ b/src/glx/glxextensions.c
@@ -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 }
};
diff --git a/src/glx/glxextensions.h b/src/glx/glxextensions.h
index 8436a94..37e4ccc 100644
--- a/src/glx/glxextensions.h
+++ b/src/glx/glxextensions.h
@@ -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
--
1.8.5.3
More information about the mesa-dev
mailing list