frontend: Add common --renderer=foo argument

Rather than reinventing --use-pixman and --use-gl throughout each
backend, just have a common --renderer=foo argument which can be used to
explicitly specify the renderer.

The old arguments are still handled for backwards compatibility.

Signed-off-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
Daniel Stone 2022-12-29 21:12:24 +00:00 committed by Marius Vlad
parent 54356be853
commit 75b3ecfcc3
7 changed files with 156 additions and 67 deletions

View file

@ -62,3 +62,32 @@ get_backend_from_string(const char *name,
return false;
}
struct {
char *name;
enum weston_renderer_type renderer;
} renderer_name_map[] = {
{ "auto", WESTON_RENDERER_AUTO },
{ "gl", WESTON_RENDERER_GL },
{ "noop", WESTON_RENDERER_NOOP },
{ "pixman", WESTON_RENDERER_PIXMAN },
};
bool
get_renderer_from_string(const char *name,
enum weston_renderer_type *renderer)
{
size_t i;
if (!name)
name = "auto";
for (i = 0; i < ARRAY_LENGTH(renderer_name_map); i++) {
if (strcmp(name, renderer_name_map[i].name) == 0) {
*renderer = renderer_name_map[i].renderer;
return true;
}
}
return false;
}

View file

@ -670,6 +670,13 @@ usage(int error_code)
#if defined(BUILD_X11_COMPOSITOR)
"\t\t\t\tx11\n"
#endif
" --renderer=NAME\tRenderer to use, one of\n"
"\t\t\t\tauto\tAutomatic selection of one of the below renderers\n"
#if defined(ENABLE_EGL)
"\t\t\t\tgl\tOpenGL ES\n"
#endif
"\t\t\t\tnoop\tNo-op renderer for testing only\n"
"\t\t\t\tpixman\tPixman software renderer\n"
" --shell=NAME\tShell to load, defaults to desktop\n"
" -S, --socket=NAME\tName of socket to listen on\n"
" -i, --idle-time=SECS\tIdle time in seconds\n"
@ -695,7 +702,7 @@ usage(int error_code)
"Options for drm:\n\n"
" --seat=SEAT\t\tThe seat that weston should run on, instead of the seat defined in XDG_SEAT\n"
" --drm-device=CARD\tThe DRM device to use, e.g. \"card0\".\n"
" --use-pixman\t\tUse the pixman (CPU) renderer\n"
" --use-pixman\t\tUse the pixman (CPU) renderer (deprecated alias for --renderer=pixman)\n"
" --current-mode\tPrefer current KMS mode over EDID preferred mode\n"
" --continue-without-input\tAllow the compositor to start without input devices\n\n");
#endif
@ -708,8 +715,8 @@ usage(int error_code)
" --scale=SCALE\t\tScale factor of output\n"
" --transform=TR\tThe output transformation, TR is one of:\n"
"\tnormal 90 180 270 flipped flipped-90 flipped-180 flipped-270\n"
" --use-pixman\t\tUse the pixman (CPU) renderer (default: no rendering)\n"
" --use-gl\t\tUse the GL renderer (default: no rendering)\n"
" --use-pixman\t\tUse the pixman (CPU) renderer (deprecated alias for --renderer=pixman)\n"
" --use-gl\t\tUse the GL renderer (deprecated alias for --renderer=gl)\n"
" --no-outputs\t\tDo not create any virtual outputs\n"
"\n");
#endif
@ -748,7 +755,7 @@ usage(int error_code)
" --height=HEIGHT\tHeight of Wayland surface\n"
" --scale=SCALE\t\tScale factor of output\n"
" --fullscreen\t\tRun in fullscreen mode\n"
" --use-pixman\t\tUse the pixman (CPU) renderer\n"
" --use-pixman\t\tUse the pixman (CPU) renderer (deprecated alias for --renderer=pixman)\n"
" --output-count=COUNT\tCreate multiple outputs\n"
" --sprawl\t\tCreate one fullscreen output for every parent output\n"
" --display=DISPLAY\tWayland display to connect to\n\n");
@ -761,7 +768,7 @@ usage(int error_code)
" --height=HEIGHT\tHeight of X window\n"
" --scale=SCALE\t\tScale factor of output\n"
" --fullscreen\t\tRun in fullscreen mode\n"
" --use-pixman\t\tUse the pixman (CPU) renderer\n"
" --use-pixman\t\tUse the pixman (CPU) renderer (deprecated alias for --renderer=pixman)\n"
" --output-count=COUNT\tCreate multiple outputs\n"
" --no-input\t\tDont create input devices\n\n");
#endif
@ -2885,8 +2892,8 @@ load_pipewire(struct weston_compositor *c, struct weston_config *wc)
}
static int
load_drm_backend(struct weston_compositor *c,
int *argc, char **argv, struct weston_config *wc)
load_drm_backend(struct weston_compositor *c, int *argc, char **argv,
struct weston_config *wc, enum weston_renderer_type renderer)
{
struct weston_drm_backend_config config = {{ 0, }};
struct weston_config_section *section;
@ -2912,10 +2919,14 @@ load_drm_backend(struct weston_compositor *c,
parse_options(options, ARRAY_LENGTH(options), argc, argv);
if (force_pixman)
if (force_pixman && renderer != WESTON_RENDERER_AUTO) {
weston_log("error: conflicting renderer specification\n");
return -1;
} else if (force_pixman) {
config.renderer = WESTON_RENDERER_PIXMAN;
else
config.renderer = WESTON_RENDERER_AUTO;
} else {
config.renderer = renderer;
}
section = weston_config_get_section(wc, "core", NULL, NULL);
weston_config_section_get_string(section,
@ -2976,7 +2987,8 @@ headless_backend_output_configure(struct weston_output *output)
static int
load_headless_backend(struct weston_compositor *c,
int *argc, char **argv, struct weston_config *wc)
int *argc, char **argv, struct weston_config *wc,
enum weston_renderer_type renderer)
{
const struct weston_windowed_output_api *api;
struct weston_headless_backend_config config = {{ 0, }};
@ -3011,7 +3023,8 @@ load_headless_backend(struct weston_compositor *c,
parse_options(options, ARRAY_LENGTH(options), argc, argv);
if (force_pixman && force_gl) {
if ((force_pixman && force_gl) ||
(renderer != WESTON_RENDERER_AUTO && (force_pixman || force_gl))) {
weston_log("Conflicting renderer specifications\n");
return -1;
} else if (force_pixman) {
@ -3019,7 +3032,7 @@ load_headless_backend(struct weston_compositor *c,
} else if (force_gl) {
config.renderer = WESTON_RENDERER_GL;
} else {
config.renderer = WESTON_RENDERER_AUTO;
config.renderer = renderer;
}
if (transform) {
@ -3113,7 +3126,8 @@ weston_rdp_backend_config_init(struct weston_rdp_backend_config *config)
static int
load_rdp_backend(struct weston_compositor *c,
int *argc, char *argv[], struct weston_config *wc)
int *argc, char *argv[], struct weston_config *wc,
enum weston_renderer_type renderer)
{
struct weston_rdp_backend_config config = {{ 0, }};
struct weston_config_section *section;
@ -3143,6 +3157,7 @@ load_rdp_backend(struct weston_compositor *c,
parse_options(rdp_options, ARRAY_LENGTH(rdp_options), argc, argv);
config.remotefx_codec = !no_remotefx_codec;
config.renderer = renderer;
wet_set_simple_head_configurator(c, rdp_backend_output_configure);
section = weston_config_get_section(wc, "rdp", NULL, NULL);
@ -3216,7 +3231,8 @@ weston_vnc_backend_config_init(struct weston_vnc_backend_config *config)
static int
load_vnc_backend(struct weston_compositor *c,
int *argc, char *argv[], struct weston_config *wc)
int *argc, char *argv[], struct weston_config *wc,
enum weston_renderer_type renderer)
{
struct weston_vnc_backend_config config = {{ 0, }};
struct weston_config_section *section;
@ -3239,6 +3255,8 @@ load_vnc_backend(struct weston_compositor *c,
parse_options(vnc_options, ARRAY_LENGTH(vnc_options), argc, argv);
config.renderer = renderer;
wet_set_simple_head_configurator(c, vnc_backend_output_configure);
section = weston_config_get_section(wc, "vnc", NULL, NULL);
weston_config_section_get_int(section, "refresh-rate",
@ -3270,7 +3288,8 @@ x11_backend_output_configure(struct weston_output *output)
static int
load_x11_backend(struct weston_compositor *c,
int *argc, char **argv, struct weston_config *wc)
int *argc, char **argv, struct weston_config *wc,
enum weston_renderer_type renderer)
{
char *default_output;
const struct weston_windowed_output_api *api;
@ -3306,10 +3325,14 @@ load_x11_backend(struct weston_compositor *c,
config.base.struct_version = WESTON_X11_BACKEND_CONFIG_VERSION;
config.base.struct_size = sizeof(struct weston_x11_backend_config);
if (force_pixman)
if (force_pixman && renderer != WESTON_RENDERER_AUTO) {
weston_log("error: conflicting renderer specification\n");
return -1;
} else if (force_pixman) {
config.renderer = WESTON_RENDERER_PIXMAN;
else
} else {
config.renderer = WESTON_RENDERER_AUTO;
}
wet_set_simple_head_configurator(c, x11_backend_output_configure);
@ -3385,7 +3408,8 @@ wayland_backend_output_configure(struct weston_output *output)
static int
load_wayland_backend(struct weston_compositor *c,
int *argc, char **argv, struct weston_config *wc)
int *argc, char **argv, struct weston_config *wc,
enum weston_renderer_type renderer)
{
struct weston_wayland_backend_config config = {{ 0, }};
struct weston_config_section *section;
@ -3431,10 +3455,14 @@ load_wayland_backend(struct weston_compositor *c,
config.base.struct_size = sizeof(struct weston_wayland_backend_config);
config.base.struct_version = WESTON_WAYLAND_BACKEND_CONFIG_VERSION;
if (force_pixman)
if (force_pixman && renderer != WESTON_RENDERER_AUTO) {
weston_log("error: conflicting renderer specification\n");
return -1;
} else if (force_pixman) {
config.renderer = WESTON_RENDERER_PIXMAN;
else
config.renderer = WESTON_RENDERER_AUTO;
} else {
config.renderer = renderer;
}
/* load the actual wayland backend and configure it */
ret = weston_compositor_load_backend(c, WESTON_BACKEND_WAYLAND,
@ -3506,28 +3534,41 @@ load_wayland_backend(struct weston_compositor *c,
static int
load_backend(struct weston_compositor *compositor, const char *name,
int *argc, char **argv, struct weston_config *config)
int *argc, char **argv, struct weston_config *config,
const char *renderer_name)
{
enum weston_compositor_backend backend;
enum weston_renderer_type renderer;
if (!get_backend_from_string(name, &backend)) {
weston_log("Error: unknown backend \"%s\"\n", name);
return -1;
}
if (!get_renderer_from_string(renderer_name, &renderer)) {
weston_log("Error: unknown renderer \"%s\"\n", renderer_name);
return -1;
}
switch (backend) {
case WESTON_BACKEND_DRM:
return load_drm_backend(compositor, argc, argv, config);
return load_drm_backend(compositor, argc, argv, config,
renderer);
case WESTON_BACKEND_HEADLESS:
return load_headless_backend(compositor, argc, argv, config);
return load_headless_backend(compositor, argc, argv, config,
renderer);
case WESTON_BACKEND_RDP:
return load_rdp_backend(compositor, argc, argv, config);
return load_rdp_backend(compositor, argc, argv, config,
renderer);
case WESTON_BACKEND_VNC:
return load_vnc_backend(compositor, argc, argv, config);
return load_vnc_backend(compositor, argc, argv, config,
renderer);
case WESTON_BACKEND_WAYLAND:
return load_wayland_backend(compositor, argc, argv, config);
return load_wayland_backend(compositor, argc, argv, config,
renderer);
case WESTON_BACKEND_X11:
return load_x11_backend(compositor, argc, argv, config);
return load_x11_backend(compositor, argc, argv, config,
renderer);
default:
unreachable("unknown backend type in load_backend()");
}
@ -3670,6 +3711,7 @@ wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_data)
struct wl_event_loop *loop;
int i, fd;
char *backend = NULL;
char *renderer = NULL;
char *shell = NULL;
bool xwayland = false;
char *modules = NULL;
@ -3703,6 +3745,7 @@ wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_data)
const struct weston_option core_options[] = {
{ WESTON_OPTION_STRING, "backend", 'B', &backend },
{ WESTON_OPTION_STRING, "renderer", 0, &renderer },
{ WESTON_OPTION_STRING, "shell", 0, &shell },
{ WESTON_OPTION_STRING, "socket", 'S', &socket_name },
{ WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time },
@ -3837,6 +3880,11 @@ wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_data)
raise(SIGSTOP);
}
if (!renderer) {
weston_config_section_get_string(section, "renderer",
&renderer, NULL);
}
if (!backend) {
weston_config_section_get_string(section, "backend", &backend,
NULL);
@ -3876,7 +3924,8 @@ wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_data)
weston_config_section_get_bool(section, "require-input",
&wet.compositor->require_input, true);
if (load_backend(wet.compositor, backend, &argc, argv, config) < 0) {
if (load_backend(wet.compositor, backend, &argc, argv, config,
renderer) < 0) {
weston_log("fatal: failed to create compositor backend\n");
goto out;
}

View file

@ -32,6 +32,10 @@ bool
get_backend_from_string(const char *name,
enum weston_compositor_backend *backend);
bool
get_renderer_from_string(const char *name,
enum weston_renderer_type *renderer);
int
wet_output_set_color_characteristics(struct weston_output *output,
struct weston_config *wc,

View file

@ -34,15 +34,12 @@ stitching them together is performed by a *renderer*. By doing so, it is
compositing all surfaces into a single image, which is being handed out to a
back-end, and finally, displayed on the screen.
libweston has a CPU-based type of renderer by making use of the
`Pixman <http://www.pixman.org/>`_ library, but also one that can make
use of the GPU to do that, which uses `OpenGL ES <https://www.khronos.org/opengles/>`_
and it is simply called the GL-renderer.
Most of the back-ends provide a command line option to disable the GL-renderer,
and use the CPU for doing that. That happens by appending to the command line
``--use-pixman`` when running Weston. One might use the CPU-based renderer
to exclude any other potential issues with the GL-renderer.
libweston provides two useful renderers. One uses
`OpenGL ES <https://www.khronos.org/opengles/>`_, which will often be accelerated
by your GPU when suitable drivers are installed. The other uses the
`Pixman <http://www.pixman.org>`_ library which is entirely CPU (software)
rendered. You can select between these with the ``--renderer=gl`` and
``--renderer=pixman`` arguments when starting Weston.
Additional set-up steps
-----------------------

View file

@ -188,7 +188,25 @@ directory are:
.fi
.RE
.TP 7
.BI "renderer=" auto
Selects a renderer to use for internal composition when required, or
.BI auto
to select the most appropriate renderer. Available renderers are:
.PP
.RS 10
.nf
.BR auto
.BR gl
.BR noop
.BR pixman
.fi
.RE
Not all backends support all renderers.
.TP 7
.BI "use-pixman=" true
Deprecated in favour of the
.BI "renderer="
option.
Enables pixman-based rendering for all outputs on backends that support it.
Boolean, defaults to
.BR false .

View file

@ -185,6 +185,10 @@ Do not read
for the compositor. Avoids e.g. loading compositor modules via the
configuration file, which is useful for unit tests.
.TP
\fB\-\-renderer\fR=\fIrenderer\fR
Select which renderer to use for Weston's internal composition. Defaults to
automatic selection.
.TP
\fB\-\-shell\fR=\fIshell\fR
Select which shell to load to provide Weston's user interface. See
.BR ENVIRONMENT "."
@ -236,7 +240,9 @@ Give all outputs a scale factor of
.I N.
.TP
.B \-\-use\-pixman
Use the pixman renderer. By default, weston will try to use EGL and
Deprecated in favour of the
.BI \-\-renderer
option. Use the pixman renderer. By default weston will try to use EGL and
GLES2 for rendering and will fall back to the pixman-based renderer for
software compositing if EGL cannot be used. Passing this option will force
weston to use the pixman renderer.
@ -262,7 +268,9 @@ Give all outputs a scale factor of
.I N.
.TP
.B \-\-use\-pixman
Use the pixman renderer. By default weston will try to use EGL and
Deprecated in favour of the
.BI \-\-renderer
option. Use the pixman renderer. By default weston will try to use EGL and
GLES2 for rendering. Passing this option will make weston use the
pixman library for software compsiting.
.

View file

@ -218,30 +218,15 @@ backend_to_str(enum weston_compositor_backend b)
}
static const char *
renderer_to_arg(enum weston_compositor_backend b, enum renderer_type r)
renderer_to_str(enum renderer_type t)
{
static const char * const headless_names[] = {
[RENDERER_NOOP] = NULL,
[RENDERER_PIXMAN] = "--use-pixman",
[RENDERER_GL] = "--use-gl",
static const char * const names[] = {
[RENDERER_NOOP] = "noop",
[RENDERER_PIXMAN] = "pixman",
[RENDERER_GL] = "gl",
};
static const char * const drm_names[] = {
[RENDERER_PIXMAN] = "--use-pixman",
[RENDERER_GL] = NULL,
};
switch (b) {
case WESTON_BACKEND_HEADLESS:
assert(r >= RENDERER_NOOP && r <= RENDERER_GL);
return headless_names[r];
case WESTON_BACKEND_DRM:
assert(r >= RENDERER_PIXMAN && r <= RENDERER_GL);
return drm_names[r];
default:
assert(0 && "renderer_to_str() does not know the backend");
}
return NULL;
assert(t >= 0 && t <= ARRAY_LENGTH(names));
return names[t];
}
static const char *
@ -291,7 +276,7 @@ execute_compositor(const struct compositor_setup *setup,
struct weston_testsuite_data test_data;
struct prog_args args;
char *tmp;
const char *ctmp, *drm_device;
const char *drm_device;
int lock_fd = -1;
int ret = RESULT_OK;
@ -367,9 +352,8 @@ execute_compositor(const struct compositor_setup *setup,
prog_args_take(&args, strdup("--no-config"));
}
ctmp = renderer_to_arg(setup->backend, setup->renderer);
if (ctmp)
prog_args_take(&args, strdup(ctmp));
str_printf(&tmp, "--renderer=%s", renderer_to_str(setup->renderer));
prog_args_take(&args, strdup(tmp));
str_printf(&tmp, "--shell=%s", shell_to_str(setup->shell));
prog_args_take(&args, tmp);