Hi, > Here's a work in progress that adds dithering for 16 bit > gradients. This does a 2x2 ordered dither in the same way that Skia > does. Skia and Coregraphics also do dithering of 32bit gradients which > I expect would also be useful for pixman in the future too.
> This patch adds a partial implementation of a 16 bit pipeline in > addition to the existing wide and narrow ones. This probably isn't > strictly necessary, but is important for decent performance. The 16 > bit pipeline is only used in the specific cases where it is supported, > everything else is left unimplemented. > > One of the things I'm currently unhappy with is that it duplicates the > gradient walker code for 16 bits. We could turn it into a large macro > that does the appropriate things for 16 bit and 32 bit versions, but > that's not particularly appealing. > > Does anyone have any other thoughts on this? Dithering is clearly needed for gradients on 16 bit destinations, and also a noticable improvement for 32 bit destinations, so thanks for looking into this. Some thoughts on the subject: - Dithering before or after compositing? Conceptually, it seems to me that it makes more sense to composite first and then dither the result just before writing back to the destination, because this is the point where quantization to 565 takes place. This also would give us dithering of regular sampled images for free. Implementing this would be straightforward in principle: just add a dither signal to the buffer in dest_write_back_narrow/wide(), although there would be some additional work to ensure that the various fast path blitters are not taken when dithering is enabled. Regarding performance, note that there is no requirement that gradients have to composited by the general implementation. There is nothing that prevents fast paths from being written that composited and dithered gradients. Such fast paths could make use of the gradient iterators, or they could reimplement the gradients themselves. - Roundtripping There are some potential issues with roundtripping. For example if you composite x8r8g8b8 to a4r4g4b4, the resulting alpha channel should really be solid 0xf and not, say, alternate between 0xe and 0xf. Also, it would be desirable to have SRC 565 to 565 be just a blit even with dithering enabled. This may just be a question of doing the dithering carefully though. - 16 bit pipe If we dither after compositing, that may make the question of a 16 bit pipe irrelevant for gradient dithering since the output of compositing would clearly have to be 32+ bits for dithering to make sense. But as a tangent, allowing iterators to generate other formats than a8r8g8b8 is not a bad idea. It's especially tempting if it would make noop 565 iterators possible so that 565 images could be composited by having a 565_565 combiner read directly from the images. I'm not wild about the special-casing that this patch adds in pixman-general.c, though. A trend over the last many releases has been to get rid of special cases or to at least cleanly separate them from general-purpose code. So while it might be worthwhile generalizing the general code so that it can deal with more intermediate pixel formats than just a8r8g8b8, doing it properly would likely involve turning the look-up of iterators and combiners into something similar to the current fast path lookup (and caching the resulting combinations). - Scrolling Suppose you scroll a pixmap one pixel up and then render the exposed area. If the dither matrix is positioned at the same place as before scrolling, vertical stripes will be produced. GTK+ solved this by having a user-settable "dither offset" that would be added to the destination position before accessing the dither matrix. - Dither matrix quality It's possible to do a lot better than a 2x2 Bayer matrix, although for a first implementation I guess it's better than nothing. Søren _______________________________________________ Pixman mailing list Pixman@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pixman