[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