From 77a099b85dea6aac096413f95d02479e75e5df44 Mon Sep 17 00:00:00 2001
From: Pablo Castellano <pablo@anche.no>
Date: Fri, 16 Jun 2017 21:35:34 +0200
Subject: [PATCH 1/3] compositor-fbdev: Added parameter --pixman-type

This parameter allows to override the weston heuristic in
calculate_pixman_format() and specify a PIXMAN_TYPE_ value.
This is needed at least in LG Nexus 5 because the framebuffer
drivers seem to be reporting wrong information and causes
the screen to be redish when weston is run.
---
 compositor/main.c            |  2 ++
 libweston/compositor-fbdev.c | 23 +++++++++++++++++++----
 libweston/compositor-fbdev.h |  1 +
 libweston/compositor.h       |  3 +++
 4 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/compositor/main.c b/compositor/main.c
index f8a60e9..6246c89 100644
--- a/compositor/main.c
+++ b/compositor/main.c
@@ -574,6 +574,7 @@ usage(int error_code)
 		"Options for fbdev-backend.so:\n\n"
 		"  --tty=TTY\t\tThe tty to use\n"
 		"  --device=DEVICE\tThe framebuffer device to use\n"
+		"  --pixman-type=PIXMAN_TYPE\tThe pixman type to use\n"
 		"\n");
 #endif
 
@@ -1445,6 +1446,7 @@ load_fbdev_backend(struct weston_compositor *c,
 
 	const struct weston_option fbdev_options[] = {
 		{ WESTON_OPTION_INTEGER, "tty", 0, &config.tty },
+		{ WESTON_OPTION_INTEGER, "pixman-type", 0, &config.pixman_type },
 		{ WESTON_OPTION_STRING, "device", 0, &config.device },
 	};
 
diff --git a/libweston/compositor-fbdev.c b/libweston/compositor-fbdev.c
index e80a504..b7d2c74 100644
--- a/libweston/compositor-fbdev.c
+++ b/libweston/compositor-fbdev.c
@@ -159,7 +159,8 @@ finish_frame_handler(void *data)
 
 static pixman_format_code_t
 calculate_pixman_format(struct fb_var_screeninfo *vinfo,
-                        struct fb_fix_screeninfo *finfo)
+                        struct fb_fix_screeninfo *finfo,
+                        int pixman_type)
 {
 	/* Calculate the pixman format supported by the frame buffer from the
 	 * buffer's metadata. Return 0 if no known pixman format is supported
@@ -180,7 +181,8 @@ calculate_pixman_format(struct fb_var_screeninfo *vinfo,
 	           STAMP_SPACE " - red: offset: %i, length: %i, MSB: %i\n"
 	           STAMP_SPACE " - green: offset: %i, length: %i, MSB: %i\n"
 	           STAMP_SPACE " - blue: offset: %i, length: %i, MSB: %i\n"
-	           STAMP_SPACE " - transp: offset: %i, length: %i, MSB: %i\n",
+	           STAMP_SPACE " - transp: offset: %i, length: %i, MSB: %i\n"
+	           STAMP_SPACE " - pixman_type: %i\n",
 	           finfo->type, finfo->type_aux, finfo->visual,
 	           vinfo->bits_per_pixel, vinfo->grayscale,
 	           vinfo->red.offset, vinfo->red.length, vinfo->red.msb_right,
@@ -189,7 +191,8 @@ calculate_pixman_format(struct fb_var_screeninfo *vinfo,
 	           vinfo->blue.offset, vinfo->blue.length,
 	           vinfo->blue.msb_right,
 	           vinfo->transp.offset, vinfo->transp.length,
-	           vinfo->transp.msb_right);
+	           vinfo->transp.msb_right,
+	           pixman_type);
 
 	/* We only handle packed formats at the moment. */
 	if (finfo->type != FB_TYPE_PACKED_PIXELS)
@@ -211,6 +214,15 @@ calculate_pixman_format(struct fb_var_screeninfo *vinfo,
 	    vinfo->blue.msb_right != 0)
 		return 0;
 
+	/* Use pixman type specified by parameter */
+	if (pixman_type != PIXMAN_TYPE_OTHER) {
+		return PIXMAN_FORMAT(vinfo->bits_per_pixel, pixman_type,
+				     vinfo->transp.length,
+			             vinfo->red.length,
+ 			             vinfo->green.length,
+			             vinfo->blue.length);
+	}
+	
 	/* Work out the format type from the offsets. We only support RGBA and
 	 * ARGB at the moment. */
 	type = PIXMAN_TYPE_OTHER;
@@ -285,7 +297,7 @@ fbdev_query_screen_info(struct fbdev_output *output, int fd,
 	strncpy(info->id, fixinfo.id, sizeof(info->id));
 	info->id[sizeof(info->id)-1] = '\0';
 
-	info->pixel_format = calculate_pixman_format(&varinfo, &fixinfo);
+	info->pixel_format = calculate_pixman_format(&varinfo, &fixinfo, output->base.pixman_type);
 	info->refresh_rate = calculate_refresh_rate(&varinfo);
 
 	if (info->pixel_format == 0) {
@@ -495,6 +507,7 @@ fbdev_output_create(struct fbdev_backend *backend,
 		goto out_free;
 	}
 
+	output->base.pixman_type = backend->base.pixman_type;
 	output->base.name = strdup("fbdev");
 	output->base.destroy = fbdev_output_destroy;
 	output->base.disable = NULL;
@@ -742,6 +755,7 @@ fbdev_backend_create(struct weston_compositor *compositor,
 		goto out_udev;
 	}
 
+	backend->base.pixman_type = param->pixman_type;
 	backend->base.destroy = fbdev_backend_destroy;
 	backend->base.restore = fbdev_restore;
 
@@ -781,6 +795,7 @@ config_init_to_defaults(struct weston_fbdev_backend_config *config)
 	 * udev, rather than passing a device node in as a parameter. */
 	config->tty = 0; /* default to current tty */
 	config->device = "/dev/fb0"; /* default frame buffer */
+	config->pixman_type = PIXMAN_TYPE_RGBA; /* default pixman type */
 }
 
 WL_EXPORT int
diff --git a/libweston/compositor-fbdev.h b/libweston/compositor-fbdev.h
index 8b7d900..268de31 100644
--- a/libweston/compositor-fbdev.h
+++ b/libweston/compositor-fbdev.h
@@ -43,6 +43,7 @@ struct weston_fbdev_backend_config {
 
 	int tty;
 	char *device;
+	int pixman_type;
 
 	/** Callback used to configure input devices.
 	 *
diff --git a/libweston/compositor.h b/libweston/compositor.h
index 21c4046..fee8de0 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -235,6 +235,7 @@ struct weston_output {
 
 	bool enabled;
 	int scale;
+	int pixman_type;
 
 	int (*enable)(struct weston_output *output);
 	int (*disable)(struct weston_output *output);
@@ -810,6 +811,8 @@ struct weston_backend_config {
 };
 
 struct weston_backend {
+	int pixman_type;
+
 	void (*destroy)(struct weston_compositor *compositor);
 	void (*restore)(struct weston_compositor *compositor);
 
-- 
2.7.4

