Revert "render: add wlr_egl_create_from_drm_fd function"

This reverts commit ee31be167b.
This commit is contained in:
Simon Ser 2021-01-20 21:20:55 +01:00
parent 54e5ef39c0
commit 7c995b78b2
3 changed files with 46 additions and 149 deletions

View file

@ -53,9 +53,6 @@ struct wlr_egl {
// Device extensions // Device extensions
bool device_drm_ext; bool device_drm_ext;
// Client extensions
bool device_query_ext;
} exts; } exts;
struct { struct {
@ -73,7 +70,6 @@ struct wlr_egl {
PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR; PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR;
PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT; PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT;
PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT; PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT;
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT;
} procs; } procs;
struct wl_display *wl_display; struct wl_display *wl_display;
@ -91,15 +87,6 @@ struct wlr_egl {
struct wlr_egl *wlr_egl_create(EGLenum platform, void *remote_display, struct wlr_egl *wlr_egl_create(EGLenum platform, void *remote_display,
const EGLint *config_attribs); const EGLint *config_attribs);
/**
* Creates and EGL context from a given drm fd. This function uses the
* following extensions:
* - EXT_device_enumeration to get the list of available EGLDeviceEXT
* - EXT_device_drm to get the name of the EGLDeviceEXT
* - EXT_platform_device to create an EGLDisplay from an EGLDeviceEXT
*/
struct wlr_egl *wlr_egl_create_from_drm_fd(int drm_fd);
/** /**
* Frees all related EGL resources, makes the context not-current and * Frees all related EGL resources, makes the context not-current and
* unbinds a bound wayland display. * unbinds a bound wayland display.

View file

@ -150,7 +150,8 @@ out:
free(formats); free(formats);
} }
static struct wlr_egl *egl_create(void) { struct wlr_egl *wlr_egl_create(EGLenum platform, void *remote_display,
const EGLint *config_attribs) {
struct wlr_egl *egl = calloc(1, sizeof(struct wlr_egl)); struct wlr_egl *egl = calloc(1, sizeof(struct wlr_egl));
if (egl == NULL) { if (egl == NULL) {
wlr_log_errno(WLR_ERROR, "Allocation failed"); wlr_log_errno(WLR_ERROR, "Allocation failed");
@ -166,7 +167,6 @@ static struct wlr_egl *egl_create(void) {
} }
return NULL; return NULL;
} }
wlr_log(WLR_INFO, "Supported EGL client extensions: %s", client_exts_str);
if (!check_egl_ext(client_exts_str, "EGL_EXT_platform_base")) { if (!check_egl_ext(client_exts_str, "EGL_EXT_platform_base")) {
wlr_log(WLR_ERROR, "EGL_EXT_platform_base not supported"); wlr_log(WLR_ERROR, "EGL_EXT_platform_base not supported");
@ -177,18 +177,6 @@ static struct wlr_egl *egl_create(void) {
load_egl_proc(&egl->procs.eglCreatePlatformWindowSurfaceEXT, load_egl_proc(&egl->procs.eglCreatePlatformWindowSurfaceEXT,
"eglCreatePlatformWindowSurfaceEXT"); "eglCreatePlatformWindowSurfaceEXT");
if (check_egl_ext(client_exts_str, "EGL_EXT_device_enumeration")) {
load_egl_proc(&egl->procs.eglQueryDevicesEXT, "eglQueryDevicesEXT");
}
if (check_egl_ext(client_exts_str, "EGL_EXT_device_query")) {
egl->exts.device_query_ext = true;
load_egl_proc(&egl->procs.eglQueryDeviceStringEXT,
"eglQueryDeviceStringEXT");
load_egl_proc(&egl->procs.eglQueryDisplayAttribEXT,
"eglQueryDisplayAttribEXT");
}
if (check_egl_ext(client_exts_str, "EGL_KHR_debug")) { if (check_egl_ext(client_exts_str, "EGL_KHR_debug")) {
load_egl_proc(&egl->procs.eglDebugMessageControlKHR, load_egl_proc(&egl->procs.eglDebugMessageControlKHR,
"eglDebugMessageControlKHR"); "eglDebugMessageControlKHR");
@ -205,31 +193,26 @@ static struct wlr_egl *egl_create(void) {
if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) { if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
wlr_log(WLR_ERROR, "Failed to bind to the OpenGL ES API"); wlr_log(WLR_ERROR, "Failed to bind to the OpenGL ES API");
return NULL; goto error;
} }
return egl;
}
static bool egl_init(struct wlr_egl *egl, EGLenum platform,
void *remote_display, const EGLint *config_attribs) {
egl->display = egl->procs.eglGetPlatformDisplayEXT(platform, egl->display = egl->procs.eglGetPlatformDisplayEXT(platform,
remote_display, NULL); remote_display, NULL);
if (egl->display == EGL_NO_DISPLAY) { if (egl->display == EGL_NO_DISPLAY) {
wlr_log(WLR_ERROR, "Failed to create EGL display"); wlr_log(WLR_ERROR, "Failed to create EGL display");
return false; goto error;
} }
EGLint major, minor; EGLint major, minor;
if (eglInitialize(egl->display, &major, &minor) == EGL_FALSE) { if (eglInitialize(egl->display, &major, &minor) == EGL_FALSE) {
wlr_log(WLR_ERROR, "Failed to initialize EGL"); wlr_log(WLR_ERROR, "Failed to initialize EGL");
return false; goto error;
} }
const char *display_exts_str = eglQueryString(egl->display, EGL_EXTENSIONS); const char *display_exts_str = eglQueryString(egl->display, EGL_EXTENSIONS);
if (display_exts_str == NULL) { if (display_exts_str == NULL) {
wlr_log(WLR_ERROR, "Failed to query EGL display extensions"); wlr_log(WLR_ERROR, "Failed to query EGL display extensions");
return false; return NULL;
} }
if (check_egl_ext(display_exts_str, "EGL_KHR_image_base")) { if (check_egl_ext(display_exts_str, "EGL_KHR_image_base")) {
@ -268,12 +251,17 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
} }
const char *device_exts_str = NULL; const char *device_exts_str = NULL;
if (egl->exts.device_query_ext) { if (check_egl_ext(client_exts_str, "EGL_EXT_device_query")) {
load_egl_proc(&egl->procs.eglQueryDisplayAttribEXT,
"eglQueryDisplayAttribEXT");
load_egl_proc(&egl->procs.eglQueryDeviceStringEXT,
"eglQueryDeviceStringEXT");
EGLAttrib device_attrib; EGLAttrib device_attrib;
if (!egl->procs.eglQueryDisplayAttribEXT(egl->display, if (!egl->procs.eglQueryDisplayAttribEXT(egl->display,
EGL_DEVICE_EXT, &device_attrib)) { EGL_DEVICE_EXT, &device_attrib)) {
wlr_log(WLR_ERROR, "eglQueryDisplayAttribEXT(EGL_DEVICE_EXT) failed"); wlr_log(WLR_ERROR, "eglQueryDisplayAttribEXT(EGL_DEVICE_EXT) failed");
return false; goto error;
} }
egl->device = (EGLDeviceEXT)device_attrib; egl->device = (EGLDeviceEXT)device_attrib;
@ -281,7 +269,7 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
egl->procs.eglQueryDeviceStringEXT(egl->device, EGL_EXTENSIONS); egl->procs.eglQueryDeviceStringEXT(egl->device, EGL_EXTENSIONS);
if (device_exts_str == NULL) { if (device_exts_str == NULL) {
wlr_log(WLR_ERROR, "eglQueryDeviceStringEXT(EGL_EXTENSIONS) failed"); wlr_log(WLR_ERROR, "eglQueryDeviceStringEXT(EGL_EXTENSIONS) failed");
return false; goto error;
} }
egl->exts.device_drm_ext = egl->exts.device_drm_ext =
@ -293,27 +281,28 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
if (!eglChooseConfig(egl->display, config_attribs, &egl->config, 1, if (!eglChooseConfig(egl->display, config_attribs, &egl->config, 1,
&matched)) { &matched)) {
wlr_log(WLR_ERROR, "eglChooseConfig failed"); wlr_log(WLR_ERROR, "eglChooseConfig failed");
return false; goto error;
} }
if (matched == 0) { if (matched == 0) {
wlr_log(WLR_ERROR, "Failed to match an EGL config"); wlr_log(WLR_ERROR, "Failed to match an EGL config");
return false; goto error;
} }
} else { } else {
if (!check_egl_ext(display_exts_str, "EGL_KHR_no_config_context") && if (!check_egl_ext(display_exts_str, "EGL_KHR_no_config_context") &&
!check_egl_ext(display_exts_str, "EGL_MESA_configless_context")) { !check_egl_ext(display_exts_str, "EGL_MESA_configless_context")) {
wlr_log(WLR_ERROR, "EGL_KHR_no_config_context or " wlr_log(WLR_ERROR, "EGL_KHR_no_config_context or "
"EGL_MESA_configless_context not supported"); "EGL_MESA_configless_context not supported");
return false; goto error;
} }
egl->config = EGL_NO_CONFIG_KHR; egl->config = EGL_NO_CONFIG_KHR;
} }
wlr_log(WLR_INFO, "Using EGL %d.%d", (int)major, (int)minor);
wlr_log(WLR_INFO, "Supported EGL client extensions: %s", client_exts_str);
wlr_log(WLR_INFO, "Supported EGL display extensions: %s", display_exts_str); wlr_log(WLR_INFO, "Supported EGL display extensions: %s", display_exts_str);
if (device_exts_str != NULL) { if (device_exts_str != NULL) {
wlr_log(WLR_INFO, "Supported EGL device extensions: %s", device_exts_str); wlr_log(WLR_INFO, "Supported EGL device extensions: %s", device_exts_str);
} }
wlr_log(WLR_INFO, "Using EGL %d.%d", (int)major, (int)minor);
wlr_log(WLR_INFO, "EGL vendor: %s", eglQueryString(egl->display, EGL_VENDOR)); wlr_log(WLR_INFO, "EGL vendor: %s", eglQueryString(egl->display, EGL_VENDOR));
init_dmabuf_formats(egl); init_dmabuf_formats(egl);
@ -328,8 +317,7 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
// On DRM, request a high priority context if possible // On DRM, request a high priority context if possible
bool request_high_priority = ext_context_priority && bool request_high_priority = ext_context_priority &&
(platform == EGL_PLATFORM_GBM_MESA platform == EGL_PLATFORM_GBM_MESA;
|| platform == EGL_PLATFORM_DEVICE_EXT);
// Try to reschedule all of our rendering to be completed first. If it // Try to reschedule all of our rendering to be completed first. If it
// fails, it will fallback to the default priority (MEDIUM). // fails, it will fallback to the default priority (MEDIUM).
@ -345,7 +333,7 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
EGL_NO_CONTEXT, attribs); EGL_NO_CONTEXT, attribs);
if (egl->context == EGL_NO_CONTEXT) { if (egl->context == EGL_NO_CONTEXT) {
wlr_log(WLR_ERROR, "Failed to create EGL context"); wlr_log(WLR_ERROR, "Failed to create EGL context");
return false; goto error;
} }
if (request_high_priority) { if (request_high_priority) {
@ -359,105 +347,6 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
} }
} }
return true;
}
struct wlr_egl *wlr_egl_create(EGLenum platform, void *remote_display,
const EGLint *config_attribs) {
struct wlr_egl *egl = egl_create();
if (egl == NULL) {
wlr_log(WLR_ERROR, "Failed to create EGL context");
return NULL;
}
if (!egl_init(egl, platform, remote_display, config_attribs)) {
wlr_log(WLR_ERROR, "Failed to initialize EGL context");
eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT);
if (egl->display) {
eglTerminate(egl->display);
}
free(egl);
eglReleaseThread();
return NULL;
}
return egl;
}
static bool device_has_name(const drmDevice *device, const char *name) {
for (size_t i = 0; i < DRM_NODE_MAX; i++) {
if (!(device->available_nodes & (1 << i))) {
continue;
}
if (strcmp(device->nodes[i], name) == 0) {
return true;
}
}
return false;
}
struct wlr_egl *wlr_egl_create_from_drm_fd(int drm_fd) {
struct wlr_egl *egl = egl_create();
if (egl == NULL) {
wlr_log(WLR_ERROR, "Failed to create EGL context");
return NULL;
}
if (egl->procs.eglQueryDevicesEXT == NULL) {
wlr_log(WLR_ERROR, "EGL_EXT_device_enumeration not supported");
goto error;
}
EGLint nb_devices = 0;
if (!egl->procs.eglQueryDevicesEXT(0, NULL, &nb_devices)) {
wlr_log(WLR_ERROR, "Failed to query EGL devices");
goto error;
}
EGLDeviceEXT *devices = calloc(nb_devices, sizeof(EGLDeviceEXT));
if (devices == NULL) {
wlr_log_errno(WLR_ERROR, "Failed to allocate device list");
goto error;
}
if (!egl->procs.eglQueryDevicesEXT(nb_devices, devices, &nb_devices)) {
wlr_log(WLR_ERROR, "Failed to query EGL devices");
goto error;
}
drmDevice *device = NULL;
int ret = drmGetDevice(drm_fd, &device);
if (ret < 0) {
wlr_log(WLR_ERROR, "Failed to get DRM device: %s", strerror(-ret));
goto error;
}
EGLDeviceEXT egl_device = NULL;
for (int i = 0; i < nb_devices; i++) {
const char *egl_device_name = egl->procs.eglQueryDeviceStringEXT(
devices[i], EGL_DRM_DEVICE_FILE_EXT);
if (egl_device_name == NULL) {
continue;
}
if (device_has_name(device, egl_device_name)) {
wlr_log(WLR_DEBUG, "Using EGL device %s", egl_device_name);
egl_device = devices[i];
break;
}
}
if (egl_device == NULL) {
wlr_log(WLR_ERROR, "Failed to find EGLDeviceEXT");
goto error;
}
if (!egl_init(egl, EGL_PLATFORM_DEVICE_EXT, egl_device, NULL)) {
wlr_log(WLR_ERROR, "Failed to initialize EGL context");
goto error;
}
return egl; return egl;
error: error:
@ -465,7 +354,6 @@ error:
if (egl->display) { if (egl->display) {
eglTerminate(egl->display); eglTerminate(egl->display);
} }
free(egl);
eglReleaseThread(); eglReleaseThread();
return NULL; return NULL;
} }
@ -851,6 +739,18 @@ bool wlr_egl_destroy_surface(struct wlr_egl *egl, EGLSurface surface) {
return eglDestroySurface(egl->display, surface); return eglDestroySurface(egl->display, surface);
} }
static bool device_has_name(const drmDevice *device, const char *name) {
for (size_t i = 0; i < DRM_NODE_MAX; i++) {
if (!(device->available_nodes & (1 << i))) {
continue;
}
if (strcmp(device->nodes[i], name) == 0) {
return true;
}
}
return false;
}
static char *get_render_name(const char *name) { static char *get_render_name(const char *name) {
uint32_t flags = 0; uint32_t flags = 0;
int devices_len = drmGetDevices2(flags, NULL, 0); int devices_len = drmGetDevices2(flags, NULL, 0);

View file

@ -251,12 +251,22 @@ bool wlr_renderer_init_wl_display(struct wlr_renderer *r,
} }
struct wlr_renderer *wlr_renderer_autocreate_with_drm_fd(int drm_fd) { struct wlr_renderer *wlr_renderer_autocreate_with_drm_fd(int drm_fd) {
struct wlr_egl *egl = wlr_egl_create_from_drm_fd(drm_fd); struct gbm_device *gbm_device = gbm_create_device(drm_fd);
if (egl == NULL) { if (!gbm_device) {
wlr_log(WLR_ERROR, "Could not initialize EGL"); wlr_log(WLR_ERROR, "Failed to create GBM device");
return NULL; return NULL;
} }
struct wlr_egl *egl = wlr_egl_create(EGL_PLATFORM_GBM_KHR, gbm_device,
NULL);
if (egl == NULL) {
wlr_log(WLR_ERROR, "Could not initialize EGL");
gbm_device_destroy(gbm_device);
return NULL;
}
egl->gbm_device = gbm_device;
struct wlr_renderer *renderer = wlr_gles2_renderer_create(egl); struct wlr_renderer *renderer = wlr_gles2_renderer_create(egl);
if (!renderer) { if (!renderer) {
wlr_log(WLR_ERROR, "Failed to create GLES2 renderer"); wlr_log(WLR_ERROR, "Failed to create GLES2 renderer");