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

Enric Balletbo i Serra eballetbo at gmail.com
Fri Jul 3 14:41:53 PDT 2015


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;
 		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. */
 	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);
+}
+
 /* 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);
 	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;
-- 
2.1.0



More information about the wayland-devel mailing list