[PATCH 1/3] video: add support for drawing 8bpp bitmap on 32bpp framebuffer

Igor Opaniuk igor.opaniuk at gmail.com
Tue Jun 23 13:40:45 CEST 2020


Hi Anatolij,

On Wed, Feb 5, 2020 at 6:50 PM Anatolij Gustschin <agust at denx.de> wrote:
>
> cfb_console driver supported 8bpp bitmap drawing on 24bpp/32bpp
> displays and some boards used this configuration for drawing
> the logo. After conversion to DM_VIDEO the logo drawing on such
> boards doesn't work any more due to missing rendering code in the
> updated bmp command code for DM_VIDEO. Add 8bpp bitmap support
> for 32bpp displays.
>
> Signed-off-by: Anatolij Gustschin <agust at denx.de>
> ---
>  drivers/video/video-uclass.c |  6 ++++
>  drivers/video/video_bmp.c    | 62 ++++++++++++++++++++++++------------
>  include/video.h              |  2 +-
>  3 files changed, 48 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c
> index 12057c8a5b..44380a38d9 100644
> --- a/drivers/video/video-uclass.c
> +++ b/drivers/video/video-uclass.c
> @@ -228,6 +228,12 @@ static int video_post_probe(struct udevice *dev)
>         struct udevice *cons;
>         int ret;
>
> +       if (priv->bpix == VIDEO_BPP32) {
> +               priv->cmap = realloc(priv->cmap, 256 * sizeof(uint));
> +               if (!priv->cmap)
> +                       return -ENOMEM;
> +       }
> +
>         /* Set up the line and display size */
>         priv->fb = map_sysmem(plat->base, plat->size);
>         if (!priv->line_length)
> diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c
> index 8768228029..79d6c6afa5 100644
> --- a/drivers/video/video_bmp.c
> +++ b/drivers/video/video_bmp.c
> @@ -172,16 +172,29 @@ static void video_set_cmap(struct udevice *dev,
>                            struct bmp_color_table_entry *cte, unsigned colours)
>  {
>         struct video_priv *priv = dev_get_uclass_priv(dev);
> +       u16 *cmap16;
> +       u32 *cmap32;
>         int i;
> -       ushort *cmap = priv->cmap;
>
>         debug("%s: colours=%d\n", __func__, colours);
> -       for (i = 0; i < colours; ++i) {
> -               *cmap = ((cte->red   << 8) & 0xf800) |
> -                       ((cte->green << 3) & 0x07e0) |
> -                       ((cte->blue  >> 3) & 0x001f);
> -               cmap++;
> -               cte++;
> +       if (priv->bpix == VIDEO_BPP16) {
> +               cmap16 = priv->cmap;
> +               for (i = 0; i < colours; ++i) {
> +                       *cmap16 = ((cte->red << 8) & 0xf800) |
> +                               ((cte->green << 3) & 0x07e0) |
> +                               ((cte->blue  >> 3) & 0x001f);
> +                       cmap16++;
> +                       cte++;
> +               }
> +       } else if (priv->bpix == VIDEO_BPP32) {
> +               cmap32 = priv->cmap;
> +               for (i = 0; i < colours; ++i) {
> +                       *cmap32 = (cte->red  << 16) |
> +                                 (cte->green << 8) |
> +                                 cte->blue;
> +                       cmap32++;
> +                       cte++;
> +               }
>         }
>  }
>
> @@ -189,7 +202,8 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
>                       bool align)
>  {
>         struct video_priv *priv = dev_get_uclass_priv(dev);
> -       ushort *cmap_base = NULL;
> +       u32 *cmap32_base = NULL;
> +       u16 *cmap16_base = NULL;
>         int i, j;
>         uchar *fb;
>         struct bmp_image *bmp = map_sysmem(bmp_image, 0);
> @@ -227,11 +241,11 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
>         }
>
>         /*
> -        * We support displaying 8bpp and 24bpp BMPs on 16bpp LCDs
> -        * and displaying 24bpp BMPs on 32bpp LCDs
> +        * We support displaying 8bpp and 24bpp BMPs on 16bpp or 32bpp LCDs
>          */
>         if (bpix != bmp_bpix &&
>             !(bmp_bpix == 8 && bpix == 16) &&
> +           !(bmp_bpix == 8 && bpix == 32) &&
>             !(bmp_bpix == 24 && bpix == 16) &&
>             !(bmp_bpix == 24 && bpix == 32)) {
>                 printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
> @@ -264,36 +278,42 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
>         switch (bmp_bpix) {
>         case 1:
>         case 8: {
> -               cmap_base = priv->cmap;
>  #ifdef CONFIG_VIDEO_BMP_RLE8
>                 u32 compression = get_unaligned_le32(&bmp->header.compression);
>                 debug("compressed %d %d\n", compression, BMP_BI_RLE8);
>                 if (compression == BMP_BI_RLE8) {
>                         if (bpix != 16) {
>                                 /* TODO implement render code for bpix != 16 */
> -                               printf("Error: only support 16 bpix");
> +                               printf("Error: only support 16 bpix\n");
>                                 return -EPROTONOSUPPORT;
>                         }
> -                       video_display_rle8_bitmap(dev, bmp, cmap_base, fb, x,
> +                       video_display_rle8_bitmap(dev, bmp, priv->cmap, fb, x,
>                                                   y, width, height);
>                         break;
>                 }
>  #endif
>
> -               if (bpix != 16)
> -                       byte_width = width;
> -               else
> +               cmap16_base = priv->cmap;
> +               cmap32_base = priv->cmap;
> +
> +               if (bpix == 16)
>                         byte_width = width * 2;
> +               else if (bpix == 32)
> +                       byte_width = width * 4;
> +               else
> +                       byte_width = width;
>
>                 for (i = 0; i < height; ++i) {
>                         WATCHDOG_RESET();
>                         for (j = 0; j < width; j++) {
> -                               if (bpix != 16) {
> -                                       fb_put_byte(&fb, &bmap);
> -                               } else {
> -                                       *(uint16_t *)fb = cmap_base[*bmap];
> -                                       bmap++;
> +                               if (bpix == 16) {
> +                                       *(uint16_t *)fb = cmap16_base[*bmap++];
>                                         fb += sizeof(uint16_t) / sizeof(*fb);
> +                               } else if (bpix == 32) {
> +                                       *(uint32_t *)fb = cmap32_base[*bmap++];
> +                                       fb += 4;
> +                               } else {
> +                                       fb_put_byte(&fb, &bmap);
>                                 }
>                         }
>                         bmap += (padded_width - width);
> diff --git a/include/video.h b/include/video.h
> index e7c58e86cb..2f3183f873 100644
> --- a/include/video.h
> +++ b/include/video.h
> @@ -93,7 +93,7 @@ struct video_priv {
>         u32 colour_fg;
>         u32 colour_bg;
>         bool flush_dcache;
> -       ushort *cmap;
> +       void *cmap;
>         u8 fg_col_idx;
>         u8 bg_col_idx;
>  };
> --
> 2.17.1
>

Any chance to get this merged?

Thanks

-- 
Best regards - Freundliche Grüsse - Meilleures salutations

Igor Opaniuk

mailto: igor.opaniuk at gmail.com
skype: igor.opanyuk
+380 (93) 836 40 67
http://ua.linkedin.com/in/iopaniuk


More information about the U-Boot mailing list