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 <davidriley@chromium.org>
Signed-off-by: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Gurchetan Singh 5 years ago
parent 4cade493dc
commit 6d6c653b5f
  1. 3
      src/virgl_egl.h
  2. 38
      src/virgl_egl_context.c
  3. 30
      src/virglrenderer.c

@ -26,8 +26,9 @@
#include "vrend_renderer.h" #include "vrend_renderer.h"
struct virgl_egl; 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); void virgl_egl_destroy(struct virgl_egl *egl);

@ -82,7 +82,7 @@ static bool virgl_egl_has_extension_in_string(const char *haystack, const char *
return false; 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[] = { static EGLint conf_att[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
@ -110,28 +110,12 @@ struct virgl_egl *virgl_egl_init(int fd, bool surfaceless, bool gles)
if (gles) if (gles)
conf_att[3] = EGL_OPENGL_ES2_BIT; conf_att[3] = EGL_OPENGL_ES2_BIT;
/* if (surfaceless)
* 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) {
conf_att[1] = EGL_PBUFFER_BIT; conf_att[1] = EGL_PBUFFER_BIT;
egl->gbm = NULL; else if (!gbm)
} else { goto fail;
egl->gbm = virgl_gbm_init(fd);
if (!egl->gbm)
goto fail;
}
egl->gbm = gbm;
const char *client_extensions = eglQueryString (NULL, EGL_EXTENSIONS); const char *client_extensions = eglQueryString (NULL, EGL_EXTENSIONS);
if (strstr (client_extensions, "EGL_KHR_platform_base")) { 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) * Don't fallback to the default display if the fd provided by (*get_drm_fd)
* can't be used. * can't be used.
*/ */
if (fd >= 0) if (egl->gbm && egl->gbm->fd < 0)
goto fail; goto fail;
if (egl->gbm) {
virgl_gbm_fini(egl->gbm);
egl->gbm = NULL;
}
egl->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); egl->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (!egl->egl_display) if (!egl->egl_display)
goto fail; goto fail;
@ -246,9 +225,6 @@ struct virgl_egl *virgl_egl_init(int fd, bool surfaceless, bool gles)
return egl; return egl;
fail: fail:
if (egl->gbm)
virgl_gbm_fini(egl->gbm);
free(egl); free(egl);
return NULL; return NULL;
} }
@ -259,8 +235,6 @@ void virgl_egl_destroy(struct virgl_egl *egl)
EGL_NO_CONTEXT); EGL_NO_CONTEXT);
eglDestroyContext(egl->egl_display, egl->egl_ctx); eglDestroyContext(egl->egl_display, egl->egl_ctx);
eglTerminate(egl->egl_display); eglTerminate(egl->egl_display);
if (egl->gbm)
virgl_gbm_fini(egl->gbm);
free(egl); free(egl);
} }

@ -39,8 +39,10 @@
#include "virglrenderer.h" #include "virglrenderer.h"
#ifdef HAVE_EPOXY_EGL_H #ifdef HAVE_EPOXY_EGL_H
#include "virgl_gbm.h"
#include "virgl_egl.h" #include "virgl_egl.h"
static struct virgl_egl *egl; static struct virgl_gbm *gbm = NULL;
static struct virgl_egl *egl = NULL;
#endif #endif
#ifdef HAVE_EPOXY_GLX_H #ifdef HAVE_EPOXY_GLX_H
@ -312,6 +314,10 @@ void virgl_renderer_cleanup(UNUSED void *cookie)
virgl_egl_destroy(egl); virgl_egl_destroy(egl);
egl = NULL; egl = NULL;
use_context = CONTEXT_NONE; use_context = CONTEXT_NONE;
if (gbm) {
virgl_gbm_fini(gbm);
gbm = NULL;
}
} }
#endif #endif
#ifdef HAVE_EPOXY_GLX_H #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) { if (cbs->version >= 2 && cbs->get_drm_fd) {
fd = cbs->get_drm_fd(cookie); 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; 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; use_context = CONTEXT_EGL;
#else #else
vrend_printf( "EGL is not supported on this platform\n"); vrend_printf( "EGL is not supported on this platform\n");

Loading…
Cancel
Save