[cairo] 8 bit pseudo color missing.

Owen Taylor otaylor at redhat.com
Wed Mar 22 12:55:08 PST 2006

On Wed, 2006-03-22 at 10:18 -0800, Carl Worth wrote:
> On Wed, 15 Mar 2006 13:59:42 +0100, "Eric Faurot" wrote:
> > So for the record, could somebody with intimate knowledge of cairo internals
> > explain what code needs to be written, and where to hook it up in the
> > current code?  It would help somebody really interrested in fixing
> > that to know, at least, where to begin.
> The primary place where things are missing is within the pixman code,
> (that is the directory cairo/pixman/src from a cairo checkout or tar
> file).
> The pixman code was derived from the fb code in the X server.
> The X server does deal with indexed color operations and so to some
> extent the "necessary code" already exists within the X server. When I
> ported fb over to pixman to make a library usable outside of the X
> server, I simply discarded anything related to indexed color
> operations, since I had no interest in doing the work necessary to
> make it functional.
> The discarding may have included #ifdefs to prevent code from being
> compiled, or it may have been simply not copying portions of the code
> needed. I really couldn't say for sure now. But a good place to start
> would be comparing the pixman code to the fb code in the X server.

This approach assumes that you can get the color assignments on the
server to agree with what the pixman code wants. If the server has
RENDER of a reasonably recent vintage, then that is going to be the
case, considering the common heritage. But the server might not 
have RENDER at all; it's really a question of why pseudo-color support
is wanted - you can imagine various cases:

 - Get Cairo working on 10+ year old hardware that only supports
   pseudo-color modes.

 - Get Cairo running on newer hardware to remote display to an
   old X terminal that only supports pseudo-color modes.

 - Get Cairo working on newer hardware that supports decent modes,
   but where the work hasn't been done to figure out how to
   configure the hardware that way.

The last is actually what was brought up last time Pseudo-color
support was brought up in the context of *BSD, but if someone was
going to spend on this fairly hard problem, it seems to me that
time would be better spent trying to solve a bigger piece of
the problem set ... it makes little sense to program to the 
fringe of a fringe.

And that makes me think that a better approach would be to, for 
software fallbacks, use an internal TrueColor buffer inside of 
Cairo, and only convert to and from indexed color when getting an
image from the display or writing the image back to the display.

Then you basically have only two problems to solve:

 - How do you grab an image from the screen and convert it
   to RGBA data. 

   The most basic way to do this is to just do
   two roundtrips ... query the colormap, and then fetch 
   the image data. You can get more sophisticated by only
   fetching the colormap periodically or by playing Xlib
   programming tricks to combine the two roundtrips into 

 - How do you convert RGBA data back into screen format.

   Vast quantities of time were spent on this problem back
   when people still cared about Pseudo-color support, but
   there are some pretty simple ways to get really basic

   Floyd-Steinberg dithering, though it really doesn't work
   well for screen display due to discontinuities at the
   edges of dithered regions has the nice property that 
   it is easy to get going with an arbitrary color map
   rather than a color cube. As long as you have *some* way
   of finding an color in the color map that approximates
   the color of the pixel, then you'll get decent results.

It's probably possible to get something appearing on the screen
in a day or so of work with that approach.

Rather then going into a lot more detail about the above, I'll
just mention a few of the problems that would have to be
addressed in making something that wasn't just a complete toy:

 - To get pseudo-color display to be at all usable, you need
   to dither. However, dithering has the problem of joins - 
   you can't just glue two separately dithered areas together
   and expect it to look right.

   I'd suggest for a first approximation, ignoring this.

   To get good dithering results, you need to keep track
   of a "dither offset". Now, since this has to be dealt with
   at all layers ... from the application to the lowest part
   of rendering, it's basically an impossibility to get right
   these days, since applications just aren't going to care,
   but you could do better-than-nothing at only the 
   Cairo <=> toolkit layer. (In the GTK+ case
   cairo_surface_set_device_offset() is almost what you need.)
   Or you could do what Carl was suggesting at the X server
   level and render the entire screen in true color and dither
   down from there. That's not feasible for all use cases.

 - It's pretty much of a disaster if you repeatedly dither
   to the display and fetch data back. Both from a performance
   point of view and an a results point of view. So there are
   a couple of things that help all servers without RENDER
   that would help even more here:

    - Keep data around for the window client side, and only
      write at the end ... this is what the flush() and
      mark_dirty() APIs are meant to enable.

    - Optimize the case where the contents of the destination
      are known ... for example, if we create a new pixmap,
      and fill it completely with a solid color, then draw   
      on top of that, then we shouldn't need to ever read
      data back from the server.

Finally, it's worth making clear that there's no way things are
going to work as well in pseudo-color modes as they did in 1996.
Getting Pseudo-color working was a delicate balancing job
which required cooperation between all the applications, code
at all levels, and even cooperation from the people doing 
the graphic art. That cooperation is no longer there, and people
simply aren't willing to make the necessary compromises. 

So, really, hoping for more than "something vaguely recognizable
appears on the screen slowly" may be futile.


More information about the cairo mailing list