<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>