<div dir="ltr"><div><div><div><div>Hello,<br></div>OK this patch now checks FB_VISUAL_DIRECTCOLOR twice but set the cmap inside the fbdev_query_screen_info function.<br></div>I use "malloc" instead "table" declaration because it takes less memory and it's used only once, it's useless to be faster.<br>
</div>After I set the same values for each colors, because it's a default map. To set more finely we have to know the screen and it's capabilities.<br></div>I don't set the alpha when it's required (no alpha => no alpha map)<br>
<br>[PATCH] [compositor-fbdev]: DirectColor support<br>The backend accepts to use TRUECOLOR and DIRECTCOLOR which are similares.<br>DIRECTCOLOR has better results if the application applies a Colors map before to use it.<br>
The colors map is just a list of gradients for each colors and alpha.<br><br>---<br> src/compositor-fbdev.c | 43 ++++++++++++++++++++++++++++++++++++++++++-<br> 1 file changed, 42 insertions(+), 1 deletion(-)<br><br>diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c<br>
index 9c3d17e..c966d5a 100644<br>--- a/src/compositor-fbdev.c<br>+++ b/src/compositor-fbdev.c<br>@@ -203,6 +203,43 @@ finish_frame_handler(void *data)<br> return 1;<br> }<br> <br>+static int<br>+set_cmap(int fd, struct fb_var_screeninfo *vinfo)<br>
+{<br>+ struct fb_cmap cmap;<br>+ uint16_t *colors;<br>+ int i;<br>+ int rcols = 1 << vinfo->red.length;<br>+ int gcols = 1 << vinfo->green.length;<br>+ int bcols = 1 << vinfo->blue.length;<br>
+<br>+ memset(&cmap, 0, sizeof(cmap));<br>+<br>+ /* Make our palette the length of the deepest color */<br>+ int cols = (rcols > gcols ? rcols : gcols);<br>+ cols = (cols > bcols ? cols : bcols);<br>
+<br>+ colors = malloc(sizeof(uint16_t) * cols);<br>+ if (!colors) return -1;<br>+<br>+ for (i = 0; i < rcols; i++)<br>+ colors[i] = (UINT16_MAX / (rcols - 1)) * i;<br>+<br>+ cmap.start = 0;<br>+ cmap.len = cols;<br>
+ cmap.red = colors;<br>+ cmap.blue = colors;<br>+ cmap.green = colors;<br>+ if (vinfo->transp.length)<br>+ cmap.transp = colors;<br>+ else<br>+ cmap.transp = NULL;<br>+ ioctl(fd, FBIOPUTCMAP, &cmap);<br>
+<br>+ free(colors);<br>+ return 0;<br>+}<br>+<br> static pixman_format_code_t<br> calculate_pixman_format(struct fb_var_screeninfo *vinfo,<br> struct fb_fix_screeninfo *finfo)<br>@@ -242,7 +279,8 @@ calculate_pixman_format(struct fb_var_screeninfo *vinfo,<br>
return 0;<br> <br> /* We only handle true-colour frame buffers at the moment. */<br>- if (finfo->visual != FB_VISUAL_TRUECOLOR || vinfo->grayscale != 0)<br>+ if (!(finfo->visual == FB_VISUAL_TRUECOLOR || finfo->visual == FB_VISUAL_DIRECTCOLOR)<br>
+ || vinfo->grayscale != 0)<br> return 0;<br> <br> /* We only support formats with MSBs on the left. */<br>@@ -325,6 +363,9 @@ fbdev_query_screen_info(struct fbdev_output *output, int fd,<br> info->pixel_format = calculate_pixman_format(&varinfo, &fixinfo);<br>
info->refresh_rate = calculate_refresh_rate(&varinfo);<br> <br>+ if (fixinfo.visual == FB_VISUAL_DIRECTCOLOR)<br>+ set_cmap(fd, &varinfo);<br>+<br> if (info->pixel_format == 0) {<br> weston_log("Frame buffer uses an unsupported format.\n");<br>
return -1;<br>-- <br>1.7.9.5<br><br><br></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/6/10 Pekka Paalanen <span dir="ltr"><<a href="mailto:ppaalanen@gmail.com" target="_blank">ppaalanen@gmail.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Fri, 7 Jun 2013 17:13:59 +0200<br>
Marc Chalain <<a href="mailto:marc.chalain@gmail.com">marc.chalain@gmail.com</a>> wrote:<br>
<br>
> From e30486e0288e7be526fc358a5318b344522e407b Mon Sep 17 00:00:00 2001<br>
> From: mchalain <<a href="mailto:marc.chalain@gmail.com">marc.chalain@gmail.com</a>><br>
> Date: Fri, 7 Jun 2013 17:12:31 +0200<br>
> Subject: [PATCH] [fbdev_backend]: support of DIRECTCOLOR Frame buffer<br>
><br>
<br>
</div>A properly formatted title:<br>
compositor-fbdev: add direct color support<br>
<br>
Commit message is missing.<br>
<div><div class="h5"><br>
> ---<br>
> src/compositor-fbdev.c | 49<br>
> +++++++++++++++++++++++++++++++++++++++++++++---<br>
> 1 file changed, 46 insertions(+), 3 deletions(-)<br>
><br>
> diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c<br>
> index 9c3d17e..d6d911a 100644<br>
> --- a/src/compositor-fbdev.c<br>
> +++ b/src/compositor-fbdev.c<br>
> @@ -203,9 +203,42 @@ finish_frame_handler(void *data)<br>
> return 1;<br>
> }<br>
><br>
> +static int<br>
> +build_cmap(struct fb_var_screeninfo *vinfo,<br>
> + struct fb_cmap *cmap)<br>
> +{<br>
> + uint16_t *colors;<br>
> + int i;<br>
> + int rcols = 1 << vinfo->red.length;<br>
> + int gcols = 1 << vinfo->green.length;<br>
> + int bcols = 1 << vinfo->blue.length;<br>
> +<br>
> + /* Make our palette the length of the deepest color */<br>
> + int cols = (rcols > gcols ? rcols : gcols);<br>
> + cols = (cols > bcols ? cols : bcols);<br>
> +<br>
> + colors = malloc(sizeof(uint16_t) * cols);<br>
> + if (!colors) return -1;<br>
> +<br>
> + for (i = 0; i < rcols; i++)<br>
> + colors[i] = (UINT16_MAX / (rcols - 1)) * i;<br>
> +<br>
> + cmap->start = 0;<br>
> + cmap->len = cols;<br>
> + cmap->red = colors;<br>
> + cmap->blue = colors;<br>
> + cmap->green = colors;<br>
<br>
</div></div>If there actually is a difference between rcols, gcols, and bcols,<br>
should you not compute a different a 'colors' array for each different<br>
_cols?<br>
<div class="im"><br>
> + if (vinfo->transp.length)<br>
> + cmap->transp = colors;<br>
> + else<br>
> + cmap->transp = NULL;<br>
<br>
</div>Now, 'colors' is malloc'd here. How does the caller of this function<br>
know what to free? Freeing each of cmap->{red,blue,green,transp} would<br>
lead to double-free errors.<br>
<br>
Right, you free only 'red'. But that's rather surprising.<br>
<div class="im"><br>
> + return 0;<br>
> +}<br>
> +<br>
> static pixman_format_code_t<br>
> calculate_pixman_format(struct fb_var_screeninfo *vinfo,<br>
> - struct fb_fix_screeninfo *finfo)<br>
> + struct fb_fix_screeninfo *finfo,<br>
> + struct fb_cmap *cmap)<br>
> {<br>
> /* Calculate the pixman format supported by the frame buffer from the<br>
> * buffer's metadata. Return 0 if no known pixman format is supported<br>
> @@ -241,7 +274,10 @@ calculate_pixman_format(struct fb_var_screeninfo<br>
> *vinfo,<br>
> if (finfo->type != FB_TYPE_PACKED_PIXELS)<br>
> return 0;<br>
><br>
> - /* We only handle true-colour frame buffers at the moment. */<br>
> + if (finfo->visual == FB_VISUAL_DIRECTCOLOR)<br>
> + build_cmap(vinfo, cmap);<br>
<br>
</div>This is a strange place to call build_cmap(). The purpose of this<br>
function is to return a pixman format or an error, not to fill a<br>
fb_cmap struct.<br>
<br>
Yes, you probably need to test for FB_VISUAL_DIRECTCOLOR in two places.<br>
<div><div class="h5"><br>
> + else<br>
> + /* We only handle true-colour frame buffers at the moment. */<br>
> if (finfo->visual != FB_VISUAL_TRUECOLOR || vinfo->grayscale != 0)<br>
> return 0;<br>
><br>
> @@ -304,6 +340,9 @@ fbdev_query_screen_info(struct fbdev_output *output,<br>
> int fd,<br>
> {<br>
> struct fb_var_screeninfo varinfo;<br>
> struct fb_fix_screeninfo fixinfo;<br>
> + struct fb_cmap cmap;<br>
> +<br>
> + memset(&cmap, 0, sizeof(cmap));<br>
><br>
> /* Probe the device for screen information. */<br>
> if (ioctl(fd, FBIOGET_FSCREENINFO, &fixinfo) < 0 ||<br>
> @@ -322,9 +361,13 @@ fbdev_query_screen_info(struct fbdev_output *output,<br>
> int fd,<br>
> info->line_length = fixinfo.line_length;<br>
> strncpy(info->id, <a href="http://fixinfo.id" target="_blank">fixinfo.id</a>, sizeof(info->id) / sizeof(*info->id));<br>
><br>
> - info->pixel_format = calculate_pixman_format(&varinfo, &fixinfo);<br>
> + info->pixel_format = calculate_pixman_format(&varinfo, &fixinfo,<br>
> &cmap);<br>
> info->refresh_rate = calculate_refresh_rate(&varinfo);<br>
><br>
> + if (cmap.red != NULL) {<br>
> + ioctl(fd, FBIOPUTCMAP, &cmap);<br>
> + free(cmap.red);<br>
> + }<br>
> if (info->pixel_format == 0) {<br>
> weston_log("Frame buffer uses an unsupported format.\n");<br>
> return -1;<br>
<br>
</div></div>This patch is indented with 4 spaces, while weston codebase uses hard<br>
tabs of width 8. Maybe your email client messed up the whitespace?<br>
I also see a few lines cut unintendedly.<br>
<br>
<br>
Thanks<br>
pq<br>
</blockquote></div><br></div>