blob: 4c71641083fcea9064048d65470cd0425165d0f4 [file] [log] [blame]
From 9e17b77b6cea698d234cb1209c45e4f9e8601e0e Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Wed, 25 May 2016 11:51:42 +0100
Subject: [PATCH] Add DRI Query Buffers extension.
The DRI Query Buffers extension allows a driver to specify a
callback to notify the driver that it should query for new buffers
immediately.
The extension allows the query for new buffers to be done early,
such as at the end of eglSwapBuffers, so that if a window is resized
just before the call to eglSwapBuffers, the updated EGL surface
dimensions will be returned by any calls of eglQuerySurface that are
made immediately after.
The associated DRI Use Query Buffers loader extension is used to
indicate to the driver that the DRI Query Buffers extension will be
used, if the driver supports it.
---
include/GL/internal/dri_interface.h | 33 +++++++++++++++++++++++++++++++++
src/egl/drivers/dri2/egl_dri2.c | 5 +++++
src/egl/drivers/dri2/egl_dri2.h | 4 +++-
src/egl/drivers/dri2/platform_wayland.c | 10 +++++++---
src/egl/drivers/dri2/platform_x11.c | 13 ++++++++-----
src/mesa/drivers/dri/common/dri_util.c | 2 ++
src/mesa/drivers/dri/common/dri_util.h | 1 +
7 files changed, 59 insertions(+), 9 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index ee067a3..236f5bd 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -80,6 +80,7 @@ typedef struct __DRI2flushExtensionRec __DRI2flushExtension;
typedef struct __DRI2throttleExtensionRec __DRI2throttleExtension;
typedef struct __DRI2fenceExtensionRec __DRI2fenceExtension;
typedef struct __DRI2interopExtensionRec __DRI2interopExtension;
+typedef struct __DRIqueryBuffersExtensionRec __DRIqueryBuffersExtension;
typedef struct __DRIimageLoaderExtensionRec __DRIimageLoaderExtension;
@@ -418,6 +419,20 @@ struct __DRI2interopExtensionRec {
struct mesa_glinterop_export_out *out);
};
+/**
+ * Extension that the driver uses to request
+ * query buffers callbacks.
+ */
+
+#define __DRI_QUERY_BUFFERS "DRI_QueryBuffers"
+#define __DRI_QUERY_BUFFERS_VERSION 1
+
+struct __DRIqueryBuffersExtensionRec {
+ __DRIextension base;
+ void (*query_buffers)(__DRIdrawable *drawable);
+};
+
+
/*@}*/
/**
@@ -586,6 +601,24 @@ struct __DRIuseInvalidateExtensionRec {
};
/**
+ * Query buffers loader extension. The presence of this extension
+ * indicates to the DRI driver that the loader will call query buffers
+ * in the __DRI_QUERY_BUFFERS extension, to indicate to the driver
+ * that it should query for new buffers immediately.
+ *
+ * The extension doesn't provide any functionality, its only use
+ * is to indicate to the driver that query buffers will be called,
+ * if available.
+ */
+#define __DRI_USE_QUERY_BUFFERS "DRI_UseQueryBuffers"
+#define __DRI_USE_QUERY_BUFFERS_VERSION 1
+
+typedef struct __DRIuseQueryBuffersExtensionRec __DRIuseQueryBuffersExtension;
+struct __DRIuseQueryBuffersExtensionRec {
+ __DRIextension base;
+};
+
+/**
* The remaining extensions describe driver extensions, immediately
* available interfaces provided by the driver. To start using the
* driver, dlsym() for the __DRI_DRIVER_EXTENSIONS symbol and look for
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 27197ab..c6f96ef 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -78,6 +78,10 @@ const __DRIuseInvalidateExtension use_invalidate = {
.base = { __DRI_USE_INVALIDATE, 1 }
};
+const __DRIuseQueryBuffersExtension use_query_buffers = {
+ .base = { __DRI_USE_QUERY_BUFFERS, 1 }
+};
+
EGLint dri2_to_egl_attribute_map[] = {
0,
EGL_BUFFER_SIZE, /* __DRI_ATTRIB_BUFFER_SIZE */
@@ -373,6 +377,7 @@ static struct dri2_extension_match dri2_core_extensions[] = {
{ __DRI2_FLUSH, 1, offsetof(struct dri2_egl_display, flush) },
{ __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) },
{ __DRI_IMAGE, 1, offsetof(struct dri2_egl_display, image) },
+ { __DRI_QUERY_BUFFERS, 1, offsetof(struct dri2_egl_display, query_buffers) },
{ NULL, 0, 0 }
};
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index cc1dc69..1061083 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -176,6 +176,7 @@ struct dri2_egl_display
const __DRI2rendererQueryExtension *rendererQuery;
const __DRI2interopExtension *interop;
const __DRIpriorityExtension *priority;
+ const __DRIqueryBuffersExtension *query_buffers;
int fd;
int own_device;
@@ -193,7 +194,7 @@ struct dri2_egl_display
__DRIdri2LoaderExtension dri2_loader_extension;
__DRIswrastLoaderExtension swrast_loader_extension;
- const __DRIextension *extensions[5];
+ const __DRIextension *extensions[6];
const __DRIextension **driver_extensions;
#ifdef HAVE_X11_PLATFORM
@@ -335,6 +336,7 @@ _EGL_DRIVER_TYPECAST(dri2_egl_sync, _EGLSync, obj)
extern const __DRIimageLookupExtension image_lookup_extension;
extern const __DRIuseInvalidateExtension use_invalidate;
+extern const __DRIuseQueryBuffersExtension use_query_buffers;
EGLBoolean
dri2_load_driver(_EGLDisplay *disp);
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index ff0d5c8..dbcceaa 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -774,6 +774,9 @@ dri2_wl_swap_buffers_with_damage(_EGLDriver *drv,
wl_display_flush(dri2_dpy->wl_dpy);
+ if (dri2_dpy->query_buffers)
+ (*dri2_dpy->query_buffers->query_buffers)(dri2_surf->dri_drawable);
+
return EGL_TRUE;
}
@@ -1140,6 +1143,7 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp)
dri2_dpy->extensions[0] = &image_loader_extension.base;
dri2_dpy->extensions[1] = &image_lookup_extension.base;
dri2_dpy->extensions[2] = &use_invalidate.base;
+ dri2_dpy->extensions[3] = &use_query_buffers.base;
/* render nodes cannot use Gem names, and thus do not support
* the __DRI_DRI2_LOADER extension */
@@ -1150,10 +1154,10 @@ dri2_initialize_wayland_drm(_EGLDriver *drv, _EGLDisplay *disp)
dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_wl_flush_front_buffer;
dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
dri2_wl_get_buffers_with_format;
- dri2_dpy->extensions[3] = &dri2_dpy->dri2_loader_extension.base;
- dri2_dpy->extensions[4] = NULL;
+ dri2_dpy->extensions[4] = &dri2_dpy->dri2_loader_extension.base;
+ dri2_dpy->extensions[5] = NULL;
} else
- dri2_dpy->extensions[3] = NULL;
+ dri2_dpy->extensions[4] = NULL;
dri2_dpy->swap_available = EGL_TRUE;
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index c0a4005..5369282 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -866,15 +866,17 @@ dri2_x11_swap_buffers_msc(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw,
* the way xlib does), and SwapBuffers is a common cause of invalidate
* events, just shove one down to the driver, even though we haven't told
* the driver that we're the kind of loader that provides reliable
- * invalidate events. This causes the driver to request buffers again at
- * its next draw, so that we get the correct buffers if a pageflip
- * happened. The driver should still be using the viewport hack to catch
- * window resizes.
+ * invalidate events. This causes the driver to request buffers again,
+ * so that we get the correct buffers if a pageflip happened. The driver
+ * should still be using the viewport hack to catch window resizes.
*/
if (dri2_dpy->flush &&
dri2_dpy->flush->base.version >= 3 && dri2_dpy->flush->invalidate)
(*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
+ if (dri2_dpy->query_buffers)
+ (*dri2_dpy->query_buffers->query_buffers)(dri2_surf->dri_drawable);
+
return swap_count;
}
@@ -1423,7 +1425,8 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
dri2_dpy->extensions[1] = &image_lookup_extension.base;
- dri2_dpy->extensions[2] = NULL;
+ dri2_dpy->extensions[2] = &use_query_buffers.base;
+ dri2_dpy->extensions[3] = NULL;
dri2_dpy->swap_available = (dri2_dpy->dri2_minor >= 2);
dri2_dpy->invalidate_available = (dri2_dpy->dri2_minor >= 3);
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index 86ed42f..160de2e 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -79,6 +79,8 @@ setupLoaderExtensions(__DRIscreen *psp,
psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i];
if (strcmp(extensions[i]->name, __DRI_IMAGE_LOADER) == 0)
psp->image.loader = (__DRIimageLoaderExtension *) extensions[i];
+ if (strcmp(extensions[i]->name, __DRI_USE_QUERY_BUFFERS) == 0)
+ psp->dri2.useQueryBuffers = (__DRIuseQueryBuffersExtension *) extensions[i];
}
}
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index 7d7c633..9cfc330 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -172,6 +172,7 @@ struct __DRIscreenRec {
const __DRIdri2LoaderExtension *loader;
const __DRIimageLookupExtension *image;
const __DRIuseInvalidateExtension *useInvalidate;
+ const __DRIuseQueryBuffersExtension *useQueryBuffers;
} dri2;
struct {
--
1.9.1