aboutsummaryrefslogtreecommitdiff
path: root/render/egl.c
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2021-08-23 18:39:31 +0200
committerSimon Zeni <simon@bl4ckb0ne.ca>2021-08-25 10:05:37 -0400
commit749b3c00f0d0cb3575c8f058ea8c5e9877d4fd9c (patch)
treef97e7a44268d263dfbbe28bca3c9323433fdd573 /render/egl.c
parent3ce2ea9e16fcd1bfab4ec9d5994fa721c5d58dcd (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.c34
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);