| 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 |
| |