Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Jan 2021 09:17:44 +0200
From:      Toomas Soome <tsoome@me.com>
To:        Oliver Pinter <oliver.pntr@gmail.com>
Cc:        Toomas Soome <tsoome@freebsd.org>, "src-committers@freebsd.org" <src-committers@freebsd.org>, "dev-commits-src-all@freebsd.org" <dev-commits-src-all@freebsd.org>, "dev-commits-src-main@freebsd.org" <dev-commits-src-main@freebsd.org>
Subject:   Re: git: 1caed70c6264 - main - loader: update gfx module
Message-ID:  <4CC2ED16-9C4A-4821-BAB0-F1B01C525EFD@me.com>
In-Reply-To: <CAPjTQNHxuRRYfD3FsDL8N1i=1n5_JNm6zhRm=D-%2BasNSUt4GJA@mail.gmail.com>
References:  <202101172216.10HMGH1D076854@gitrepo.freebsd.org> <CAPjTQNHxuRRYfD3FsDL8N1i=1n5_JNm6zhRm=D-%2BasNSUt4GJA@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help


> On 18. Jan 2021, at 02:39, Oliver Pinter <oliver.pntr@gmail.com> =
wrote:
>=20
>=20
>=20
> On Sunday, January 17, 2021, Toomas Soome <tsoome@freebsd.org =
<mailto:tsoome@freebsd.org>> wrote:
> The branch main has been updated by tsoome:
>=20
> URL: =
https://cgit.FreeBSD.org/src/commit/?id=3D1caed70c62646a5978bbeb4562bc3ae2=
dabc874a =
<https://cgit.freebsd.org/src/commit/?id=3D1caed70c62646a5978bbeb4562bc3ae=
2dabc874a>
>=20
> commit 1caed70c62646a5978bbeb4562bc3ae2dabc874a
> Author:     Toomas Soome <tsoome@FreeBSD.org>
> AuthorDate: 2021-01-17 22:09:18 +0000
> Commit:     Toomas Soome <tsoome@FreeBSD.org>
> CommitDate: 2021-01-17 22:15:36 +0000
>=20
>     loader: update gfx module
>=20
>     Update from illumos review process.
>     Add more comments, drop memory buffer from blt functions.
> ---
>  stand/common/gfx_fb.c | 118 =
++++++++++++++++++++++++++++++++------------------
>  1 file changed, 76 insertions(+), 42 deletions(-)
>=20
> diff --git a/stand/common/gfx_fb.c b/stand/common/gfx_fb.c
> index 9342521fd0cf..d98e6d1bae4b 100644
> --- a/stand/common/gfx_fb.c
> +++ b/stand/common/gfx_fb.c
> @@ -29,6 +29,61 @@
>   * $FreeBSD$
>   */
>=20
> +/*
> + * The workhorse here is gfxfb_blt(). It is implemented to mimic UEFI
> + * GOP Blt, and allows us to fill the rectangle on screen, copy
> + * rectangle from video to buffer and buffer to video and video to =
video.
> + * Such implementation does allow us to have almost identical =
implementation
> + * for both BIOS VBE and UEFI.
> + *
> + * ALL pixel data is assumed to be 32-bit BGRA (byte order Blue, =
Green, Red,
> + * Alpha) format, this allows us to only handle RGB data and not to =
worry
> + * about mixing RGB with indexed colors.
> + * Data exchange between memory buffer and video will translate BGRA
> + * and native format as following:
> + *
> + * 32-bit to/from 32-bit is trivial case.
> + * 32-bit to/from 24-bit is also simple - we just drop the alpha =
channel.
> + * 32-bit to/from 16-bit is more complicated, because we nee to =
handle
> + * data loss from 32-bit to 16-bit. While reading/writing from/to =
video, we
> + * need to apply masks of 16-bit color components. This will preserve
> + * colors for terminal text. For 32-bit truecolor PMG images, we need =
to
> + * translate 32-bit colors to 15/16 bit colors and this means data =
loss.
> + * There are different algorithms how to perform such color space =
reduction,
> + * we are currently using bitwise right shift to reduce color space =
and so far
> + * this technique seems to be sufficient (see also gfx_fb_putimage(), =
the
> + * end of for loop).
> + * 32-bit to/from 8-bit is the most troublesome because 8-bit colors =
are
> + * indexed. =46rom video, we do get color indexes, and we do =
translate
> + * color index values to RGB. To write to video, we again need to =
translate
> + * RGB to color index. Additionally, we need to translate between VGA =
and
> + * console colors.
> + *
> + * Our internal color data is represented using BGRA format. But the =
hardware
> + * used indexed colors for 8-bit colors (0-255) and for this mode we =
do
> + * need to perform translation to/from BGRA and index values.
> + *
> + *                   - paletteentry RGB <-> index -
> + * BGRA BUFFER <----/                              \ - VIDEO
> + *                  \                              /
> + *                   -  RGB (16/24/32)            -
> + *
> + * To perform index to RGB translation, we use palette table =
generated
> + * from when we set up 8-bit mode video. We cannot read palette data =
from
> + * the hardware, because not all hardware supports reading it.
> + *
> + * BGRA to index is implemented in rgb_to_color_index() by searching
> + * palette array for closest match of RBG values.
> + *
> + * Note: In 8-bit mode, We do store first 16 colors to palette =
registers
> + * in VGA color order, this serves two purposes; firstly,
> + * if palette update is not supported, we still have correct 16 =
colors.
> + * Secondly, the kernel does get correct 16 colors when some other =
boot
> + * loader is used. However, the palette map for 8-bit colors is using
> + * console color ordering - this does allow us to skip translation
> + * from VGA colors to console colors, while we are reading RGB data.
> + */
> +
>  #include <sys/cdefs.h>
>  #include <sys/param.h>
>  #include <stand.h>
> @@ -257,7 +312,7 @@ rgb_to_color_index(uint8_t r, uint8_t g, uint8_t =
b)
>         int diff;
>=20
>         color =3D 0;
> -       best =3D NCMAP * NCMAP * NCMAP;
> +       best =3D 255 * 255 * 255;
>=20
> This change was intended to change from a named constant to magic =
number?=20

