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 <l...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev