backend/headless: add wlr_headless_backend_create_with_renderer
This allows one to create a headless backend with an existing renderer.
This commit is contained in:
parent
40513f1a0e
commit
6129a6f93e
|
@ -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,41 +87,15 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
|||
backend_destroy(&backend->backend);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
|
||||
static const EGLint config_attribs[] = {
|
||||
EGL_SURFACE_TYPE, 0,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_BLUE_SIZE, 1,
|
||||
EGL_GREEN_SIZE, 1,
|
||||
EGL_RED_SIZE, 1,
|
||||
EGL_NONE,
|
||||
};
|
||||
|
||||
if (!create_renderer_func) {
|
||||
create_renderer_func = wlr_renderer_autocreate;
|
||||
}
|
||||
|
||||
backend->renderer = create_renderer_func(&backend->egl,
|
||||
EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY,
|
||||
(EGLint*)config_attribs, 0);
|
||||
if (!backend->renderer) {
|
||||
wlr_log(WLR_ERROR, "Failed to create renderer");
|
||||
goto error_backend;
|
||||
}
|
||||
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,
|
||||
|
@ -136,15 +112,70 @@ struct wlr_backend *wlr_headless_backend_create(struct wl_display *display,
|
|||
backend->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &backend->display_destroy);
|
||||
|
||||
return &backend->backend;
|
||||
return true;
|
||||
}
|
||||
|
||||
error_renderer:
|
||||
wlr_renderer_destroy(backend->renderer);
|
||||
error_backend:
|
||||
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");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static const EGLint config_attribs[] = {
|
||||
EGL_SURFACE_TYPE, 0,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_BLUE_SIZE, 1,
|
||||
EGL_GREEN_SIZE, 1,
|
||||
EGL_RED_SIZE, 1,
|
||||
EGL_NONE,
|
||||
};
|
||||
|
||||
if (!create_renderer_func) {
|
||||
create_renderer_func = wlr_renderer_autocreate;
|
||||
}
|
||||
|
||||
struct wlr_renderer *renderer = create_renderer_func(&backend->priv_egl,
|
||||
EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY,
|
||||
(EGLint*)config_attribs, 0);
|
||||
if (!renderer) {
|
||||
wlr_log(WLR_ERROR, "Failed to create renderer");
|
||||
free(backend);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!backend_init(backend, display, renderer)) {
|
||||
wlr_renderer_destroy(backend->renderer);
|
||||
free(backend);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &backend->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;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ static struct wlr_headless_output *headless_output_from_output(
|
|||
|
||||
static bool create_fbo(struct wlr_headless_output *output,
|
||||
unsigned int width, unsigned int height) {
|
||||
if (!wlr_egl_make_current(&output->backend->egl, EGL_NO_SURFACE, NULL)) {
|
||||
if (!wlr_egl_make_current(output->backend->egl, EGL_NO_SURFACE, NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ static bool create_fbo(struct wlr_headless_output *output,
|
|||
}
|
||||
|
||||
static void destroy_fbo(struct wlr_headless_output *output) {
|
||||
if (!wlr_egl_make_current(&output->backend->egl, EGL_NO_SURFACE, NULL)) {
|
||||
if (!wlr_egl_make_current(output->backend->egl, EGL_NO_SURFACE, NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ static bool output_attach_render(struct wlr_output *wlr_output,
|
|||
struct wlr_headless_output *output =
|
||||
headless_output_from_output(wlr_output);
|
||||
|
||||
if (!wlr_egl_make_current(&output->backend->egl, EGL_NO_SURFACE, NULL)) {
|
||||
if (!wlr_egl_make_current(output->backend->egl, EGL_NO_SURFACE, NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ static bool output_commit(struct wlr_output *wlr_output) {
|
|||
wlr_output_send_present(wlr_output, NULL);
|
||||
}
|
||||
|
||||
wlr_egl_make_current(&output->backend->egl, EGL_NO_SURFACE, NULL);
|
||||
wlr_egl_make_current(output->backend->egl, EGL_NO_SURFACE, NULL);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
return true;
|
||||
|
@ -138,7 +138,7 @@ static bool output_commit(struct wlr_output *wlr_output) {
|
|||
static void output_rollback(struct wlr_output *wlr_output) {
|
||||
struct wlr_headless_output *output =
|
||||
headless_output_from_output(wlr_output);
|
||||
wlr_egl_make_current(&output->backend->egl, EGL_NO_SURFACE, NULL);
|
||||
wlr_egl_make_current(output->backend->egl, EGL_NO_SURFACE, NULL);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
struct wlr_headless_backend {
|
||||
struct wlr_backend backend;
|
||||
struct wlr_egl egl;
|
||||
struct wlr_egl priv_egl; // may be uninitialized
|
||||
struct wlr_egl *egl;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wl_display *display;
|
||||
struct wl_list outputs;
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
*/
|
||||
struct wlr_backend *wlr_headless_backend_create(struct wl_display *display,
|
||||
wlr_renderer_create_func_t create_renderer_func);
|
||||
/**
|
||||
* Creates a headless backend with an existing renderer.
|
||||
*/
|
||||
struct wlr_backend *wlr_headless_backend_create_with_renderer(
|
||||
struct wl_display *display, struct wlr_renderer *renderer);
|
||||
/**
|
||||
* Create a new headless output backed by an in-memory EGL framebuffer. You can
|
||||
* read pixels from this framebuffer via wlr_renderer_read_pixels but it is
|
||||
|
|
Loading…
Reference in New Issue