egl/x11: Re-allocate buffers if format is suboptimal
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@collabora.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:

committed by
Daniel Stone

parent
069fdd5f9f
commit
3160cb86aa
@@ -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 >= 2)) &&
|
||||
(dri2_dpy->present_major_version > 1 || (dri2_dpy->present_major_version == 1 &&
|
||||
dri2_dpy->present_minor_version >= 2)) &&
|
||||
(dri2_dpy->image && dri2_dpy->image->base.version >= 15);
|
||||
#endif
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -565,6 +565,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);
|
||||
|
@@ -372,7 +372,9 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable,
|
||||
pdraw->base.psc = &psc->base;
|
||||
|
||||
if ((psc->image && psc->image->base.version >= 15) &&
|
||||
(pdp->dri3Major > 1 || (pdp->dri3Major == 1 && pdp->dri3Minor >= 2)))
|
||||
(pdp->dri3Major > 1 || (pdp->dri3Major == 1 && pdp->dri3Minor >= 2)) &&
|
||||
(pdp->presentMajor > 1 ||
|
||||
(pdp->presentMajor == 1 && pdp->presentMinor >= 2)))
|
||||
has_multibuffer = true;
|
||||
|
||||
(void) __glXInitialize(psc->base.dpy);
|
||||
|
@@ -374,6 +374,29 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
|
||||
if (draw->recv_sbc > draw->send_sbc)
|
||||
draw->recv_sbc -= 0x100000000;
|
||||
|
||||
/* When moving from flip to copy, we assume that we can allocate in
|
||||
* a more optimal way if we don't need to cater for the display
|
||||
* controller.
|
||||
*/
|
||||
if (ce->mode == XCB_PRESENT_COMPLETE_MODE_COPY &&
|
||||
draw->last_present_mode == XCB_PRESENT_COMPLETE_MODE_FLIP) {
|
||||
for (int b = 0; b < ARRAY_SIZE(draw->buffers); b++) {
|
||||
if (draw->buffers[b])
|
||||
draw->buffers[b]->reallocate = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the server tells us that our allocation is suboptimal, we
|
||||
* reallocate once.
|
||||
*/
|
||||
if (ce->mode == XCB_PRESENT_COMPLETE_MODE_SUBOPTIMAL_COPY &&
|
||||
draw->last_present_mode != ce->mode) {
|
||||
for (int b = 0; b < ARRAY_SIZE(draw->buffers); b++) {
|
||||
if (draw->buffers[b])
|
||||
draw->buffers[b]->reallocate = true;
|
||||
}
|
||||
}
|
||||
|
||||
draw->last_present_mode = ce->mode;
|
||||
|
||||
if (draw->vtable->show_fps)
|
||||
@@ -397,9 +420,9 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
|
||||
if (buf && buf->pixmap == ie->pixmap)
|
||||
buf->busy = 0;
|
||||
|
||||
if (buf && draw->num_back <= b && b < LOADER_DRI3_MAX_BACK &&
|
||||
draw->cur_blit_source != b &&
|
||||
!buf->busy) {
|
||||
if (buf && draw->cur_blit_source != b && !buf->busy &&
|
||||
(buf->reallocate ||
|
||||
(draw->num_back <= b && b < LOADER_DRI3_MAX_BACK))) {
|
||||
dri3_free_render_buffer(draw, buf);
|
||||
draw->buffers[b] = NULL;
|
||||
}
|
||||
@@ -881,6 +904,9 @@ 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 (draw->multiplanes_available)
|
||||
options |= XCB_PRESENT_OPTION_SUBOPTIMAL;
|
||||
|
||||
back->busy = 1;
|
||||
back->last_swap = draw->send_sbc;
|
||||
xcb_present_pixmap(draw->conn,
|
||||
@@ -1626,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->reallocate) {
|
||||
struct loader_dri3_buffer *new_buffer;
|
||||
|
||||
/* Allocate the new buffers
|
||||
|
@@ -61,6 +61,7 @@ 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 reallocate; /* Buffer should be reallocated and not reused */
|
||||
|
||||
uint32_t num_planes;
|
||||
uint32_t size;
|
||||
|
Reference in New Issue
Block a user