diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2017-10-06 01:26:51 -0400 |
---|---|---|
committer | Daniel Stone <daniels@collabora.com> | 2018-03-09 17:47:14 +0000 |
commit | 3160cb86aa9234ff78e11fe7a00f30bfb5cb8445 (patch) | |
tree | 0fd309687b78213936bc5a5cd81efd021e25d162 /src/loader | |
parent | 069fdd5f9facbd72fb6a289696c7b74e3237e70f (diff) |
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>
Diffstat (limited to 'src/loader')
-rw-r--r-- | src/loader/loader_dri3_helper.c | 39 | ||||
-rw-r--r-- | src/loader/loader_dri3_helper.h | 1 |
2 files changed, 34 insertions, 6 deletions
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c index 6587281c4a..585f7ce3ec 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -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 diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h index c54c668032..de22c19a57 100644 --- a/src/loader/loader_dri3_helper.h +++ b/src/loader/loader_dri3_helper.h @@ -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; |