[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