AW: Implementing PseudoColor support on TrueColor screens

Carsten Haitzler (The Rasterman) raster at rasterman.com
Tue Jun 2 20:47:10 UTC 2020


On Tue, 2 Jun 2020 10:06:01 +0000 Walter Harms <wharms at bfs.de> said:

> the correct way to do is use XPutPixel().

Unfortunately it's also the very slow way. The right way is to handle the pixel
data pointer yourself correctly given format (8, 16, 32bit) and x visual rgb
masks and use the bytes_per_line correctly. This is your fast path for all
the common cases. Also try implement them in SIMD (MMX/SSE/Nneon/SVE/Altivec
etc.). If it's not an optimized common path, then fall back to XPutPixel.

You probably want to have the palette lookup table specifically filled and
optimized for the pixel format "ahead of time" so it's already 1:1 correct for
the right xRGB pixel value to expand to so all you need is a dumb lookup,
so the expand code is something like:

// assume the following input:
//unsigned char *srcpixel; // is input pointer top-left to bottom right
//int w, h; // size of image in pixels (width and height)
//unsigned int palette_lookup[256]; // expanded index -> xRGB 32bit layout
//                                  // you could do the same for 16bpp too
unsigned char *pixelrow;
unsigned int *pixel;

pixelrow = (unsigned char *)ximage->data;
// work from top left to bottom-right row by row
for (y = 0; y < h; y++) {
  pixelrow += ximage->bytes_per_line;
  pixel = (unsigned int *)pixelrow;
  for (x = 0; x < w; x++) {
    pixel = palette_lookup[*srcpixel];
    pixel++;
    srcpixel++;
  }
}

Even better if you can throw some SIMD in (I'd need to think about it a bit,
so not going to do it in an e-mail) and then write out 2 or 4 pixels at a time
(you then jump by 4 pixels at a time, instead of 1, dealing with
non-multiple-of-2-or-4 sizes as a special end-of-row cleanup at the end of a
row).

Also you really should use XShmPutImage - it's drastically faster than basic
XImage (but only for local xservers, so you have to query for it and test you
can XShmAttach() - will not work across a network). Also keep in mind that you
can have several XShmPutImages in flight as it's async, so look for the xshm
completion event to know when to clean up or be able to recycle your shm
segment - just keep a pool of xshm images/sysv shm segments around and as puts
complete put them back in the spare pool and when you need a new shm image for
a new frame, look in your pool for an available image, or create it if needed
then). You could also be lazy and use XSync()... :) it comes with blocking as a
side-effect.

> color these days if pretty easy  color=0/r/g/b
> 
> You need a lookuptable for 256 colors (=st2d_8to24table[i] ?)
> and that should it be.
> 
> re,
>  wh
> 
> ________________________________________
> Von: xorg <xorg-bounces at lists.x.org> im Auftrag von Sleep
> <ireallyhatespam at yandex.com> Gesendet: Dienstag, 2. Juni 2020 08:28:13
> An: xorg at lists.x.org
> Betreff: Implementing PseudoColor support on TrueColor screens
> 
> Is there any documentation, article or book on how to convert the colors
> displayed by a program that was originally written to work on 8 bit
> screens? The problem I am facing seems to be related to how pixels are
> represented in the 'data' member of the XImage structure, which results
> in a squashed image and colors being displayed incorrectly. The only
> reference I have are two functions in the Quake source code:
> xlib_rgb24()[1] and st3_fixup()[2], which are used to convert the colors
> (but I cannot comprehend them because the format is unknown to me), but
> I found nothing that could make the image fill the window[3] properly. I
> could use SDL to easily get around this issue but I specifically want to
> use Xlib.
> 
> I appreciate any help to learn.
> 
> [1]
> <https://github.com/id-Software/Quake/blob/bf4ac424ce754894ac8f1dae6a3981954bc9852d/WinQuake/vid_x.c#L156>
> [2]
> <https://github.com/id-Software/Quake/blob/bf4ac424ce754894ac8f1dae6a3981954bc9852d/WinQuake/vid_x.c#L219>
> [3] https://postimg.cc/MfRz0Dk7
> [4] https://i.postimg.cc/brVdhC3B/doom.png
> _______________________________________________
> xorg at lists.x.org: X.Org support
> Archives: http://lists.freedesktop.org/archives/xorg
> Info: https://lists.x.org/mailman/listinfo/xorg
> Your subscription address: %(user_address)s
> _______________________________________________
> xorg at lists.x.org: X.Org support
> Archives: http://lists.freedesktop.org/archives/xorg
> Info: https://lists.x.org/mailman/listinfo/xorg
> Your subscription address: %(user_address)s
> 


-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
Carsten Haitzler - raster at rasterman.com



More information about the xorg mailing list