Skip to content
Commits on Source (11)
/*
* Copyright 2022 Collabora, Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "config.h"
#include <string.h>
#include <libweston/libweston.h>
#include <libweston/config-parser.h>
#include "shared/helpers.h"
#include "weston-private.h"
struct {
char *short_name;
char *long_name;
enum weston_compositor_backend backend;
} backend_name_map[] = {
{ "drm", "drm-backend.so", WESTON_BACKEND_DRM },
{ "headless", "headless-backend.so", WESTON_BACKEND_HEADLESS },
{ "rdp", "rdp-backend.so", WESTON_BACKEND_RDP },
{ "vnc", "vnc-backend.so", WESTON_BACKEND_VNC },
{ "wayland", "wayland-backend.so", WESTON_BACKEND_WAYLAND },
{ "x11", "x11-backend.so", WESTON_BACKEND_X11 },
};
bool
get_backend_from_string(const char *name,
enum weston_compositor_backend *backend)
{
size_t i;
for (i = 0; i < ARRAY_LENGTH(backend_name_map); i++) {
if (strcmp(name, backend_name_map[i].short_name) == 0 ||
strcmp(name, backend_name_map[i].long_name) == 0) {
*backend = backend_name_map[i].backend;
return true;
}
}
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;
}
......@@ -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,41 +2892,42 @@ 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;
struct wet_compositor *wet = to_wet_compositor(c);
bool without_input = false;
bool use_pixman_default;
bool force_pixman = false;
int ret = 0;
wet->drm_use_current_mode = false;
section = weston_config_get_section(wc, "core", NULL, NULL);
/* Use the pixman renderer by default when GBM/EGL support is
* not enabled */
#if defined(BUILD_DRM_GBM)
use_pixman_default = false;
#else
use_pixman_default = true;
#endif
weston_config_section_get_bool(section, "use-pixman", &config.use_pixman,
use_pixman_default);
weston_config_section_get_bool(section, "use-pixman", &force_pixman,
false);
const struct weston_option options[] = {
{ WESTON_OPTION_STRING, "seat", 0, &config.seat_id },
{ WESTON_OPTION_STRING, "drm-device", 0, &config.specific_device },
{ WESTON_OPTION_BOOLEAN, "current-mode", 0, &wet->drm_use_current_mode },
{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &config.use_pixman },
{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &force_pixman },
{ WESTON_OPTION_BOOLEAN, "continue-without-input", false, &without_input }
};
parse_options(options, ARRAY_LENGTH(options), argc, argv);
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 = renderer;
}
section = weston_config_get_section(wc, "core", NULL, NULL);
weston_config_section_get_string(section,
"gbm-format", &config.gbm_format,
......@@ -2979,11 +2987,14 @@ 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, }};
struct weston_config_section *section;
bool force_pixman;
bool force_gl;
bool no_outputs = false;
int ret = 0;
char *transform = NULL;
......@@ -2993,9 +3004,9 @@ load_headless_backend(struct weston_compositor *c,
return -1;
section = weston_config_get_section(wc, "core", NULL, NULL);
weston_config_section_get_bool(section, "use-pixman", &config.use_pixman,
weston_config_section_get_bool(section, "use-pixman", &force_pixman,
false);
weston_config_section_get_bool(section, "use-gl", &config.use_gl,
weston_config_section_get_bool(section, "use-gl", &force_gl,
false);
weston_config_section_get_bool(section, "output-decorations", &config.decorate,
false);
......@@ -3004,14 +3015,26 @@ load_headless_backend(struct weston_compositor *c,
{ WESTON_OPTION_INTEGER, "width", 0, &parsed_options->width },
{ WESTON_OPTION_INTEGER, "height", 0, &parsed_options->height },
{ WESTON_OPTION_INTEGER, "scale", 0, &parsed_options->scale },
{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &config.use_pixman },
{ WESTON_OPTION_BOOLEAN, "use-gl", 0, &config.use_gl },
{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &force_pixman },
{ WESTON_OPTION_BOOLEAN, "use-gl", 0, &force_gl },
{ WESTON_OPTION_STRING, "transform", 0, &transform },
{ WESTON_OPTION_BOOLEAN, "no-outputs", 0, &no_outputs },
};
parse_options(options, ARRAY_LENGTH(options), argc, argv);
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) {
config.renderer = WESTON_RENDERER_PIXMAN;
} else if (force_gl) {
config.renderer = WESTON_RENDERER_GL;
} else {
config.renderer = renderer;
}
if (transform) {
if (weston_parse_transform(transform, &parsed_options->transform) < 0) {
weston_log("Invalid transform \"%s\"\n", transform);
......@@ -3087,6 +3110,7 @@ weston_rdp_backend_config_init(struct weston_rdp_backend_config *config)
config->base.struct_version = WESTON_RDP_BACKEND_CONFIG_VERSION;
config->base.struct_size = sizeof(struct weston_rdp_backend_config);
config->renderer = WESTON_RENDERER_AUTO;
config->bind_address = NULL;
config->port = 3389;
config->rdp_key = NULL;
......@@ -3102,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;
......@@ -3132,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);
......@@ -3197,6 +3223,7 @@ weston_vnc_backend_config_init(struct weston_vnc_backend_config *config)
config->base.struct_version = WESTON_VNC_BACKEND_CONFIG_VERSION;
config->base.struct_size = sizeof(struct weston_vnc_backend_config);
config->renderer = WESTON_RENDERER_AUTO;
config->bind_address = NULL;
config->port = 5900;
config->refresh_rate = VNC_DEFAULT_FREQ;
......@@ -3204,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;
......@@ -3227,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",
......@@ -3258,12 +3288,14 @@ 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;
struct weston_x11_backend_config config = {{ 0, }};
struct weston_config_section *section;
bool force_pixman;
int ret = 0;
int option_count = 1;
int output_count = 0;
......@@ -3275,7 +3307,7 @@ load_x11_backend(struct weston_compositor *c,
return -1;
section = weston_config_get_section(wc, "core", NULL, NULL);
weston_config_section_get_bool(section, "use-pixman", &config.use_pixman,
weston_config_section_get_bool(section, "use-pixman", &force_pixman,
false);
const struct weston_option options[] = {
......@@ -3285,7 +3317,7 @@ load_x11_backend(struct weston_compositor *c,
{ WESTON_OPTION_BOOLEAN, "fullscreen", 'f', &config.fullscreen },
{ WESTON_OPTION_INTEGER, "output-count", 0, &option_count },
{ WESTON_OPTION_BOOLEAN, "no-input", 0, &config.no_input },
{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &config.use_pixman },
{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &force_pixman },
};
parse_options(options, ARRAY_LENGTH(options), argc, argv);
......@@ -3293,6 +3325,15 @@ 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 && 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;
}
wet_set_simple_head_configurator(c, x11_backend_output_configure);
/* load the actual backend and configure it */
......@@ -3367,13 +3408,15 @@ 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;
const struct weston_windowed_output_api *api;
const char *section_name;
char *output_name = NULL;
bool force_pixman = false;
int count = 1;
int ret = 0;
int i;
......@@ -3387,7 +3430,7 @@ load_wayland_backend(struct weston_compositor *c,
config.display_name = NULL;
section = weston_config_get_section(wc, "core", NULL, NULL);
weston_config_section_get_bool(section, "use-pixman", &config.use_pixman,
weston_config_section_get_bool(section, "use-pixman", &force_pixman,
false);
const struct weston_option wayland_options[] = {
......@@ -3395,7 +3438,7 @@ load_wayland_backend(struct weston_compositor *c,
{ WESTON_OPTION_INTEGER, "height", 0, &parsed_options->height },
{ WESTON_OPTION_INTEGER, "scale", 0, &parsed_options->scale },
{ WESTON_OPTION_STRING, "display", 0, &config.display_name },
{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &config.use_pixman },
{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &force_pixman },
{ WESTON_OPTION_INTEGER, "output-count", 0, &count },
{ WESTON_OPTION_BOOLEAN, "fullscreen", 0, &config.fullscreen },
{ WESTON_OPTION_BOOLEAN, "sprawl", 0, &config.sprawl },
......@@ -3412,6 +3455,15 @@ 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 && 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 = renderer;
}
/* load the actual wayland backend and configure it */
ret = weston_compositor_load_backend(c, WESTON_BACKEND_WAYLAND,
&config.base);
......@@ -3481,30 +3533,45 @@ load_wayland_backend(struct weston_compositor *c,
static int
load_backend(struct weston_compositor *compositor, const char *backend,
int *argc, char **argv, struct weston_config *config)
{
if (strcmp(backend, "headless") == 0 ||
strstr(backend, "headless-backend.so"))
return load_headless_backend(compositor, argc, argv, config);
else if (strcmp(backend, "rdp") == 0 ||
strstr(backend, "rdp-backend.so"))
return load_rdp_backend(compositor, argc, argv, config);
else if (strcmp(backend, "vnc") == 0 ||
strstr(backend, "vnc-backend.so"))
return load_vnc_backend(compositor, argc, argv, config);
else if (strcmp(backend, "drm") == 0 ||
strstr(backend, "drm-backend.so"))
return load_drm_backend(compositor, argc, argv, config);
else if (strcmp(backend, "x11") == 0 ||
strstr(backend, "x11-backend.so"))
return load_x11_backend(compositor, argc, argv, config);
else if (strcmp(backend, "wayland") == 0 ||
strstr(backend, "wayland-backend.so"))
return load_wayland_backend(compositor, argc, argv, config);
weston_log("Error: unknown backend \"%s\"\n", backend);
return -1;
load_backend(struct weston_compositor *compositor, const char *name,
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,
renderer);
case WESTON_BACKEND_HEADLESS:
return load_headless_backend(compositor, argc, argv, config,
renderer);
case WESTON_BACKEND_RDP:
return load_rdp_backend(compositor, argc, argv, config,
renderer);
case WESTON_BACKEND_VNC:
return load_vnc_backend(compositor, argc, argv, config,
renderer);
case WESTON_BACKEND_WAYLAND:
return load_wayland_backend(compositor, argc, argv, config,
renderer);
case WESTON_BACKEND_X11:
return load_x11_backend(compositor, argc, argv, config,
renderer);
default:
unreachable("unknown backend type in load_backend()");
}
}
static char *
......@@ -3644,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;
......@@ -3677,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 },
......@@ -3811,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);
......@@ -3850,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;
}
......
......@@ -2,6 +2,7 @@ srcs_weston = [
git_version_h,
'main.c',
'text-backend.c',
'config-helpers.c',
'weston-screenshooter.c',
text_input_unstable_v1_server_protocol_h,
text_input_unstable_v1_protocol_c,
......
......@@ -28,6 +28,14 @@
#include <libweston/libweston.h>
#include <libweston/config-parser.h>
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,
......
......@@ -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
-----------------------
......
......@@ -35,7 +35,7 @@
extern "C" {
#endif
#define WESTON_DRM_BACKEND_CONFIG_VERSION 5
#define WESTON_DRM_BACKEND_CONFIG_VERSION 6
struct libinput_device;
......@@ -201,8 +201,8 @@ weston_drm_virtual_output_get_api(struct weston_compositor *compositor)
struct weston_drm_backend_config {
struct weston_backend_config base;
/** Whether to use the pixman renderer instead of the OpenGL ES renderer. */
bool use_pixman;
/** Select the renderer type to use */
enum weston_renderer_type renderer;
/** The seat to be used for input and output.
*
......
......@@ -34,16 +34,13 @@ extern "C" {
#include <libweston/libweston.h>
#define WESTON_HEADLESS_BACKEND_CONFIG_VERSION 2
#define WESTON_HEADLESS_BACKEND_CONFIG_VERSION 3
struct weston_headless_backend_config {
struct weston_backend_config base;
/** Whether to use the pixman renderer, default is no-op */
bool use_pixman;
/** Whether to use the GL renderer, conflicts with use_pixman */
bool use_gl;
/** Select the renderer to use */
enum weston_renderer_type renderer;
/** Use output decorations, requires use_gl = true */
bool decorate;
......
......@@ -55,7 +55,7 @@ weston_rdp_output_get_api(struct weston_compositor *compositor)
return (const struct weston_rdp_output_api *)api;
}
#define WESTON_RDP_BACKEND_CONFIG_VERSION 2
#define WESTON_RDP_BACKEND_CONFIG_VERSION 3
typedef void *(*rdp_audio_in_setup)(struct weston_compositor *c, void *vcm);
typedef void (*rdp_audio_in_teardown)(void *audio_private);
......@@ -64,6 +64,7 @@ typedef void (*rdp_audio_out_teardown)(void *audio_private);
struct weston_rdp_backend_config {
struct weston_backend_config base;
enum weston_renderer_type renderer;
char *bind_address;
int port;
char *rdp_key;
......
......@@ -55,10 +55,11 @@ weston_vnc_output_get_api(struct weston_compositor *compositor)
return (const struct weston_vnc_output_api *)api;
}
#define WESTON_VNC_BACKEND_CONFIG_VERSION 1
#define WESTON_VNC_BACKEND_CONFIG_VERSION 2
struct weston_vnc_backend_config {
struct weston_backend_config base;
enum weston_renderer_type renderer;
char *bind_address;
int port;
int refresh_rate;
......
......@@ -34,11 +34,11 @@ extern "C" {
#include <stdint.h>
#define WESTON_WAYLAND_BACKEND_CONFIG_VERSION 2
#define WESTON_WAYLAND_BACKEND_CONFIG_VERSION 3
struct weston_wayland_backend_config {
struct weston_backend_config base;
bool use_pixman;
enum weston_renderer_type renderer;
bool sprawl;
char *display_name;
bool fullscreen;
......
......@@ -34,7 +34,7 @@ extern "C" {
#include <libweston/libweston.h>
#define WESTON_X11_BACKEND_CONFIG_VERSION 2
#define WESTON_X11_BACKEND_CONFIG_VERSION 3
struct weston_x11_backend_config {
struct weston_backend_config base;
......@@ -42,8 +42,7 @@ struct weston_x11_backend_config {
bool fullscreen;
bool no_input;
/** Whether to use the pixman renderer instead of the OpenGL ES renderer. */
bool use_pixman;
enum weston_renderer_type renderer;
};
#ifdef __cplusplus
......
......@@ -2065,6 +2065,13 @@ enum weston_compositor_backend {
WESTON_BACKEND_X11,
};
enum weston_renderer_type {
WESTON_RENDERER_AUTO = 0,
WESTON_RENDERER_NOOP = 1,
WESTON_RENDERER_PIXMAN = 2,
WESTON_RENDERER_GL = 3,
};
int
weston_compositor_load_backend(struct weston_compositor *compositor,
enum weston_compositor_backend backend,
......
......@@ -3201,16 +3201,30 @@ drm_backend_create(struct weston_compositor *compositor,
goto err_udev_dev;
}
if (config->use_pixman) {
if (config->renderer == WESTON_RENDERER_AUTO) {
#ifdef BUILD_DRM_GBM
config->renderer = WESTON_RENDERER_GL;
#else
config->renderer = WESTON_RENDERER_PIXMAN;
#endif
}
switch (config->renderer) {
case WESTON_RENDERER_PIXMAN:
if (init_pixman(b) < 0) {
weston_log("failed to initialize pixman renderer\n");
goto err_udev_dev;
}
} else {
break;
case WESTON_RENDERER_GL:
if (init_egl(b) < 0) {
weston_log("failed to initialize egl\n");
goto err_udev_dev;
}
break;
default:
weston_log("unsupported renderer for DRM backend\n");
goto err_udev_dev;
}
b->base.destroy = drm_destroy;
......@@ -3376,6 +3390,7 @@ err_compositor:
static void
config_init_to_defaults(struct weston_drm_backend_config *config)
{
config->renderer = WESTON_RENDERER_AUTO;
config->use_pixman_shadow = true;
}
......
......@@ -218,6 +218,8 @@ headless_output_disable(struct weston_output *base)
break;
case WESTON_RENDERER_NOOP:
break;
case WESTON_RENDERER_AUTO:
unreachable("cannot have auto renderer at runtime");
}
return 0;
......@@ -351,6 +353,8 @@ headless_output_enable(struct weston_output *base)
break;
case WESTON_RENDERER_NOOP:
break;
case WESTON_RENDERER_AUTO:
unreachable("cannot have auto renderer at runtime");
}
if (ret < 0) {
......@@ -539,15 +543,6 @@ headless_backend_create(struct weston_compositor *compositor,
b->base.destroy = headless_destroy;
b->base.create_output = headless_output_create;
if (config->use_pixman && config->use_gl) {
weston_log("Error: cannot use both Pixman *and* GL renderers.\n");
goto err_free;
}
if (config->decorate && !config->use_gl) {
weston_log("Error: headless-backend decorations require GL renderer.\n");
goto err_free;
}
b->decorate = config->decorate;
if (b->decorate) {
b->theme = theme_create();
......@@ -557,12 +552,29 @@ headless_backend_create(struct weston_compositor *compositor,
}
}
if (config->use_gl)
switch (config->renderer) {
case WESTON_RENDERER_GL:
ret = headless_gl_renderer_init(b);
else if (config->use_pixman)
break;
case WESTON_RENDERER_PIXMAN:
if (config->decorate) {
weston_log("Error: Pixman renderer does not support decorations.\n");
goto err_input;
}
ret = pixman_renderer_init(compositor);
else
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;
}
if (ret < 0)
goto err_input;
......
......@@ -1686,6 +1686,16 @@ rdp_backend_create(struct weston_compositor *compositor,
goto err_free_strings;
}
switch (config->renderer) {
case WESTON_RENDERER_PIXMAN:
case WESTON_RENDERER_AUTO:
weston_log("Using Pixman renderer\n");
break;
default:
weston_log("Unsupported renderer requested\n");
goto err_free_strings;
}
/* if we are listening for client connections on an external listener
* fd, we don't need to enforce TLS or RDP security, since FreeRDP
* will consider it to be a local connection */
......@@ -1790,6 +1800,7 @@ err_free_strings:
static void
config_init_to_defaults(struct weston_rdp_backend_config *config)
{
config->renderer = WESTON_RENDERER_AUTO;
config->bind_address = NULL;
config->port = 3389;
config->rdp_key = NULL;
......
......@@ -972,6 +972,16 @@ vnc_backend_create(struct weston_compositor *compositor,
if (weston_compositor_set_presentation_clock_software(compositor) < 0)
goto err_compositor;
switch (config->renderer) {
case WESTON_RENDERER_AUTO:
case WESTON_RENDERER_PIXMAN:
weston_log("Using Pixman renderer\n");
break;
default:
weston_log("Unsupported renderer requested\n");
goto err_compositor;
}
if (pixman_renderer_init(compositor) < 0)
goto err_compositor;
......
......@@ -2752,7 +2752,7 @@ wayland_backend_create(struct weston_compositor *compositor,
{
struct wayland_backend *b;
struct wl_event_loop *loop;
bool use_pixman;
enum weston_renderer_type renderer = new_config->renderer;
int fd;
b = zalloc(sizeof *b);
......@@ -2789,22 +2789,7 @@ wayland_backend_create(struct weston_compositor *compositor,
create_cursor(b, new_config);
#ifdef ENABLE_EGL
use_pixman = new_config->use_pixman;
#else
use_pixman = true;
#endif
b->fullscreen = new_config->fullscreen;
if (!use_pixman) {
gl_renderer = weston_load_module("gl-renderer.so",
"gl_renderer_interface",
LIBWESTON_MODULEDIR);
if (!gl_renderer)
use_pixman = true;
}
if (!use_pixman) {
if (renderer == WESTON_RENDERER_AUTO || renderer == WESTON_RENDERER_GL) {
const struct gl_renderer_display_options options = {
.egl_platform = EGL_PLATFORM_WAYLAND_KHR,
.egl_native_display = b->parent.wl_display,
......@@ -2812,14 +2797,26 @@ wayland_backend_create(struct weston_compositor *compositor,
.drm_formats = wayland_formats,
.drm_formats_count = ARRAY_LENGTH(wayland_formats),
};
if (gl_renderer->display_create(compositor, &options) < 0) {
weston_log("Failed to initialize the GL renderer; "
"falling back to pixman.\n");
use_pixman = true;
#ifdef ENABLE_EGL
gl_renderer = weston_load_module("gl-renderer.so",
"gl_renderer_interface",
LIBWESTON_MODULEDIR);
#endif
if (!gl_renderer ||
gl_renderer->display_create(compositor, &options) < 0) {
weston_log("Failed to initialize the GL renderer");
if (renderer == WESTON_RENDERER_AUTO) {
weston_log_continue("; falling back to Pixman.\n");
renderer = WESTON_RENDERER_PIXMAN;
} else {
goto err_display;
}
}
}
if (use_pixman) {
if (renderer == WESTON_RENDERER_PIXMAN) {
if (pixman_renderer_init(compositor) < 0) {
weston_log("Failed to initialize pixman renderer\n");
goto err_display;
......
......@@ -1895,7 +1895,7 @@ x11_backend_create(struct weston_compositor *compositor,
config->fullscreen = 0;
}
if (config->use_pixman) {
if (config->renderer == WESTON_RENDERER_PIXMAN) {
if (pixman_renderer_init(compositor) < 0) {
weston_log("Failed to initialize pixman renderer for X11 backend\n");
goto err_xdisplay;
......@@ -1904,7 +1904,8 @@ x11_backend_create(struct weston_compositor *compositor,
else if (init_gl_renderer(b) < 0) {
goto err_xdisplay;
}
weston_log("Using %s renderer\n", config->use_pixman ? "pixman" : "gl");
weston_log("Using %s renderer\n",
(config->renderer == WESTON_RENDERER_PIXMAN) ? "pixman" : "gl");
b->base.destroy = x11_destroy;
b->base.create_output = x11_output_create;
......
......@@ -46,12 +46,6 @@
/* compositor <-> renderer interface */
enum weston_renderer_type {
WESTON_RENDERER_NOOP,
WESTON_RENDERER_PIXMAN,
WESTON_RENDERER_GL,
};
struct weston_renderer {
int (*read_pixels)(struct weston_output *output,
const struct pixel_format_info *format, void *pixels,
......
......@@ -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 .
......