aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/headless/backend.c83
-rw-r--r--backend/headless/output.c10
-rw-r--r--include/backend/headless.h3
-rw-r--r--include/wlr/backend/headless.h5
4 files changed, 69 insertions, 32 deletions
diff --git a/backend/headless/backend.c b/backend/headless/backend.c
index 73ec9ebd..8eadd3b7 100644
--- a/backend/headless/backend.c
+++ b/backend/headless/backend.c
@@ -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,36 +139,41 @@ 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:
- free(backend);
- return NULL;
+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) {
diff --git a/backend/headless/output.c b/backend/headless/output.c
index 0f6a1549..dc0a1478 100644
--- a/backend/headless/output.c
+++ b/backend/headless/output.c
@@ -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);
}
diff --git a/include/backend/headless.h b/include/backend/headless.h
index d8cb4dc2..564cb154 100644
--- a/include/backend/headless.h
+++ b/include/backend/headless.h
@@ -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;
diff --git a/include/wlr/backend/headless.h b/include/wlr/backend/headless.h
index eab102e2..f9481228 100644
--- a/include/wlr/backend/headless.h
+++ b/include/wlr/backend/headless.h
@@ -20,6 +20,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
* otherwise not displayed.