[PATCH weston 7/7] compositor-drm: Add support for using the pixman renderer
Armin K.
krejzi at email.com
Wed Jan 23 04:23:07 PST 2013
Hello,
I'm not a programmer, but you might want to add --use-pixman in weston
--help output.
It currently displays this
Options for drm-backend.so:
--connector=ID Bring up only this connector
--seat=SEAT The seat that weston should run on
--tty=TTY The tty to use
--current-mode Prefer current KMS mode over EDID preferred mode
Explanation is present for x11-backend.so though
Options for x11-backend.so:
--width=WIDTH Width of X window
--height=HEIGHT Height of X window
--fullscreen Run in fullscreen mode
--use-pixman Use the pixman (CPU) renderer
--output-count=COUNT Create multiple outputs
--no-input Dont create input devices
On 01/22/2013 05:07 PM, Ander Conselvan de Oliveira wrote:
> If --use-pixman is passed as command line option to weston, the drm
> backend will use the pixman renderer instead of the gl one.
> ---
> src/compositor-drm.c | 209 ++++++++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 187 insertions(+), 22 deletions(-)
>
> diff --git a/src/compositor-drm.c b/src/compositor-drm.c
> index 7c11af1..0bc2990 100644
> --- a/src/compositor-drm.c
> +++ b/src/compositor-drm.c
> @@ -42,6 +42,7 @@
>
> #include "compositor.h"
> #include "gl-renderer.h"
> +#include "pixman-renderer.h"
> #include "evdev.h"
> #include "launcher-util.h"
>
> @@ -104,6 +105,8 @@ struct drm_compositor {
>
> int cursors_are_broken;
>
> + int use_pixman;
> +
> uint32_t prev_state;
> };
>
> @@ -145,6 +148,11 @@ struct drm_output {
> int current_cursor;
> struct drm_fb *current, *next;
> struct backlight *backlight;
> +
> + struct drm_fb *dumb[2];
> + pixman_image_t *image[2];
> + int current_image;
> + pixman_region32_t previous_damage;
> };
>
> /*
> @@ -376,7 +384,8 @@ drm_output_release_fb(struct drm_output *output, struct drm_fb *fb)
> if (!fb)
> return;
>
> - if (fb->map) {
> + if (fb->map &&
> + (fb != output->dumb[0] && fb != output->dumb[1])) {
> drm_fb_destroy_dumb(fb);
> } else if (fb->bo) {
> if (fb->is_client_buffer)
> @@ -432,7 +441,7 @@ drm_output_prepare_scanout_surface(struct weston_output *_output,
>
> if (es->geometry.x != output->base.x ||
> es->geometry.y != output->base.y ||
> - buffer == NULL ||
> + buffer == NULL || c->gbm == NULL ||
> buffer->width != output->base.current->width ||
> buffer->height != output->base.current->height ||
> output->base.transform != es->buffer_transform ||
> @@ -464,7 +473,7 @@ drm_output_prepare_scanout_surface(struct weston_output *_output,
> }
>
> static void
> -drm_output_render(struct drm_output *output, pixman_region32_t *damage)
> +drm_output_render_gl(struct drm_output *output, pixman_region32_t *damage)
> {
> struct drm_compositor *c =
> (struct drm_compositor *) output->base.compositor;
> @@ -472,9 +481,6 @@ drm_output_render(struct drm_output *output, pixman_region32_t *damage)
>
> c->base.renderer->repaint_output(&output->base, damage);
>
> - pixman_region32_subtract(&c->base.primary_plane.damage,
> - &c->base.primary_plane.damage, damage);
> -
> bo = gbm_surface_lock_front_buffer(output->surface);
> if (!bo) {
> weston_log("failed to lock front buffer: %m\n");
> @@ -490,6 +496,47 @@ drm_output_render(struct drm_output *output, pixman_region32_t *damage)
> }
>
> static void
> +drm_output_render_pixman(struct drm_output *output, pixman_region32_t *damage)
> +{
> + struct weston_compositor *ec = output->base.compositor;
> + pixman_region32_t total_damage, previous_damage;
> +
> + pixman_region32_init(&total_damage);
> + pixman_region32_init(&previous_damage);
> +
> + pixman_region32_copy(&previous_damage, damage);
> +
> + pixman_region32_union(&total_damage, damage, &output->previous_damage);
> + pixman_region32_copy(&output->previous_damage, &previous_damage);
> +
> + output->current_image ^= 1;
> +
> + output->next = output->dumb[output->current_image];
> + pixman_renderer_output_set_buffer(&output->base,
> + output->image[output->current_image]);
> +
> + ec->renderer->repaint_output(&output->base, &total_damage);
> +
> + pixman_region32_fini(&total_damage);
> + pixman_region32_fini(&previous_damage);
> +}
> +
> +static void
> +drm_output_render(struct drm_output *output, pixman_region32_t *damage)
> +{
> + struct drm_compositor *c =
> + (struct drm_compositor *) output->base.compositor;
> +
> + if (c->use_pixman)
> + drm_output_render_pixman(output, damage);
> + else
> + drm_output_render_gl(output, damage);
> +
> + pixman_region32_subtract(&c->base.primary_plane.damage,
> + &c->base.primary_plane.damage, damage);
> +}
> +
> +static void
> drm_output_repaint(struct weston_output *output_base,
> pixman_region32_t *damage)
> {
> @@ -688,6 +735,9 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
> uint32_t format;
> wl_fixed_t sx1, sy1, sx2, sy2;
>
> + if (c->gbm == NULL)
> + return NULL;
> +
> if (es->buffer_transform != output_base->transform)
> return NULL;
>
> @@ -814,6 +864,8 @@ drm_output_prepare_cursor_surface(struct weston_output *output_base,
> (struct drm_compositor *) output_base->compositor;
> struct drm_output *output = (struct drm_output *) output_base;
>
> + if (c->gbm == NULL)
> + return NULL;
> if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL)
> return NULL;
> if (output->cursor_surface)
> @@ -964,6 +1016,9 @@ drm_assign_planes(struct weston_output *output)
> }
>
> static void
> +drm_output_fini_pixman(struct drm_output *output);
> +
> +static void
> drm_output_destroy(struct weston_output *output_base)
> {
> struct drm_output *output = (struct drm_output *) output_base;
> @@ -986,9 +1041,12 @@ drm_output_destroy(struct weston_output *output_base)
> c->crtc_allocator &= ~(1 << output->crtc_id);
> c->connector_allocator &= ~(1 << output->connector_id);
>
> - gl_renderer_output_destroy(output_base);
> -
> - gbm_surface_destroy(output->surface);
> + if (c->use_pixman) {
> + drm_output_fini_pixman(output);
> + } else {
> + gl_renderer_output_destroy(output_base);
> + gbm_surface_destroy(output->surface);
> + }
>
> weston_plane_release(&output->fb_plane);
> weston_plane_release(&output->cursor_plane);
> @@ -1027,6 +1085,8 @@ choose_mode (struct drm_output *output, struct weston_mode *target_mode)
>
> static int
> drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec);
> +static int
> +drm_output_init_pixman(struct drm_output *output);
>
> static int
> drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mode)
> @@ -1068,12 +1128,22 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
> drm_output_release_fb(output, output->next);
> output->current = output->next = NULL;
>
> - gl_renderer_output_destroy(&output->base);
> - gbm_surface_destroy(output->surface);
> + if (ec->use_pixman) {
> + drm_output_fini_pixman(output);
> + if (drm_output_init_pixman(output) < 0) {
> + weston_log("failed to init output pixman state with "
> + "new mode\n");
> + return -1;
> + }
> + } else {
> + gl_renderer_output_destroy(&output->base);
> + gbm_surface_destroy(output->surface);
>
> - if (drm_output_init_egl(output, ec) < 0) {
> - weston_log("failed to init output egl state with new mode");
> - return -1;
> + if (drm_output_init_egl(output, ec) < 0) {
> + weston_log("failed to init output egl state with "
> + "new mode");
> + return -1;
> + }
> }
>
> return 0;
> @@ -1151,6 +1221,26 @@ init_egl(struct drm_compositor *ec)
> return 0;
> }
>
> +static int
> +init_pixman(struct drm_compositor *ec)
> +{
> + struct drm_output *output;
> +
> + if (pixman_renderer_init(&ec->base) < 0)
> + return -1;
> +
> + wl_list_for_each(output, &ec->base.output_list, base.link) {
> + if (drm_output_init_pixman(output) < 0) {
> + weston_log("Failed to init pixman state for output %s\n",
> + output->name);
> + weston_output_destroy(&output->base);
> + wl_list_remove(&output->base.link);
> + }
> + }
> +
> + return 0;
> +}
> +
> static struct drm_mode *
> drm_output_add_mode(struct drm_output *output, drmModeModeInfo *info)
> {
> @@ -1376,6 +1466,68 @@ drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec)
> }
>
> static int
> +drm_output_init_pixman(struct drm_output *output)
> +{
> + struct drm_compositor *c = (struct drm_compositor *)
> + output->base.compositor;
> + int w = output->base.current->width;
> + int h = output->base.current->height;
> + unsigned int i;
> +
> + /* FIXME error checking */
> +
> + for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
> + output->dumb[i] = drm_fb_create_dumb(c, w, h);
> + if (!output->dumb[i])
> + goto err;
> +
> + output->image[i] =
> + pixman_image_create_bits(PIXMAN_x8r8g8b8, w, h,
> + output->dumb[i]->map,
> + output->dumb[i]->stride);
> + if (!output->image[i])
> + goto err;
> + }
> +
> + if (pixman_renderer_output_create(&output->base) < 0)
> + goto err;
> +
> + pixman_region32_init_rect(&output->previous_damage,
> + output->base.x, output->base.y, w, h);
> +
> + return 0;
> +
> +err:
> + for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
> + if (output->dumb[i])
> + drm_fb_destroy_dumb(output->dumb[i]);
> + if (output->image[i])
> + pixman_image_unref(output->image[i]);
> +
> + output->dumb[i] = NULL;
> + output->image[i] = NULL;
> + }
> +
> + return -1;
> +}
> +
> +static void
> +drm_output_fini_pixman(struct drm_output *output)
> +{
> + unsigned int i;
> +
> + pixman_renderer_output_destroy(&output->base);
> + pixman_region32_fini(&output->previous_damage);
> +
> + for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
> + drm_fb_destroy_dumb(output->dumb[i]);
> + pixman_image_unref(output->image[i]);
> + output->dumb[i] = NULL;
> + output->image[i] = NULL;
> + }
> +}
> +
> +static int
> create_output_for_connector(struct drm_compositor *ec,
> drmModeRes *resources,
> drmModeConnector *connector,
> @@ -2099,7 +2251,10 @@ drm_destroy(struct weston_compositor *ec)
> ec->renderer->destroy(ec);
>
> destroy_sprites(d);
> - gbm_device_destroy(d->gbm);
> +
> + if (d->gbm)
> + gbm_device_destroy(d->gbm);
> +
> if (weston_launcher_drm_set_master(&d->base, d->drm.fd, 0) < 0)
> weston_log("failed to drop master: %m\n");
> tty_destroy(d->tty);
> @@ -2279,7 +2434,7 @@ planes_binding(struct wl_seat *seat, uint32_t time, uint32_t key, void *data)
>
> static struct weston_compositor *
> drm_compositor_create(struct wl_display *display,
> - int connector, const char *seat, int tty,
> + int connector, const char *seat, int tty, int pixman,
> int argc, char *argv[], const char *config_file)
> {
> struct drm_compositor *ec;
> @@ -2300,6 +2455,8 @@ drm_compositor_create(struct wl_display *display,
> * functionality for now. */
> ec->sprites_are_broken = 1;
>
> + ec->use_pixman = pixman;
> +
> if (weston_compositor_init(&ec->base, display, argc, argv,
> config_file) < 0) {
> weston_log("weston_compositor_init failed\n");
> @@ -2351,9 +2508,16 @@ drm_compositor_create(struct wl_display *display,
> goto err_sprite;
> }
>
> - if (init_egl(ec) < 0) {
> - weston_log("failed to initialize egl\n");
> - goto err_udev_dev;
> + if (ec->use_pixman) {
> + if (init_pixman(ec) < 0) {
> + weston_log("failed to initialize pixman renderer\n");
> + goto err_udev_dev;
> + }
> + } else {
> + if (init_egl(ec) < 0) {
> + weston_log("failed to initialize egl\n");
> + goto err_udev_dev;
> + }
> }
>
> path = NULL;
> @@ -2565,7 +2729,7 @@ WL_EXPORT struct weston_compositor *
> backend_init(struct wl_display *display, int argc, char *argv[],
> const char *config_file)
> {
> - int connector = 0, tty = 0;
> + int connector = 0, tty = 0, use_pixman = 0;
> const char *seat = default_seat;
>
> const struct weston_option drm_options[] = {
> @@ -2573,6 +2737,7 @@ backend_init(struct wl_display *display, int argc, char *argv[],
> { WESTON_OPTION_STRING, "seat", 0, &seat },
> { WESTON_OPTION_INTEGER, "tty", 0, &tty },
> { WESTON_OPTION_BOOLEAN, "current-mode", 0, &option_current_mode },
> + { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &use_pixman },
> };
>
> parse_options(drm_options, ARRAY_LENGTH(drm_options), argc, argv);
> @@ -2593,6 +2758,6 @@ backend_init(struct wl_display *display, int argc, char *argv[],
> parse_config_file(config_file, config_section,
> ARRAY_LENGTH(config_section), NULL);
>
> - return drm_compositor_create(display, connector, seat, tty, argc, argv,
> - config_file);
> + return drm_compositor_create(display, connector, seat, tty, use_pixman,
> + argc, argv, config_file);
> }
>
More information about the wayland-devel
mailing list