[Mesa-dev] [RFC v3 08/23] egl/x11: Reallocate buffer when the window moves to a different CRTC

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Thu Sep 28 07:54:48 UTC 2017


The optimal modifier depends on the current CRTC as some modifiers
might not allow direct scanout. When the window is moved to a
different CRTC, available modifiers should be re-fetched and the
buffers re-allocated.

Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
 src/egl/drivers/dri2/egl_dri2.h          |  2 ++
 src/egl/drivers/dri2/platform_x11_dri3.c |  8 ++++++++
 src/glx/dri3_glx.c                       |  6 +++++-
 src/loader/loader_dri3_helper.c          | 25 +++++++++++++++++++++----
 src/loader/loader_dri3_helper.h          |  3 +++
 5 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index b0811ae3eb..b69c329189 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -209,6 +209,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 5ca4347254..0f60d9d530 100644
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
@@ -144,6 +144,7 @@ dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
    struct dri3_egl_surface *dri3_surf;
    const __DRIconfig *dri_config;
    xcb_drawable_t drawable;
+   bool has_crtc_notify = false;
 
    (void) drv;
 
@@ -168,11 +169,15 @@ dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
 
    dri_config = dri2_get_dri_config(dri2_conf, type,
                                     dri3_surf->surf.base.GLColorspace);
+   has_crtc_notify = (dri2_dpy->present_major_version > 1 ||
+                      (dri2_dpy->present_major_version == 1 &&
+                       dri2_dpy->present_minor_version >= 1));
 
    if (loader_dri3_drawable_init(dri2_dpy->conn, drawable,
                                  dri2_dpy->dri_screen,
                                  dri2_dpy->is_different_gpu,
                                  dri2_dpy->multibuffers_available,
+                                 has_crtc_notify,
                                  dri_config,
                                  &dri2_dpy->loader_dri3_ext,
                                  &egl_dri3_vtable,
@@ -554,6 +559,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/glx/dri3_glx.c b/src/glx/dri3_glx.c
index 2041e7436f..3904980fc5 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -342,6 +342,7 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable,
       base->display->dri3Display;
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
    bool has_multibuffer = false;
+   bool has_crtc_notify = false;
 
    pdraw = calloc(1, sizeof(*pdraw));
    if (!pdraw)
@@ -356,12 +357,15 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable,
        (pdp->dri3Major > 1 || (pdp->dri3Major == 1 && pdp->dri3Minor >= 1)))
       has_multibuffer = true;
 
+   has_crtc_notify = (pdp->presentMajor > 1 ||
+                      (pdp->presentMajor == 1 && pdp->presentMinor >= 1));
+
    (void) __glXInitialize(psc->base.dpy);
 
    if (loader_dri3_drawable_init(XGetXCBConnection(base->dpy),
                                  xDrawable, psc->driScreen,
                                  psc->is_different_gpu, has_multibuffer,
-                                 config->driConfig,
+                                 has_crtc_notify, config->driConfig,
                                  &psc->loader_dri3_ext, &glx_dri3_vtable,
                                  &pdraw->loader_drawable)) {
       free(pdraw);
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 6c4717327f..72433248a8 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -258,6 +258,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
                           __DRIscreen *dri_screen,
                           bool is_different_gpu,
                           bool multiplanes_available,
+                          bool crtc_notify_available,
                           const __DRIconfig *dri_config,
                           struct loader_dri3_extensions *ext,
                           const struct loader_dri3_vtable *vtable,
@@ -276,6 +277,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
    draw->dri_screen = dri_screen;
    draw->is_different_gpu = is_different_gpu;
    draw->multiplanes_available = multiplanes_available;
+   draw->crtc_notify_available = crtc_notify_available;
 
    draw->have_back = 0;
    draw->have_fake_front = 0;
@@ -409,6 +411,14 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
       }
       break;
    }
+   case XCB_PRESENT_EVENT_WINDOW_CRTC_NOTIFY: {
+      int b;
+      for (b = 0; b < sizeof(draw->buffers) / sizeof(draw->buffers[0]); b++) {
+         if (draw->buffers[b])
+            draw->buffers[b]->crtc_changed = true;
+      }
+      break;
+   }
    }
    free(ge);
 }
@@ -1256,6 +1266,7 @@ dri3_update_drawable(__DRIdrawable *driDrawable,
       xcb_generic_error_t                       *error;
       xcb_present_query_capabilities_cookie_t   present_capabilities_cookie;
       xcb_present_query_capabilities_reply_t    *present_capabilities_reply;
+      uint32_t                                  input_flags = 0;
 
       draw->first_init = false;
 
@@ -1268,12 +1279,18 @@ dri3_update_drawable(__DRIdrawable *driDrawable,
        * will let us know that the drawable is a pixmap instead.
        */
 
+      input_flags = XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY |
+                    XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY |
+                    XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY;
+#if XCB_PRESENT_MAJOR_VERSION > 1 || (XCB_PRESENT_MAJOR_VERSION == 1 && XCB_PRESENT_MINOR_VERSION >= 1)
+      if (draw->crtc_notify_available)
+         input_flags |= XCB_PRESENT_EVENT_MASK_WINDOW_CRTC_NOTIFY;
+#endif
+
       draw->eid = xcb_generate_id(draw->conn);
       cookie =
          xcb_present_select_input_checked(draw->conn, draw->eid, draw->drawable,
-                                          XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY |
-                                          XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY |
-                                          XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY);
+                                          input_flags);
 
       present_capabilities_cookie =
          xcb_present_query_capabilities(draw->conn, draw->drawable);
@@ -1543,7 +1560,7 @@ 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->crtc_changed) {
       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 03c874fe0d..50aad94006 100644
--- a/src/loader/loader_dri3_helper.h
+++ b/src/loader/loader_dri3_helper.h
@@ -70,6 +70,7 @@ struct loader_dri3_buffer {
    uint32_t     flags;
    uint32_t     width, height;
    uint64_t     last_swap;
+   bool         crtc_changed;
 };
 
 
@@ -123,6 +124,7 @@ struct loader_dri3_drawable {
    __DRIscreen *dri_screen;
    bool is_different_gpu;
    bool multiplanes_available;
+   bool crtc_notify_available;
 
    /* Present extension capabilities
     */
@@ -178,6 +180,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
                           __DRIscreen *dri_screen,
                           bool is_different_gpu,
                           bool is_multiplanes_available,
+                          bool is_crtc_notify_available,
                           const __DRIconfig *dri_config,
                           struct loader_dri3_extensions *ext,
                           const struct loader_dri3_vtable *vtable,
-- 
2.13.0



More information about the mesa-dev mailing list