[Mesa-dev] [PATCH 08/16] egl/x11: Re-allocate buffers if format is suboptimal
Jason Ekstrand
jason at jlekstrand.net
Fri Feb 9 23:43:24 UTC 2018
From: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
If PresentCompleteNotify event says the pixmap was presented
with mode PresentCompleteModeSuboptimalCopy, it means the pixmap
could possibly have been flipped instead if allocated with a
different format/modifier.
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
src/egl/drivers/dri2/egl_dri2.c | 2 ++
src/egl/drivers/dri2/egl_dri2.h | 2 ++
src/egl/drivers/dri2/platform_x11_dri3.c | 3 +++
src/loader/loader_dri3_helper.c | 28 +++++++++++++++++++++++++++-
src/loader/loader_dri3_helper.h | 2 ++
5 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 8147842..752f173 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -889,6 +889,8 @@ dri2_setup_extensions(_EGLDisplay *disp)
dri2_dpy->multibuffers_available =
(dri2_dpy->dri3_major_version > 1 || (dri2_dpy->dri3_major_version == 1 &&
dri2_dpy->dri3_minor_version >= 1)) &&
+ (dri2_dpy->present_major_version > 1 || (dri2_dpy->present_major_version == 1 &&
+ dri2_dpy->present_minor_version >= 1)) &&
(dri2_dpy->image && dri2_dpy->image->base.version >= 15);
#endif
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index bff33df..4e711ff 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -202,6 +202,8 @@ struct dri2_egl_display
bool multibuffers_available;
int dri3_major_version;
int dri3_minor_version;
+ int present_major_version;
+ int present_minor_version;
struct loader_dri3_extensions loader_dri3_ext;
#endif
#endif
diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c
index 0532cd3..8e9b071 100644
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
@@ -555,6 +555,9 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy)
free(error);
return EGL_FALSE;
}
+
+ dri2_dpy->present_major_version = present_query->major_version;
+ dri2_dpy->present_minor_version = present_query->minor_version;
free(present_query);
dri2_dpy->fd = loader_dri3_open(dri2_dpy->conn, dri2_dpy->screen->root, 0);
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 80a4497..fe5c56f 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -34,6 +34,7 @@
#include <X11/Xlib-xcb.h>
#include "loader_dri3_helper.h"
+#include "util/macros.h"
/* From xmlpool/options.h, user exposed so should be stable */
#define DRI_CONF_VBLANK_NEVER 0
@@ -378,10 +379,22 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
switch (ce->mode) {
case XCB_PRESENT_COMPLETE_MODE_FLIP:
draw->flipping = true;
+ for (int b = 0; b < ARRAY_SIZE(draw->buffers); b++) {
+ if (draw->buffers[b])
+ draw->buffers[b]->realloc_suboptimal = true;
+ }
break;
case XCB_PRESENT_COMPLETE_MODE_COPY:
draw->flipping = false;
break;
+#if XCB_PRESENT_MAJOR_VERSION > 1 || (XCB_PRESENT_MAJOR_VERSION == 1 && XCB_PRESENT_MINOR_VERSION >= 1)
+ case XCB_PRESENT_COMPLETE_MODE_SUBOPTIMAL_COPY:
+ draw->flipping = false;
+ for (int b = 0; b < ARRAY_SIZE(draw->buffers); b++) {
+ if (draw->buffers[b])
+ draw->buffers[b]->suboptimal = true;
+ }
+#endif
}
if (draw->vtable->show_fps)
@@ -889,6 +902,11 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
if (!loader_dri3_have_image_blit(draw) && draw->cur_blit_source != -1)
options |= XCB_PRESENT_OPTION_COPY;
+#if XCB_PRESENT_MAJOR_VERSION > 1 || (XCB_PRESENT_MAJOR_VERSION == 1 && XCB_PRESENT_MINOR_VERSION >= 1)
+ if (draw->multiplanes_available)
+ options |= XCB_PRESENT_OPTION_SUBOPTIMAL;
+#endif
+
back->busy = 1;
back->last_swap = draw->send_sbc;
xcb_present_pixmap(draw->conn,
@@ -1255,6 +1273,8 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format,
buffer->shm_fence = shm_fence;
buffer->width = width;
buffer->height = height;
+ buffer->suboptimal = false;
+ buffer->realloc_suboptimal = true;
/* Mark the buffer as idle
*/
@@ -1599,7 +1619,8 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
* old one is the wrong size
*/
if (!buffer || buffer->width != draw->width ||
- buffer->height != draw->height) {
+ buffer->height != draw->height ||
+ (buffer->suboptimal && buffer->realloc_suboptimal)) {
struct loader_dri3_buffer *new_buffer;
/* Allocate the new buffers
@@ -1658,6 +1679,11 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
0, 0, 0);
}
}
+
+ /* Avoid multiple reallocations when the best we can use is a suboptimal
+ * format/modifier. */
+ new_buffer->realloc_suboptimal = buffer ? !buffer->suboptimal : true;
+
buffer = new_buffer;
draw->buffers[buf_id] = buffer;
}
diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
index 5689e27..2668a05 100644
--- a/src/loader/loader_dri3_helper.h
+++ b/src/loader/loader_dri3_helper.h
@@ -61,6 +61,8 @@ struct loader_dri3_buffer {
struct xshmfence *shm_fence; /* pointer to xshmfence object */
bool busy; /* Set on swap, cleared on IdleNotify */
bool own_pixmap; /* We allocated the pixmap ID, free on destroy */
+ bool suboptimal; /* Set when CompleteNotify has ModeSuboptimalCopy */
+ bool realloc_suboptimal; /* Avoid constant reallocation on worst cases */
uint32_t num_planes;
uint32_t size;
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list