[weston][PATCH] compositor-fbdev: Add support grayscale PIXMAn_g4 format.

Derek Foreman derekf at osg.samsung.com
Mon Sep 28 07:31:09 PDT 2015


On 03/07/15 04:41 PM, Enric Balletbo i Serra wrote:
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> Reviewed-by: Sjoerd Simons <sjoerd.simons at collabora.co.uk>
> ---
>  src/compositor-fbdev.c | 51 +++++++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 42 insertions(+), 9 deletions(-)
> 
> diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c
> index a6fd823..9d8a1f1 100644
> --- a/src/compositor-fbdev.c
> +++ b/src/compositor-fbdev.c
> @@ -90,6 +90,7 @@ struct fbdev_output {
>  	/* pixman details. */
>  	pixman_image_t *hw_surface;
>  	pixman_image_t *shadow_surface;
> +	pixman_indexed_t palette;
>  	void *shadow_buf;
>  	uint8_t depth;
>  };
> @@ -250,13 +251,18 @@ calculate_pixman_format(struct fb_var_screeninfo *vinfo,
>  	if (finfo->type != FB_TYPE_PACKED_PIXELS)
>  		return 0;
>  
> -	/* We only handle true-colour frame buffers at the moment. */
> +	/* Build the format. */
>  	switch(finfo->visual) {
>  		case FB_VISUAL_TRUECOLOR:
>  		case FB_VISUAL_DIRECTCOLOR:
>  			if (vinfo->grayscale != 0)
>  				return 0;
>  		break;
> +		case FB_VISUAL_MONO10:
> +			/* We only support 4bpp */
> +			if (vinfo->bits_per_pixel != 4)
> +				return 0;
> +		break;

I'm not sure I get this - FB_VISUAL_MONO10 is monochrome, not
greyscale...  It's by definition 1 bit per pixel, isn't it?

>  		default:
>  			return 0;
>  	}
> @@ -266,12 +272,14 @@ calculate_pixman_format(struct fb_var_screeninfo *vinfo,
>  	    vinfo->blue.msb_right != 0)
>  		return 0;
>  
> -	/* Work out the format type from the offsets. We only support RGBA and
> -	 * ARGB at the moment. */
> +	/* Work out the format type from the offsets. We only support RGBA,
> +	 * ARGB and GRAY at the moment. */

GRAY probably doesn't need to be all caps. :)

>  	type = PIXMAN_TYPE_OTHER;
>  
> -	if ((vinfo->transp.offset >= vinfo->red.offset ||
> -	     vinfo->transp.length == 0) &&
> +	if (vinfo->grayscale)
> +		type = PIXMAN_TYPE_GRAY;
> +	else if ((vinfo->transp.offset >= vinfo->red.offset ||
> +	    vinfo->transp.length == 0) &&
>  	    vinfo->red.offset >= vinfo->green.offset &&
>  	    vinfo->green.offset >= vinfo->blue.offset)
>  		type = PIXMAN_TYPE_ARGB;
> @@ -421,6 +429,20 @@ fbdev_frame_buffer_open(struct fbdev_output *output, const char *fb_dev,
>  	return fd;
>  }
>  
> +/* Create a PIXMAP_g4 palette filling 15 bits and picking up the 4 msb bits
> + * of the YUV value that is used as index. */
> +static void
> +init_pixmap_g4_palette(pixman_indexed_t *indexed)
> +{
> +	int i;
> +
> +	for (i = 0; i < 0x7fff; ++i)
> +		indexed->ent[i] = i >> 11;
> +
> +	for (i = 0; i < 0xff; ++i)
> +		indexed->rgba[i] = 0xff000000 | (i << 20) | (i << 12) | (i << 4);

Why is this palette in YUV?

Is this palette and use of MONO10 in any way "standard", or is this all
for a very specific weirdo platform?

> +}
> +
>  /* Closes the FD on success or failure. */
>  static int
>  fbdev_frame_buffer_map(struct fbdev_output *output, int fd)
> @@ -451,6 +473,12 @@ fbdev_frame_buffer_map(struct fbdev_output *output, int fd)
>  		goto out_unmap;
>  	}
>  
> +	/* Set indexed palette for PIXMAP_g4 format */
> +	if (output->fb_info.pixel_format == PIXMAN_g4) {
> +		init_pixmap_g4_palette(&output->palette);
> +		pixman_image_set_indexed(output->hw_surface, &output->palette);
> +	}
> +
>  	/* Success! */
>  	retval = 0;
>  
> @@ -488,7 +516,7 @@ fbdev_output_create(struct fbdev_compositor *compositor,
>  	struct weston_config_section *section;
>  	int fb_fd;
>  	int width, height;
> -	unsigned int bytes_per_pixel;
> +	unsigned int row_stride;
>  	struct wl_event_loop *loop;
>  	uint32_t config_transform;
>  	char *s;
> @@ -553,19 +581,24 @@ fbdev_output_create(struct fbdev_compositor *compositor,
>  
>  	width = output->mode.width;
>  	height = output->mode.height;
> -	bytes_per_pixel = output->fb_info.bits_per_pixel / 8;
>  
> -	output->shadow_buf = malloc(width * height * bytes_per_pixel);
> +	row_stride = width * output->fb_info.bits_per_pixel / 8;
> +	output->shadow_buf = malloc(row_stride * height);
> +
>  	output->shadow_surface =
>  		pixman_image_create_bits(output->fb_info.pixel_format,
>  		                         width, height,
>  		                         output->shadow_buf,
> -		                         width * bytes_per_pixel);
> +					 row_stride);

These row_stride bits make sense to me - currently if bits_per_pixel is
less than 8 the calculation rounds to zero...

>  	if (output->shadow_buf == NULL || output->shadow_surface == NULL) {
>  		weston_log("Failed to create surface for frame buffer.\n");
>  		goto out_hw_surface;
>  	}
>  
> +	/* Set indexed palette for PIXMAP_g4 format */
> +	if (output->fb_info.pixel_format == PIXMAN_g4)
> +		pixman_image_set_indexed(output->shadow_surface, &output->palette);
> +
>  	if (compositor->use_pixman) {
>  		if (pixman_renderer_output_create(&output->base) < 0)
>  			goto out_shadow_surface;
> 



More information about the wayland-devel mailing list