Signed-off-by: Enric Balletbo i Serra <[email protected]>
Reviewed-by: Sjoerd Simons <[email protected]>
---
 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

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to