[Mesa-dev] [RFC v4 08/23] egl/x11: Re-allocate buffers if format is suboptimal

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Mon Oct 16 07:04:18 UTC 2017


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 at collabora.com>
---
 src/loader/loader_dri3_helper.c | 22 +++++++++++++++++++++-
 src/loader/loader_dri3_helper.h |  2 ++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index a49204827a..16740f5fdd 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -372,10 +372,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 < sizeof(draw->buffers) / sizeof(draw->buffers[0]); 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 < sizeof(draw->buffers) / sizeof(draw->buffers[0]); b++) {
+               if (draw->buffers[b])
+                  draw->buffers[b]->suboptimal = true;
+            }
+#endif
          }
          dri3_update_num_back(draw);
 
@@ -1215,6 +1227,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
     */
@@ -1543,7 +1557,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
@@ -1602,6 +1617,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 03c874fe0d..e1307be089 100644
--- a/src/loader/loader_dri3_helper.h
+++ b/src/loader/loader_dri3_helper.h
@@ -60,6 +60,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.13.0



More information about the mesa-dev mailing list