|
|
|
@ -62,7 +62,9 @@ static void backend_destroy(struct wlr_backend *wlr_backend) {
|
|
|
|
|
wlr_signal_emit_safe(&wlr_backend->events.destroy, backend);
|
|
|
|
|
|
|
|
|
|
wlr_renderer_destroy(backend->renderer);
|
|
|
|
|
wlr_egl_finish(&backend->egl);
|
|
|
|
|
if (backend->egl == &backend->priv_egl) {
|
|
|
|
|
wlr_egl_finish(&backend->priv_egl);
|
|
|
|
|
}
|
|
|
|
|
free(backend);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -85,6 +87,34 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
|
|
|
|
backend_destroy(&backend->backend);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool backend_init(struct wlr_headless_backend *backend,
|
|
|
|
|
struct wl_display *display, struct wlr_renderer *renderer) {
|
|
|
|
|
wlr_backend_init(&backend->backend, &backend_impl);
|
|
|
|
|
backend->display = display;
|
|
|
|
|
wl_list_init(&backend->outputs);
|
|
|
|
|
wl_list_init(&backend->input_devices);
|
|
|
|
|
|
|
|
|
|
backend->renderer = renderer;
|
|
|
|
|
backend->egl = wlr_gles2_renderer_get_egl(renderer);
|
|
|
|
|
|
|
|
|
|
if (wlr_gles2_renderer_check_ext(backend->renderer, "GL_OES_rgb8_rgba8") ||
|
|
|
|
|
wlr_gles2_renderer_check_ext(backend->renderer,
|
|
|
|
|
"GL_OES_required_internalformat") ||
|
|
|
|
|
wlr_gles2_renderer_check_ext(backend->renderer, "GL_ARM_rgba8")) {
|
|
|
|
|
backend->internal_format = GL_RGBA8_OES;
|
|
|
|
|
} else {
|
|
|
|
|
wlr_log(WLR_INFO, "GL_RGBA8_OES not supported, "
|
|
|
|
|
"falling back to GL_RGBA4 internal format "
|
|
|
|
|
"(performance may be affected)");
|
|
|
|
|
backend->internal_format = GL_RGBA4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
backend->display_destroy.notify = handle_display_destroy;
|
|
|
|
|
wl_display_add_destroy_listener(display, &backend->display_destroy);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct wlr_backend *wlr_headless_backend_create(struct wl_display *display,
|
|
|
|
|
wlr_renderer_create_func_t create_renderer_func) {
|
|
|
|
|
wlr_log(WLR_INFO, "Creating headless backend");
|
|
|
|
@ -95,10 +125,6 @@ struct wlr_backend *wlr_headless_backend_create(struct wl_display *display,
|
|
|
|
|
wlr_log(WLR_ERROR, "Failed to allocate wlr_headless_backend");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
wlr_backend_init(&backend->backend, &backend_impl);
|
|
|
|
|
backend->display = display;
|
|
|
|
|
wl_list_init(&backend->outputs);
|
|
|
|
|
wl_list_init(&backend->input_devices);
|
|
|
|
|
|
|
|
|
|
static const EGLint config_attribs[] = {
|
|
|
|
|
EGL_SURFACE_TYPE, 0,
|
|
|
|
@ -113,38 +139,43 @@ struct wlr_backend *wlr_headless_backend_create(struct wl_display *display,
|
|
|
|
|
create_renderer_func = wlr_renderer_autocreate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
backend->renderer = create_renderer_func(&backend->egl,
|
|
|
|
|
struct wlr_renderer *renderer = create_renderer_func(&backend->priv_egl,
|
|
|
|
|
EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY,
|
|
|
|
|
(EGLint*)config_attribs, 0);
|
|
|
|
|
if (!backend->renderer) {
|
|
|
|
|
if (!renderer) {
|
|
|
|
|
wlr_log(WLR_ERROR, "Failed to create renderer");
|
|
|
|
|
goto error_backend;
|
|
|
|
|
free(backend);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (wlr_gles2_renderer_check_ext(backend->renderer, "GL_OES_rgb8_rgba8") ||
|
|
|
|
|
wlr_gles2_renderer_check_ext(backend->renderer,
|
|
|
|
|
"GL_OES_required_internalformat") ||
|
|
|
|
|
wlr_gles2_renderer_check_ext(backend->renderer, "GL_ARM_rgba8")) {
|
|
|
|
|
backend->internal_format = GL_RGBA8_OES;
|
|
|
|
|
} else {
|
|
|
|
|
wlr_log(WLR_INFO, "GL_RGBA8_OES not supported, "
|
|
|
|
|
"falling back to GL_RGBA4 internal format "
|
|
|
|
|
"(performance may be affected)");
|
|
|
|
|
backend->internal_format = GL_RGBA4;
|
|
|
|
|
if (!backend_init(backend, display, renderer)) {
|
|
|
|
|
wlr_renderer_destroy(backend->renderer);
|
|
|
|
|
free(backend);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
backend->display_destroy.notify = handle_display_destroy;
|
|
|
|
|
wl_display_add_destroy_listener(display, &backend->display_destroy);
|
|
|
|
|
|
|
|
|
|
return &backend->backend;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error_renderer:
|
|
|
|
|
wlr_renderer_destroy(backend->renderer);
|
|
|
|
|
error_backend:
|
|
|
|
|
struct wlr_backend *wlr_headless_backend_create_with_renderer(
|
|
|
|
|
struct wl_display *display, struct wlr_renderer *renderer) {
|
|
|
|
|
wlr_log(WLR_INFO, "Creating headless backend");
|
|
|
|
|
|
|
|
|
|
struct wlr_headless_backend *backend =
|
|
|
|
|
calloc(1, sizeof(struct wlr_headless_backend));
|
|
|
|
|
if (!backend) {
|
|
|
|
|
wlr_log(WLR_ERROR, "Failed to allocate wlr_headless_backend");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!backend_init(backend, display, renderer)) {
|
|
|
|
|
free(backend);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &backend->backend;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool wlr_backend_is_headless(struct wlr_backend *backend) {
|
|
|
|
|
return backend->impl == &backend_impl;
|
|
|
|
|
}
|
|
|
|
|