From: Louis-Francis Ratté-Boulianne <l...@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 <l...@collabora.com> Reviewed-by: Daniel Stone <dani...@collabora.com> Signed-off-by: Daniel Stone <dani...@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 | 37 ++++++++++++++++++++++++++++---- src/loader/loader_dri3_helper.h | 2 ++ src/loader/meson.build | 2 +- 6 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 9a7e43bafb6..921d1a52931 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -885,6 +885,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 00c4768d421..bd637f73c9d 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 15c349eb828..ae2588d04c4 100644 --- a/src/egl/drivers/dri2/platform_x11_dri3.c +++ b/src/egl/drivers/dri2/platform_x11_dri3.c @@ -557,6 +557,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 038216c2637..855ec5ce343 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -34,6 +34,8 @@ #include <X11/Xlib-xcb.h> #include "loader_dri3_helper.h" +#include "util/macros.h" +#include "drm_fourcc.h" /* From xmlpool/options.h, user exposed so should be stable */ #define DRI_CONF_VBLANK_NEVER 0 @@ -373,11 +375,25 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw, draw->recv_sbc -= 0x100000000; switch (ce->mode) { case XCB_PRESENT_COMPLETE_MODE_FLIP: - draw->flipping = true; + if (!draw->flipping) { + 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) @@ -885,6 +901,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, @@ -1287,6 +1308,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 */ @@ -1629,11 +1652,12 @@ dri3_get_buffer(__DRIdrawable *driDrawable, buffer = draw->buffers[buf_id]; - /* Allocate a new buffer if there isn't an old one, or if that - * old one is the wrong size + /* Allocate a new buffer if there isn't an old one, if that + * old one is the wrong size, or if it's suboptimal */ 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 @@ -1692,6 +1716,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 5689e2707c5..2668a05b758 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; diff --git a/src/loader/meson.build b/src/loader/meson.build index e4455e9a72b..76fcae2cb44 100644 --- a/src/loader/meson.build +++ b/src/loader/meson.build @@ -25,7 +25,7 @@ if with_platform_x11 and with_dri3 'loader_dri3_helper', ['loader_dri3_helper.c', 'loader_dri3_helper.h'], c_args : c_vis_args, - include_directories : inc_include, + include_directories : [inc_include, inc_src, inc_drm_uapi], dependencies : [ dep_libdrm, dep_xcb_dri3, dep_xcb_present, dep_xcb_sync, dep_xshmfence, ], -- 2.14.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev