On Fri, Feb 9, 2018 at 3:43 PM, Jason Ekstrand <ja...@jlekstrand.net> wrote:
> 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> > --- > 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; > + } > Pardon my ignorance but don't we get a present event on every frame? Do we want to do this loop unconditionally or only if draw->flipping changes? > 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; > + } > The same comment may apply here. It's also entirely possible that I don't know how this code works. > +#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 > >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev