summaryrefslogtreecommitdiff
path: root/src/loader
diff options
context:
space:
mode:
authorLouis-Francis Ratté-Boulianne <lfrb@collabora.com>2017-10-06 01:26:51 -0400
committerDaniel Stone <daniels@collabora.com>2018-03-09 17:47:14 +0000
commit3160cb86aa9234ff78e11fe7a00f30bfb5cb8445 (patch)
tree0fd309687b78213936bc5a5cd81efd021e25d162 /src/loader
parent069fdd5f9facbd72fb6a289696c7b74e3237e70f (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.c39
-rw-r--r--src/loader/loader_dri3_helper.h1
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;