diff options
author | Simon Ser <contact@emersion.fr> | 2021-08-23 18:39:31 +0200 |
---|---|---|
committer | Simon Zeni <simon@bl4ckb0ne.ca> | 2021-08-25 10:05:37 -0400 |
commit | 749b3c00f0d0cb3575c8f058ea8c5e9877d4fd9c (patch) | |
tree | f97e7a44268d263dfbbe28bca3c9323433fdd573 /render/egl.c | |
parent | 3ce2ea9e16fcd1bfab4ec9d5994fa721c5d58dcd (diff) |
render/egl: reopen DRM node for GBM
This will be necessary for the next patch, to avoid messing up BO
handles shared between the GL implementation and the DRM backend.
Diffstat (limited to 'render/egl.c')
-rw-r--r-- | render/egl.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/render/egl.c b/render/egl.c index 3b57b0d5..712a61c8 100644 --- a/render/egl.c +++ b/render/egl.c @@ -421,6 +421,28 @@ static EGLDeviceEXT get_egl_device_from_drm_fd(struct wlr_egl *egl, return egl_device; } +static int open_render_node(int drm_fd) { + char *render_name = drmGetRenderDeviceNameFromFd(drm_fd); + if (render_name == NULL) { + // This can happen on split render/display platforms, fallback to + // primary node + render_name = drmGetPrimaryDeviceNameFromFd(drm_fd); + if (render_name == NULL) { + wlr_log_errno(WLR_ERROR, "drmGetPrimaryDeviceNameFromFd failed"); + return -1; + } + wlr_log(WLR_DEBUG, "DRM device '%s' has no render node, " + "falling back to primary node", render_name); + } + + int render_fd = open(render_name, O_RDWR | O_CLOEXEC); + if (render_fd < 0) { + wlr_log_errno(WLR_ERROR, "Failed to open DRM node '%s'", render_name); + } + free(render_name); + return render_fd; +} + struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd) { struct wlr_egl *egl = egl_create(); if (egl == NULL) { @@ -447,8 +469,15 @@ struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd) { } if (egl->exts.KHR_platform_gbm) { - egl->gbm_device = gbm_create_device(drm_fd); + int gbm_fd = open_render_node(drm_fd); + if (gbm_fd < 0) { + wlr_log(WLR_ERROR, "Failed to open DRM render node"); + goto error; + } + + egl->gbm_device = gbm_create_device(gbm_fd); if (!egl->gbm_device) { + close(gbm_fd); wlr_log(WLR_ERROR, "Failed to create GBM device"); goto error; } @@ -459,6 +488,7 @@ struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd) { } gbm_device_destroy(egl->gbm_device); + close(gbm_fd); } else { wlr_log(WLR_DEBUG, "KHR_platform_gbm not supported"); } @@ -490,7 +520,9 @@ void wlr_egl_destroy(struct wlr_egl *egl) { eglReleaseThread(); if (egl->gbm_device) { + int gbm_fd = gbm_device_get_fd(egl->gbm_device); gbm_device_destroy(egl->gbm_device); + close(gbm_fd); } free(egl); |