#include <xcb/dri3.h>
#include <xcb/present.h>
#include <GL/gl.h>
-#include "glapi.h"
#include "glxclient.h"
-#include "xf86dri.h"
#include <dlfcn.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/time.h>
-#include "xf86drm.h"
#include "dri_common.h"
#include "dri3_priv.h"
#include "loader.h"
+#include "dri2.h"
static const struct glx_context_vtable dri3_context_vtable;
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)
{
break;
}
+ dri3_update_num_back(pdraw);
+
(void) __glXInitialize(psc->base.dpy);
/* Create a new drawable */
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;
}
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;
}
}
/* Convert from __DRI_IMAGE_FORMAT to __DRI_IMAGE_FOURCC (sigh) */
switch (format) {
+ case __DRI_IMAGE_FORMAT_SARGB8: return __DRI_IMAGE_FOURCC_SARGB8888;
case __DRI_IMAGE_FORMAT_RGB565: return __DRI_IMAGE_FOURCC_RGB565;
case __DRI_IMAGE_FORMAT_XRGB8888: return __DRI_IMAGE_FOURCC_XRGB8888;
case __DRI_IMAGE_FORMAT_ARGB8888: return __DRI_IMAGE_FOURCC_ARGB8888;
xcb_present_generic_event_t *ge;
for (;;) {
+ for (b = 0; b < priv->num_back; b++) {
+ int id = DRI3_BACK_ID((b + priv->cur_back) % priv->num_back);
+ struct dri3_buffer *buffer = priv->buffers[id];
- for (b = 0; b < DRI3_NUM_BACK; b++) {
- int id = DRI3_BACK_ID(b);
- struct dri3_buffer *buffer = priv->buffers[id];
-
- if (!buffer)
- return b;
- if (!buffer->busy)
- return b;
+ if (!buffer || !buffer->busy) {
+ priv->cur_back = id;
+ return id;
+ }
}
xcb_flush(c);
ev = xcb_wait_for_special_event(c, priv->special_event);
int buf_id;
if (buffer_type == dri3_buffer_back) {
- int back = dri3_find_back(c, priv);
+ buf_id = dri3_find_back(c, priv);
- if (back < 0)
+ if (buf_id < 0)
return NULL;
-
- priv->cur_back = back;
- buf_id = DRI3_BACK_ID(priv->cur_back);
} else {
buf_id = DRI3_FRONT_ID;
}
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;
/* The image loader extension record for DRI3
*/
static const __DRIimageLoaderExtension imageLoaderExtension = {
- {__DRI_IMAGE_LOADER, __DRI_IMAGE_LOADER_VERSION},
- .getBuffers = dri3_get_buffers,
- .flushFrontBuffer = dri3_flush_front_buffer,
+ .base = { __DRI_IMAGE_LOADER, 1 },
+
+ .getBuffers = dri3_get_buffers,
+ .flushFrontBuffer = dri3_flush_front_buffer,
+};
+
+static const __DRIextension *loader_extensions[] = {
+ &imageLoaderExtension.base,
+ &systemTimeExtension.base,
+ NULL
};
/** dri3_swap_buffers
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,
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
}
priv->swap_interval = interval;
+ dri3_update_num_back(priv);
return 0;
}
if (pdraw != NULL) {
psc = (struct dri3_screen *) base->psc;
- if (psc->texBuffer->releaseTexBuffer)
+ if (psc->texBuffer->base.version >= 3 &&
+ psc->texBuffer->releaseTexBuffer != NULL)
(*psc->texBuffer->releaseTexBuffer) (pcp->driContext,
pdraw->base.textureTarget,
pdraw->driDrawable);
}
static const struct glx_context_vtable dri3_context_vtable = {
- dri3_destroy_context,
- dri3_bind_context,
- dri3_unbind_context,
- dri3_wait_gl,
- dri3_wait_x,
- DRI_glXUseXFont,
- dri3_bind_tex_image,
- dri3_release_tex_image,
- NULL, /* get_proc_address */
+ .destroy = dri3_destroy_context,
+ .bind = dri3_bind_context,
+ .unbind = dri3_unbind_context,
+ .wait_gl = dri3_wait_gl,
+ .wait_x = dri3_wait_x,
+ .use_x_font = DRI_glXUseXFont,
+ .bind_tex_image = dri3_bind_tex_image,
+ .release_tex_image = dri3_release_tex_image,
+ .get_proc_address = NULL,
};
/** dri3_bind_extensions
if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0)
__glXEnableDirectExtension(&psc->base,
"GLX_ARB_create_context_robustness");
+
+ if (strcmp(extensions[i]->name, __DRI2_RENDERER_QUERY) == 0) {
+ psc->rendererQuery = (__DRI2rendererQueryExtension *) extensions[i];
+ __glXEnableDirectExtension(&psc->base, "GLX_MESA_query_renderer");
+ }
}
}
static const struct glx_screen_vtable dri3_screen_vtable = {
- dri3_create_context,
- dri3_create_context_attribs
+ .create_context = dri3_create_context,
+ .create_context_attribs = dri3_create_context_attribs,
+ .query_renderer_integer = dri3_query_renderer_integer,
+ .query_renderer_string = dri3_query_renderer_string,
};
/** dri3_create_screen
psc->driScreen =
psc->image_driver->createNewScreen2(screen, psc->fd,
- (const __DRIextension **)
- &pdp->loader_extensions[0],
+ pdp->loader_extensions,
extensions,
&driver_configs, psc);
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);
dri3_create_display(Display * dpy)
{
struct dri3_display *pdp;
- int i;
xcb_connection_t *c = XGetXCBConnection(dpy);
xcb_dri3_query_version_cookie_t dri3_cookie;
xcb_dri3_query_version_reply_t *dri3_reply;
pdp->base.createScreen = dri3_create_screen;
loader_set_logger(dri_message);
- i = 0;
-
- pdp->loader_extensions[i++] = &imageLoaderExtension.base;
-
- pdp->loader_extensions[i++] = &systemTimeExtension.base;
- pdp->loader_extensions[i++] = NULL;
+ pdp->loader_extensions = loader_extensions;
return &pdp->base;
no_extension: