headless: Enable use as a secondary backend

Conditionally create the renderer like other secondary backends.

Now that we have multi-backend support and overlapping outputs, an
interesting use case for the headless backend exists.

We can have a high performance steady state on the drm backend with
all content on scan-out planes, bypassing the renderer. Taking a
screenshot of this would ideally use readback, but some hardware is
incapable of readback, or only capable at certain resolutions.

By using the headless backend as a secondary backend, and creating a
headless output that overlaps the drm outputs, we can take the
screenshot on the headless backend without disrupting the plane
layout on the drm backend.

For this to be efficient, other changes need to be made, but this is
a step in that direction.

Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
Derek Foreman 2023-09-30 09:56:09 -05:00
parent e622be7423
commit e3a509236b

View File

@ -559,55 +559,57 @@ headless_backend_create(struct weston_compositor *compositor,
b->formats_count = ARRAY_LENGTH(headless_formats); b->formats_count = ARRAY_LENGTH(headless_formats);
b->formats = pixel_format_get_array(headless_formats, b->formats_count); b->formats = pixel_format_get_array(headless_formats, b->formats_count);
switch (config->renderer) { if (!compositor->renderer) {
case WESTON_RENDERER_GL: { switch (config->renderer) {
const struct gl_renderer_display_options options = { case WESTON_RENDERER_GL: {
.egl_platform = EGL_PLATFORM_SURFACELESS_MESA, const struct gl_renderer_display_options options = {
.egl_native_display = NULL, .egl_platform = EGL_PLATFORM_SURFACELESS_MESA,
.formats = b->formats, .egl_native_display = NULL,
.formats_count = b->formats_count, .formats = b->formats,
}; .formats_count = b->formats_count,
ret = weston_compositor_init_renderer(compositor, };
WESTON_RENDERER_GL, ret = weston_compositor_init_renderer(compositor,
&options.base); WESTON_RENDERER_GL,
break; &options.base);
} break;
case WESTON_RENDERER_PIXMAN:
if (config->decorate) {
weston_log("Error: Pixman renderer does not support decorations.\n");
goto err_input;
} }
ret = weston_compositor_init_renderer(compositor, case WESTON_RENDERER_PIXMAN:
WESTON_RENDERER_PIXMAN, if (config->decorate) {
NULL); weston_log("Error: Pixman renderer does not support decorations.\n");
break; goto err_input;
case WESTON_RENDERER_AUTO: }
case WESTON_RENDERER_NOOP: ret = weston_compositor_init_renderer(compositor,
if (config->decorate) { WESTON_RENDERER_PIXMAN,
weston_log("Error: no-op renderer does not support decorations.\n"); NULL);
goto err_input; break;
case WESTON_RENDERER_AUTO:
case WESTON_RENDERER_NOOP:
if (config->decorate) {
weston_log("Error: no-op renderer does not support decorations.\n");
goto err_input;
}
ret = noop_renderer_init(compositor);
break;
default:
weston_log("Error: unsupported renderer\n");
break;
} }
ret = noop_renderer_init(compositor);
break;
default:
weston_log("Error: unsupported renderer\n");
break;
}
if (ret < 0) if (ret < 0)
goto err_input;
if (compositor->renderer->import_dmabuf) {
if (linux_dmabuf_setup(compositor) < 0) {
weston_log("Error: dmabuf protocol setup failed.\n");
goto err_input; goto err_input;
}
}
/* Support zwp_linux_explicit_synchronization_unstable_v1 to enable if (compositor->renderer->import_dmabuf) {
* testing. */ if (linux_dmabuf_setup(compositor) < 0) {
if (linux_explicit_synchronization_setup(compositor) < 0) weston_log("Error: dmabuf protocol setup failed.\n");
goto err_input; goto err_input;
}
}
/* Support zwp_linux_explicit_synchronization_unstable_v1 to enable
* testing. */
if (linux_explicit_synchronization_setup(compositor) < 0)
goto err_input;
}
ret = weston_plugin_api_register(compositor, WESTON_WINDOWED_OUTPUT_API_NAME, ret = weston_plugin_api_register(compositor, WESTON_WINDOWED_OUTPUT_API_NAME,
&api, sizeof(api)); &api, sizeof(api));
@ -647,11 +649,6 @@ weston_backend_init(struct weston_compositor *compositor,
return -1; return -1;
} }
if (compositor->renderer) {
weston_log("headless backend must be the primary backend\n");
return -1;
}
config_init_to_defaults(&config); config_init_to_defaults(&config);
memcpy(&config, config_base, config_base->struct_size); memcpy(&config, config_base, config_base->struct_size);