yes, one thing is that NCMAP is wrong named constant to be used in this =
context. We want to start with large enough value > 255^2 + 255^2 + =
255^2, where 255 is max value of RGB component. In that sense even =
UINT32_MAX is ok, but I think, 255 * 255 * 255 is visually better =
(better than UINT8_MAX * UINT8_MAX * UINT8_MAX).

rgds,
toomas

> =20
>         for (k =3D 0; k < NCMAP; k++) {
>                 diff =3D r - pe8[k].Red;
>                 dist =3D diff * diff;
> @@ -337,7 +392,6 @@ gfx_mem_wr4(uint8_t *base, size_t size, uint32_t =
o, uint32_t v)
>         *(uint32_t *)(base + o) =3D v;
>  }
>=20
> -/* Our GFX Block transfer toolkit. */
>  static int gfxfb_blt_fill(void *BltBuffer,
>      uint32_t DestinationX, uint32_t DestinationY,
>      uint32_t Width, uint32_t Height)
> @@ -409,6 +463,8 @@ static int gfxfb_blt_fill(void *BltBuffer,
>                         case 4:
>                                 gfx_mem_wr4(destination, size, off, =
data);
>                                 break;
> +                       default:
> +                               return (EINVAL);
>                         }
>                         off +=3D bpp;
>                 }
> @@ -430,7 +486,7 @@ gfxfb_blt_video_to_buffer(void *BltBuffer, =
uint32_t SourceX, uint32_t SourceY,
>         uint32_t x, sy, dy;
>         uint32_t bpp, pitch, copybytes;
>         off_t off;
> -       uint8_t *source, *destination, *buffer, *sb;
> +       uint8_t *source, *destination, *sb;
>         uint8_t rm, rp, gm, gp, bm, bp;
>         bool bgra;
>=20
> @@ -468,36 +524,21 @@ gfxfb_blt_video_to_buffer(void *BltBuffer, =
uint32_t SourceX, uint32_t SourceY,
>             ffs(gm) - 1 =3D=3D 8 && gp =3D=3D 8 &&
>             ffs(bm) - 1 =3D=3D 8 && bp =3D=3D 0;
>=20
> -       if (bgra) {
> -               buffer =3D NULL;
> -       } else {
> -               buffer =3D malloc(copybytes);
> -               if (buffer =3D=3D NULL)
> -                       return (ENOMEM);
> -       }
> -
>         for (sy =3D SourceY, dy =3D DestinationY; dy < Height + =
DestinationY;
>             sy++, dy++) {
>                 off =3D sy * pitch + SourceX * bpp;
>                 source =3D gfx_get_fb_address() + off;
> +               destination =3D (uint8_t *)BltBuffer + dy * Delta +
> +                   DestinationX * sizeof (*p);
>=20
>                 if (bgra) {
> -                       destination =3D (uint8_t *)BltBuffer + dy * =
Delta +
> -                           DestinationX * sizeof (*p);
> +                       bcopy(source, destination, copybytes);
>                 } else {
> -                       destination =3D buffer;
> -               }
> -
> -               bcopy(source, destination, copybytes);
> -
> -               if (!bgra) {
>                         for (x =3D 0; x < Width; x++) {
>                                 uint32_t c =3D 0;
>=20
> -                               p =3D (void *)((uint8_t *)BltBuffer +
> -                                   dy * Delta +
> -                                   (DestinationX + x) * sizeof (*p));
> -                               sb =3D buffer + x * bpp;
> +                               p =3D (void *)(destination + x * =
sizeof (*p));
> +                               sb =3D source + x * bpp;
>                                 switch (bpp) {
>                                 case 1:
>                                         c =3D *sb;
> @@ -511,6 +552,8 @@ gfxfb_blt_video_to_buffer(void *BltBuffer, =
uint32_t SourceX, uint32_t SourceY,
>                                 case 4:
>                                         c =3D *(uint32_t *)sb;
>                                         break;
> +                               default:
> +                                       return (EINVAL);
>                                 }
>=20
>                                 if (bpp =3D=3D 1) {
> @@ -527,7 +570,6 @@ gfxfb_blt_video_to_buffer(void *BltBuffer, =
uint32_t SourceX, uint32_t SourceY,
>                 }
>         }
>=20
> -       free(buffer);
>         return (0);
>  }
>=20
> @@ -544,7 +586,7 @@ gfxfb_blt_buffer_to_video(void *BltBuffer, =
uint32_t SourceX, uint32_t SourceY,
>         uint32_t x, sy, dy;
>         uint32_t bpp, pitch, copybytes;
>         off_t off;
> -       uint8_t *source, *destination, *buffer;
> +       uint8_t *source, *destination;
>         uint8_t rm, rp, gm, gp, bm, bp;
>         bool bgra;
>=20
> @@ -582,13 +624,6 @@ gfxfb_blt_buffer_to_video(void *BltBuffer, =
uint32_t SourceX, uint32_t SourceY,
>             ffs(gm) - 1 =3D=3D 8 && gp =3D=3D 8 &&
>             ffs(bm) - 1 =3D=3D 8 && bp =3D=3D 0;
>=20
> -       if (bgra) {
> -               buffer =3D NULL;
> -       } else {
> -               buffer =3D malloc(copybytes);
> -               if (buffer =3D=3D NULL)
> -                       return (ENOMEM);
> -       }
>         for (sy =3D SourceY, dy =3D DestinationY; sy < Height + =
SourceY;
>             sy++, dy++) {
>                 off =3D dy * pitch + DestinationX * bpp;
> @@ -597,6 +632,7 @@ gfxfb_blt_buffer_to_video(void *BltBuffer, =
uint32_t SourceX, uint32_t SourceY,
>                 if (bgra) {
>                         source =3D (uint8_t *)BltBuffer + sy * Delta +
>                             SourceX * sizeof (*p);
> +                       bcopy(source, destination, copybytes);
>                 } else {
>                         for (x =3D 0; x < Width; x++) {
>                                 uint32_t c;
> @@ -615,35 +651,33 @@ gfxfb_blt_buffer_to_video(void *BltBuffer, =
uint32_t SourceX, uint32_t SourceY,
>                                 off =3D x * bpp;
>                                 switch (bpp) {
>                                 case 1:
> -                                       gfx_mem_wr1(buffer, copybytes,
> +                                       gfx_mem_wr1(destination, =
copybytes,
>                                             off, (c < 16) ?
>                                             cons_to_vga_colors[c] : =
c);
>                                         break;
>                                 case 2:
> -                                       gfx_mem_wr2(buffer, copybytes,
> +                                       gfx_mem_wr2(destination, =
copybytes,
>                                             off, c);
>                                         break;
>                                 case 3:
> -                                       gfx_mem_wr1(buffer, copybytes,
> +                                       gfx_mem_wr1(destination, =
copybytes,
>                                             off, (c >> 16) & 0xff);
> -                                       gfx_mem_wr1(buffer, copybytes,
> +                                       gfx_mem_wr1(destination, =
copybytes,
>                                             off + 1, (c >> 8) & 0xff);
> -                                       gfx_mem_wr1(buffer, copybytes,
> +                                       gfx_mem_wr1(destination, =
copybytes,
>                                             off + 2, c & 0xff);
>                                         break;
>                                 case 4:
> -                                       gfx_mem_wr4(buffer, copybytes,
> +                                       gfx_mem_wr4(destination, =
copybytes,
>                                             x * bpp, c);
>                                         break;
> +                               default:
> +                                       return (EINVAL);
>                                 }
>                         }
> -                       source =3D buffer;
>                 }
> -
> -               bcopy(source, destination, copybytes);
>         }
>=20
> -       free(buffer);
>         return (0);
>  }
>=20
> _______________________________________________
> dev-commits-src-main@freebsd.org =
<mailto:dev-commits-src-main@freebsd.org> mailing list
> https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main =
<https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main>;
> To unsubscribe, send any mail to =
"dev-commits-src-main-unsubscribe@freebsd.org =
<mailto:dev-commits-src-main-unsubscribe@freebsd.org>"




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4CC2ED16-9C4A-4821-BAB0-F1B01C525EFD>