From 6d6c653b5f08b9601c56a3f1fb442137b659700f Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 18 Jul 2019 08:39:24 -0700 Subject: [PATCH] virglrenderer: open rendernode even for EGL_MESA_platform_surfaceless It is possible to open rendernodes when using EGL_MESA_platform_surfaceless. v2: fail if user-provided fd fails (@davidriley) Reviewed-by: David Riley Signed-off-by: Gurchetan Singh --- src/virgl_egl.h | 3 ++- src/virgl_egl_context.c | 38 ++++++-------------------------------- src/virglrenderer.c | 30 ++++++++++++++++++++++++++---- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/src/virgl_egl.h b/src/virgl_egl.h index 180cfb5..35b3d62 100644 --- a/src/virgl_egl.h +++ b/src/virgl_egl.h @@ -26,8 +26,9 @@ #include "vrend_renderer.h" struct virgl_egl; +struct virgl_gbm; -struct virgl_egl *virgl_egl_init(int fd, bool surfaceless, bool gles); +struct virgl_egl *virgl_egl_init(struct virgl_gbm *gbm, bool surfaceless, bool gles); void virgl_egl_destroy(struct virgl_egl *egl); diff --git a/src/virgl_egl_context.c b/src/virgl_egl_context.c index 90a2d3f..a08acc4 100644 --- a/src/virgl_egl_context.c +++ b/src/virgl_egl_context.c @@ -82,7 +82,7 @@ static bool virgl_egl_has_extension_in_string(const char *haystack, const char * return false; } -struct virgl_egl *virgl_egl_init(int fd, bool surfaceless, bool gles) +struct virgl_egl *virgl_egl_init(struct virgl_gbm *gbm, bool surfaceless, bool gles) { static EGLint conf_att[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, @@ -110,28 +110,12 @@ struct virgl_egl *virgl_egl_init(int fd, bool surfaceless, bool gles) if (gles) conf_att[3] = EGL_OPENGL_ES2_BIT; - /* - * The surfaceless flag (specified with VIRGL_RENDERER_USE_SURFACELESS) - * takes precedence and will attempt to get a display of type - * EGL_PLATFORM_SURFACELESS_MESA. - * If surfaceless is not specified, an fd supplied with the get_drm_fd - * is used to open a GBM device. - * If not provided, /dev/dri rendernodes are scanned and used to open - * a GBM device. - * If none of the above results in a valid display, a fallback will be - * done to use the default display, as long as an fd hasn't been explicitly - * provided. - */ - - if (surfaceless) { + if (surfaceless) conf_att[1] = EGL_PBUFFER_BIT; - egl->gbm = NULL; - } else { - egl->gbm = virgl_gbm_init(fd); - if (!egl->gbm) - goto fail; - } + else if (!gbm) + goto fail; + egl->gbm = gbm; const char *client_extensions = eglQueryString (NULL, EGL_EXTENSIONS); if (strstr (client_extensions, "EGL_KHR_platform_base")) { @@ -169,14 +153,9 @@ struct virgl_egl *virgl_egl_init(int fd, bool surfaceless, bool gles) * Don't fallback to the default display if the fd provided by (*get_drm_fd) * can't be used. */ - if (fd >= 0) + if (egl->gbm && egl->gbm->fd < 0) goto fail; - if (egl->gbm) { - virgl_gbm_fini(egl->gbm); - egl->gbm = NULL; - } - egl->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (!egl->egl_display) goto fail; @@ -246,9 +225,6 @@ struct virgl_egl *virgl_egl_init(int fd, bool surfaceless, bool gles) return egl; fail: - if (egl->gbm) - virgl_gbm_fini(egl->gbm); - free(egl); return NULL; } @@ -259,8 +235,6 @@ void virgl_egl_destroy(struct virgl_egl *egl) EGL_NO_CONTEXT); eglDestroyContext(egl->egl_display, egl->egl_ctx); eglTerminate(egl->egl_display); - if (egl->gbm) - virgl_gbm_fini(egl->gbm); free(egl); } diff --git a/src/virglrenderer.c b/src/virglrenderer.c index b5ad0fa..ab68846 100644 --- a/src/virglrenderer.c +++ b/src/virglrenderer.c @@ -39,8 +39,10 @@ #include "virglrenderer.h" #ifdef HAVE_EPOXY_EGL_H +#include "virgl_gbm.h" #include "virgl_egl.h" -static struct virgl_egl *egl; +static struct virgl_gbm *gbm = NULL; +static struct virgl_egl *egl = NULL; #endif #ifdef HAVE_EPOXY_GLX_H @@ -312,6 +314,10 @@ void virgl_renderer_cleanup(UNUSED void *cookie) virgl_egl_destroy(egl); egl = NULL; use_context = CONTEXT_NONE; + if (gbm) { + virgl_gbm_fini(gbm); + gbm = NULL; + } } #endif #ifdef HAVE_EPOXY_GLX_H @@ -341,10 +347,26 @@ int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks if (cbs->version >= 2 && cbs->get_drm_fd) { fd = cbs->get_drm_fd(cookie); } - egl = virgl_egl_init(fd, flags & VIRGL_RENDERER_USE_SURFACELESS, - flags & VIRGL_RENDERER_USE_GLES); - if (!egl) + + /* + * If the user specifies a preferred DRM fd and we can't use it, fail. If the user doesn't + * specify an fd, it's possible to initialize EGL without one. + */ + gbm = virgl_gbm_init(fd); + if (fd > 0 && !gbm) return -1; + + egl = virgl_egl_init(gbm, flags & VIRGL_RENDERER_USE_SURFACELESS, + flags & VIRGL_RENDERER_USE_GLES); + if (!egl) { + if (gbm) { + virgl_gbm_fini(gbm); + gbm = NULL; + } + + return -1; + } + use_context = CONTEXT_EGL; #else vrend_printf( "EGL is not supported on this platform\n");